├── .gitignore ├── autobahn.h ├── SPEC.md ├── README.md ├── DEVELOPERS.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Libraries 8 | *.lib 9 | *.a 10 | 11 | # Shared objects (inc. Windows DLLs) 12 | *.dll 13 | *.so 14 | *.so.* 15 | *.dylib 16 | 17 | # Executables 18 | *.exe 19 | *.out 20 | *.app 21 | *.i*86 22 | *.x86_64 23 | *.hex 24 | -------------------------------------------------------------------------------- /autobahn.h: -------------------------------------------------------------------------------- 1 | /** 2 | * AutobahnC. Copyright (c) 2013 Tavendo GmbH. All rights reserved. 3 | * 4 | * Besides a API for raw WebSocket, AutobahnC exposes a WAMP API for 5 | * talking to WAMP-compatible servers: 6 | */ 7 | 8 | /** 9 | * Open a new WAMP session to a server. 10 | */ 11 | ab_result_t ab_wamp_connect (json_t* sessionconfig, 12 | void* cbdata, 13 | ab_wamp_onconnect onconnect, 14 | ab_wamp_onclose onclose); 15 | 16 | typdef void (*ab_wamp_onconnect) (void* cbdata, 17 | ab_wamp_session_t* session, 18 | json_t* sessioninfo); 19 | 20 | typdef void (*ab_wamp_onclose) (void* cbdata, 21 | ab_wamp_session_t* session, 22 | int reason, 23 | const char* desc); 24 | 25 | 26 | /** 27 | * Call a remote procedure. 28 | */ 29 | ab_result_t ab_call (ab_wamp_session_t* session, 30 | const char* endpoint, 31 | json_t* args, 32 | void* cbdata, 33 | ab_onsuccess onsuccess, 34 | ab_onerror onerror); 35 | 36 | typedef void (*ab_onsuccess) (void* cbdata, 37 | json_t* result); 38 | 39 | typedef void (*ab_onerror) (void* cbdata, 40 | const char* error, 41 | const char* desc, 42 | json_t* details); 43 | 44 | 45 | /** 46 | * Subscribe to topics. 47 | */ 48 | ab_result_t ab_subscribe (ab_wamp_session_t* session, 49 | const char* topic, 50 | void* cbdata, 51 | ab_onevent onevent); 52 | 53 | typedef void (*ab_onevent) (void* cbdata, 54 | const char* topic, 55 | json_t* event); 56 | 57 | 58 | /** 59 | * Publish to topics. 60 | */ 61 | ab_result_t ab_publish (ab_wamp_session_t* session, 62 | const char* topic, 63 | json_t* event); 64 | 65 | 66 | /** 67 | * Process WAMP protocol data coming in from the network via the 68 | * underlying socket queue. This function never blocks. 69 | */ 70 | ab_result_t ab_wamp_loop_once (ab_wamp_session_t* session); 71 | -------------------------------------------------------------------------------- /SPEC.md: -------------------------------------------------------------------------------- 1 | http://www.digip.org/jansson/ 2 | http://kgabis.github.io/parson/ 3 | 4 | 5 | ANSI C (C89) WebSocket/WAMP client library with WSS support 6 | runs on FreeRTOS/CyaSSL 7 | Apache 2.0 license 8 | 9 | 10 | Jansson 11 | http://www.digip.org/jansson/ 12 | 13 | Parson 14 | https://github.com/kgabis/parson 15 | 16 | 17 | http://elk.informatik.fh-augsburg.de/hhweb/labor/arm/stm32-discovery/index.html 18 | 19 | 20 | http://electronicdesign.com/embedded/practical-advice-running-uclinux-cortex-m3m4 21 | https://github.com/EmcraftSystems 22 | 23 | /** 24 | * Besides a API for raw WebSocket, AutobahnC exposes a WAMP API for talking 25 | * with WAMP-compatible servers. 26 | */ 27 | 28 | /** 29 | * Open a new WAMP session to a server. 30 | */ 31 | ab_result_t ab_wamp_connect (json_t* sessionconfig, 32 | void* cbdata, 33 | ab_wamp_onconnect onconnect, 34 | ab_wamp_onclose onclose); 35 | 36 | typdef void (*ab_wamp_onconnect) (void* cbdata, 37 | ab_wamp_session_t* session, 38 | json_t* sessioninfo); 39 | 40 | typdef void (*ab_wamp_onclose) (void* cbdata, 41 | ab_wamp_session_t* session, 42 | int reason, 43 | const char* desc); 44 | 45 | typedef enum ab_result_t { 46 | AB_WAMP_CONNE 47 | AB_WAMP_SESSION_CLOSED = 10, 48 | AB_SQUEUE_CLOSED = 1, 49 | AB_SQUEUE_EMPTY = 2, 50 | AB_SQUEUE_FULL = 3, 51 | } 52 | 53 | 54 | /** 55 | * Call a remote procedure. 56 | */ 57 | ab_result_t ab_call (ab_wamp_session_t* session, 58 | const char* endpoint, 59 | json_t* args, 60 | void* cbdata, 61 | ab_onsuccess onsuccess, 62 | ab_onerror onerror); 63 | 64 | typedef void (*ab_onsuccess) (void* cbdata, 65 | json_t* result); 66 | 67 | typedef void (*ab_onerror) (void* cbdata, 68 | const char* error, 69 | const char* desc, 70 | json_t* details); 71 | 72 | 73 | /** 74 | * Subscribe to topics. 75 | */ 76 | ab_result_t ab_subscribe (ab_wamp_session_t* session, 77 | const char* topic, 78 | void* cbdata, 79 | ab_onevent onevent); 80 | 81 | typedef void (*ab_onevent) (void* cbdata, 82 | const char* topic, 83 | json_t* event); 84 | 85 | 86 | /** 87 | * Publish to topics. 88 | */ 89 | ab_result_t ab_publish (ab_wamp_session_t* session, 90 | const char* topic, 91 | json_t* event); 92 | 93 | 94 | /** 95 | * Process WAMP protocol data coming in from the network via the 96 | * underlying socket queue. This function never blocks. 97 | */ 98 | ab_result_t ab_wamp_loop_once (ab_wamp_session_t* session); 99 | 100 | 101 | ... 102 | 103 | int ab_transmit (const char* data, int length); 104 | 105 | int ab_receive (const char* data, int length); 106 | 107 | 108 | void ab_squeue_connect (const char* hostname, 109 | int port, 110 | ab_squeue_onconnect onconnect, 111 | ab_sqeue_onclose onclose); 112 | 113 | typedef void (*ab_squeue_onconnect) (ab_squeue_t* squeue); 114 | 115 | typedef void (*ab_sqeue_onclose) (ab_squeue_t* squeue, int reason, const char* desc) 116 | 117 | ab_result_t ab_squeue_put (ab_squeue_t* squeue, ab_squeue_cargo cargo); 118 | 119 | /* Get next cargo from socket queue. When successful, returns 0. 120 | * When a cargo could not be retrieved, the return value indicates 121 | * the reason. This function never blocks. 122 | */ 123 | ab_result_t ab_squeue_get (ab_squeue_t* squeue, ab_squeue_cargo* cargo); 124 | 125 | typedef struct ab_squeue_cargo { 126 | int length; 127 | int capacity; 128 | void* data; 129 | } 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Milestones 2 | 3 | 1. Connect two RIOT nodes over bridged TAP devices and talk UDP 4 | 2. Connect one RIOT node to a Python UDP node and talk UDP 5 | 3. Create a fuzzing UDP bridge that can drop, delay and reorder UDP datagrams 6 | 7 | 8 | ## Resources 9 | 10 | * [RIOT native intro](https://github.com/RIOT-OS/RIOT/wiki/Introduction#native-riot---run-riot-on-your-pc) 11 | * [RIOT native](https://github.com/RIOT-OS/RIOT/wiki/Family:-native) 12 | * [RIOT Virtual Networking](https://github.com/RIOT-OS/RIOT/wiki/Virtual-riot-network) 13 | * [Linux Kernel TUN/TAP docs](https://www.kernel.org/doc/Documentation/networking/tuntap.txt) 14 | * [RIOT-Lab Tutorial](http://riot-os.org/files/2015-riotlab-tutorial.pdf) 15 | * [Docker Buildbox](https://github.com/RIOT-OS/riotdocker/blob/master/Dockerfile) 16 | * [Microcoap example](https://github.com/RIOT-OS/applications/tree/master/microcoap) 17 | * [Serving CoAP on RIOT](http://watr.li/microcoap-and-ff-copper.html) 18 | * [Twisted/TAP/UDP Bridge](https://github.com/sgso/marz) 19 | * [txThings](https://github.com/mwasilak/txThings) 20 | 21 | ## Prerequisites 22 | 23 | The following was tested on Ubuntu 14.04. Install some tools 24 | 25 | ```console 26 | sudo apt-get install gcc-multilib bridge-utils 27 | ``` 28 | 29 | Clone the RIOT repo: 30 | 31 | ```console 32 | git clone https://github.com/RIOT-OS/RIOT.git 33 | cd RIOT/examples/posix_sockets 34 | make BOARD=native 35 | ``` 36 | 37 | Create two bridged TAP devices: 38 | 39 | ```console 40 | cd RIOT 41 | ./dist/tools/tapsetup/tapsetup -c 2 42 | ``` 43 | 44 | ## Sending over UDP between two RIOT nodes 45 | 46 | Build the [UDP example](https://github.com/RIOT-OS/RIOT/tree/master/examples/posix_sockets): 47 | 48 | ```console 49 | cd RIOT/examples/posix_sockets 50 | make BOARD=native 51 | ``` 52 | 53 | This should produce `./bin/native/posix_sockets.elf`. 54 | 55 | In a first terminal, start node 1: 56 | 57 | ```console 58 | oberstet@thinkpad-t430s:~/scm/3rdparty/RIOT/examples/posix_sockets$ sudo make term 59 | [sudo] password for oberstet: 60 | /home/oberstet/scm/3rdparty/RIOT/examples/posix_sockets/bin/native/posix_sockets.elf tap0 61 | RIOT native interrupts/signals initialized. 62 | LED_RED_OFF 63 | LED_GREEN_ON 64 | RIOT native board initialized. 65 | RIOT native hardware initialization complete. 66 | 67 | main(): This is RIOT! (Version: 2016.03-devel-1699-g0aa0-thinkpad-t430s) 68 | RIOT socket example application 69 | All up, running the shell now 70 | > help 71 | help 72 | Command Description 73 | --------------------------------------- 74 | udp send data over UDP and listen on UDP ports 75 | reboot Reboot the node 76 | ps Prints information about running threads. 77 | random_init initializes the PRNG 78 | random_get returns 32 bit of pseudo randomness 79 | ifconfig Configure network interfaces 80 | txtsnd Sends a custom string as is over the link layer 81 | ncache manage neighbor cache by hand 82 | routers IPv6 default router list 83 | > ifconfig 84 | ifconfig 85 | Iface 5 HWaddr: ce:c7:93:47:8a:94 86 | 87 | MTU:1500 HL:64 88 | Source address length: 6 89 | Link type: wired 90 | inet6 addr: ff02::1/128 scope: local [multicast] 91 | inet6 addr: fe80::ccc7:93ff:fe47:8a94/64 scope: local 92 | inet6 addr: ff02::1:ff47:8a94/128 scope: local [multicast] 93 | 94 | > udp 95 | udp 96 | usage: udp [send|server] 97 | > udp server start 9000 98 | udp server start 9000 99 | Success: started UDP server on port 9000 100 | > ps 101 | ps 102 | pid | name | state Q | pri | stack ( used) | location 103 | 1 | idle | pending Q | 15 | 8192 ( 6240) | 0x8070180 104 | 2 | main | running Q | 7 | 12288 ( 9312) | 0x806d180 105 | 3 | ipv6 | bl rx _ | 4 | 8192 ( 6240) | 0x807d3c0 106 | 4 | udp | bl rx _ | 5 | 8192 ( 6240) | 0x8081200 107 | 5 | gnrc_netdev2_tap | bl rx _ | 4 | 8192 ( 6240) | 0x807b380 108 | 6 | UDP server | bl rx _ | 6 | 8192 ( 6240) | 0x8079200 109 | | SUM | | | 53248 (40512) 110 | > Received data: hello, world! 111 | ``` 112 | 113 | In a second terminal start node 2: 114 | 115 | ```console 116 | oberstet@thinkpad-t430s:~/scm/3rdparty/RIOT/examples/posix_sockets$ sudo PORT=tap1 make term 117 | [sudo] password for oberstet: 118 | /home/oberstet/scm/3rdparty/RIOT/examples/posix_sockets/bin/native/posix_sockets.elf tap1 119 | RIOT native interrupts/signals initialized. 120 | LED_RED_OFF 121 | LED_GREEN_ON 122 | RIOT native board initialized. 123 | RIOT native hardware initialization complete. 124 | 125 | main(): This is RIOT! (Version: 2016.03-devel-1699-g0aa0-thinkpad-t430s) 126 | RIOT socket example application 127 | All up, running the shell now 128 | > udp send fe80::ccc7:93ff:fe47:8a94 9000 "hello, world!" 129 | udp send fe80::ccc7:93ff:fe47:8a94 9000 "hello, world!" 130 | Success: send 13 byte to fe80::ccc7:93ff:fe47:8a94:9000 131 | > 132 | ``` 133 | -------------------------------------------------------------------------------- /DEVELOPERS.md: -------------------------------------------------------------------------------- 1 | # AutobahnC 2 | 3 | ## Motivation 4 | 5 | So, why another Autobahn? Why yet another WAMP client library? 6 | 7 | In one word: because IoT. 8 | 9 | Because we want to allow small, embedded devices to be first-class WAMP citizens. 10 | 11 | And without requiring bridging from some other protocol. 12 | 13 | For example, using AutobahnCpp and C++, it is possible to create an (essentially) completely statically linked, small executable. 14 | 15 | However, the fact that AutobahnCpp uses a couple of C++ features only available in C++ 11 and later (better C++ 14), and the fact that it deeply depends on Boost (in particular Boost ASIO) can make it hard when using C/C++ toolchains for embedded devices, which often are not as current as your modern GCC or Clang. Even Windows requires a very recent incarnation of VSS. Modern C++ is a weapon, but its also a biest. 16 | 17 | Then Boost, and ASIO in particular is written against Posix/Win32 APIs. Of course, no issue when on a full blown *nix, *BSD or Windows system. But it is a problem on smallish embedded devices that can't run such OSs. 18 | 19 | Then, while AutobahnCpp now implements multiple WAMP transports, namely WebSocket and RawSocket, all these run over TCP (or in general, a reliable stream transport .. besides TCP, another one would be Unix domain sockets). 20 | 21 | However, TCP (and TLS) require non-trivial and complex implementations. Eg there are "Wifi/TCP on a chip" solutions, but I have yet to see one that provides a *robust, full and interoperable* implementation. For example, the TI CC chips (eg used in Tessel 1) or ESP86xx suck big time. The Wifi is flaky. The TCP is. Not to speak of TLS. Not recommended. 22 | 23 | Of course, when you can run a full Linux, all of above are non-issues. Linux has (obviously) capable and robust TCP, and GCC and Clang, and Open/LibreSSL. etc etc 24 | 25 | But you can't get Linux onto a 64kB RAM 32 bit MMU-less MCU. No way. You can strip it down to maybe 1MB RAM. But not much below. And that already require screwing the GNU glibc and moving to a "non-standard" C run-time - and that means pain, pain, pain already anyway. 26 | 27 | > Sidenote: There is a modern development called "Rump kernels". The *BSDs are again innovating here. But this is more a research thing right now, and more directed towards server loads, not embedded. And I doubt it can run without a MMU and hardware assisted virtual memory. 28 | 29 | So, how do we get WAMP onto say an ARM Cortex M3 with 64kB RAM, but no MMU? 30 | 31 | 32 | ## Requirements 33 | 34 | * 32 bit MCU (no MMU), at least 64kB RAM (eg ARM Cortex M devices) 35 | * RIOT OS 36 | * 6LoWPAN/UDP WAMP transport 37 | * CBOR serialization support 38 | * DTLS? 39 | * WAMP-cryptosign 40 | * WAMP-cryptobox (possibly) 41 | 42 | 43 | ## License and Copyrights 44 | 45 | **The license for AutobahnC will be MIT.** 46 | 47 | This is a liberal, non-copyleft license that allows use in both commercial, closed-source applications and open-source projects. 48 | 49 | The MIT license - different from Apache 2.0 - is also compatible with GPL v2. 50 | 51 | We also use MIT for AutobahnPython and AutobahnJS. AutobahnCpp uses the Boost license, mainly because be deeply depend on Boost anyway, and users then don't have to deal with yet another one. AutobahnAndroid (after the revamp that is upcoming) will also move to MIT. 52 | 53 | **The copyright notice will read: `Copyright (c) Tavendo GmbH and contributors.`** 54 | 55 | For various reasons, I think this is a sane, precise and fair one. 56 | 57 | We (Tavendo) will thus share the copyright, and there is no way we would be able to take away anything from the community or contributors. 58 | 59 | Listing each contributor in copyright notice is impractical (witness the discussion we had in AutobahnCpp). On the other hand, giving proper credits and visibility to contributors is important. We'll make sure that happens: in announcements ("X did awesome work") and/or CHANGELOG ("fix: ZZ - Thanks to X for this!"). Prominently placing us (Tavendo) in the copyright notice on the other hand is fair IMO, because we started all this. 60 | 61 | This is our policy (for all Autobahns), we do make this fully transparent in the wild open, and I think we (as a company) do already have a track record of being a good open-source fellow;) Not to speak of the significant amounts of money we've invested sponsoring all these open-source efforts. 62 | 63 | > Note: we'll soonish retire "Tavendo GmbH", and found "Crossbar.io GmbH". The copyright notice then will be changed to: `Copyright (c) Crossbar.io GmbH and contributors.` The new company will be transferred all legal rights from the old one. So we don't need to ask anyone for permission to do the change. 64 | 65 | 66 | ## Dev environment 67 | 68 | ### Hardware 69 | 70 | The dev MCU/SoC/board we'll use in (early) development of AutobahnC is: 71 | 72 | * ARM Cortex M4 73 | * Freescale Kinetis KW2x 74 | * [PHYTEC phyWAVE-KW2x](http://www.phytec.de/produkte/internet-of-things/phywave/) 75 | 76 | 77 | http://www.compex.com.sg/wp-content/uploads/2015/12/WPQ864-v1.7a.pdf 78 | http://www.compex.com.sg/product/wpq864/ 79 | 80 | 81 | The main reasons to use this specific product are: 82 | 83 | * the MCU is a state-of-the-art ARM Cortex device 84 | * RIOT *mainline* support for both the MCU/SoC and board (for *all* sensors/actuators) 85 | * PHYTEC seem to be a vivid open-source supporter with close relations to RIOT 86 | * PHYTEC has very good, openly available docs for their products 87 | 88 | > I've met the RIOT guys at EmbeddedWorld in Nürnberg/Germany 2016, and they had a booth _sponsored_ by PHYTEC. No sales talking at all. All engineers/developers there. Nice, nice. 89 | 90 | An alternative or equivalent would be 91 | 92 | * ST Microelectronics STM32F40 (ARM Cortex M4) 93 | * STM32F4discovery 94 | 95 | And of course, there are a lot of other M4 SoCs and boards. We do want to be open of course for other vendors/products - so this isn't about pushing for one vendor. But in my experience, its worth settling on one specific device in particular during early development, simply to reduce the number of variables, and don't spend too much time fiddling with stuff instead of writing code. 96 | 97 | > Disclosure: We (Tavendo) do NOT (2016/04) have any commercial relationship with Freescale or PHYTEC. 98 | 99 | ### Software 100 | 101 | We'll use GNU Tools for ARM Embedded Processors toolchain, aka **gcc-arm-embedded**. 102 | 103 | > We do not use proprietory 3rd party or ARM proprietory closed source tools. None. I don't care about that and would actively oppose anything in that direction. If we get patches to support properietory toolchain, so be it, and we'll merge *if it fits*. But we won't spend time ourself fiddling with these. 104 | 105 | 106 | ## Dev process 107 | 108 | Code will be hosted on GitHub in the main repo [https://github.com/crossbario/autobahn-c](https://github.com/crossbario/autobahn-c). 109 | 110 | Developers fork that repo, develop on private, short-lived branches and file PRs against the main repo. No direct merges to master on the main repo! 111 | 112 | Before merging, at least one other developer should have a look / review the PR. 113 | 114 | During early developement, we don't require any specifics regarding the dev branches. 115 | 116 | > Whether we require squasing commits before merging and/or rebasing to master we need to decide too. 117 | 118 | When AutobahnC has reached a minimal viable / functional state, we'll tighten the process: 119 | 120 | 1. no change without an issue 121 | 2. feature/fix branches refer to an issue 122 | 3. only on thing per issue, and hence feature/fix branch (granularity) 123 | 4. a proper changelog 124 | 125 | Issue are tracked on GitHub. We'll use labels for light-weight organization of issues. Yes, GH issues isn't perfect and limited, but it's super easy, light-weight and integrated with other GH features. 126 | 127 | 128 | ## Dev communication 129 | 130 | Discussions about concrete code proposal are encouraged to happen on PRs and/or related issues. 131 | 132 | We get the nice GH integrations for free, as well as long-term persistency of all the discussions. 133 | 134 | **The Autobahns have a mailing list and an IRC channel as well, but we might consider setting up Gitter (trivial) or Slack (we use that internally at Tavendo), because that has some real pros vs the former.** 135 | 136 | 137 | ## Coding Styleguide 138 | 139 | Lets not reinvent a new one, but look for something nice and existing **but well-defined**. 140 | 141 | Eg in the Python world, there is PEP8. Its there, hashed out, and many projects use it. 142 | 143 | Is there something similar for C? Obviously, but needs discussion / decision. 144 | 145 | > I've learned that the hard way (read, I did it wrong;). Personal taste is one thing. NOT having to hash out rules ourself, and then have endless discussions, and the doing it different from the rest of the community IS NOT producing value, but a waste of time. 146 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------