├── .gitmodules ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Config ├── LICENSE ├── Makefile ├── NOTICE ├── README.md ├── main ├── .clang-format ├── AppCommon.c ├── AppCredential.c ├── AppDataChannel.c ├── AppMain.c ├── AppMediaSrc_ESP32_FileSrc.c ├── AppMessageQueue.c ├── AppMetrics.c ├── AppSignaling.c ├── AppWebRTC.c ├── CMakeLists.txt ├── Kconfig.projbuild ├── cert.pem ├── component.mk ├── include │ ├── AppCommon.h │ ├── AppConfig.h │ ├── AppCredential.h │ ├── AppDataChannel.h │ ├── AppError.h │ ├── AppMain.h │ ├── AppMediaSink.h │ ├── AppMediaSrc.h │ ├── AppMediaSrc_ESP32_FileSrc.h │ ├── AppMessageQueue.h │ ├── AppMetrics.h │ ├── AppSignaling.h │ └── AppWebRTC.h ├── kvswebrtc_example_main.c ├── lib │ └── libllhttp │ │ └── CMakeLists.txt └── scripts │ └── clang-format.sh ├── patch ├── amazon-kinesis-video-streams-webrtc-sdk-c │ └── 0001-fix-mbedtls.patch ├── amazon-kinesis-video-streams-webrtc-sdk-js │ └── 0001-diable-offerToReceiveAudio.patch ├── libsrtp │ ├── 0001-disable-the-test-apps.patch │ ├── 0002-fix-the-compile-error-for-esp32.patch │ ├── 0003-add-the-mbedtls-support.patch │ ├── 0004-use-angle-brackets-for-consistency.patch │ ├── 0005-change-the-order-of-mbedtls.patch │ ├── 0006-remove-the-wordy-define.patch │ ├── 0007-remove-unnecessary-parentheses.patch │ └── 0008-fix-compile-error.patch ├── usrsctp │ ├── 0001-add-lwip-support.patch │ ├── 0002-disable-ipv6-and-program.patch │ ├── 0003-add-mbedtls-sha1-support.patch │ ├── 0004-change-the-cmakefiles-for-esp32.patch │ ├── 0005-add-the-name-and-size-of-threads.patch │ ├── 0006-add-pthread_exit.patch │ └── 0007-disable-the-compiling-of-shared-lib.patch └── wslay │ └── 0001-patches-for-freertos.patch ├── sdkconfig └── webrtc_example.csv /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "main/lib/libsrtp"] 2 | path = main/lib/libsrtp 3 | url = https://github.com/cisco/libsrtp.git 4 | [submodule "main/lib/amazon-kinesis-video-streams-webrtc-sdk-c"] 5 | path = main/lib/amazon-kinesis-video-streams-webrtc-sdk-c 6 | url = https://github.com/iotlabtpe/amazon-kinesis-video-streams-webrtc-sdk-c.git 7 | [submodule "main/lib/wslay"] 8 | path = main/lib/wslay 9 | url = https://github.com/tatsuhiro-t/wslay.git 10 | [submodule "main/lib/usrsctp"] 11 | path = main/lib/usrsctp 12 | url = https://github.com/sctplab/usrsctp.git 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following five lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | project(webrtc_example) 7 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /Config: -------------------------------------------------------------------------------- 1 | package.Webrtc-demo-on-esp = { 2 | interfaces = (1.0); 3 | 4 | # Use NoOpBuild. See https://w.amazon.com/index.php/BrazilBuildSystem/NoOpBuild 5 | build-system = no-op; 6 | build-tools = { 7 | 1.0 = { 8 | NoOpBuild = 1.0; 9 | }; 10 | }; 11 | 12 | # Use runtime-dependencies for when you want to bring in additional 13 | # packages when deploying. 14 | # Use dependencies instead if you intend for these dependencies to 15 | # be exported to other packages that build against you. 16 | dependencies = { 17 | 1.0 = { 18 | }; 19 | }; 20 | 21 | runtime-dependencies = { 22 | 1.0 = { 23 | }; 24 | }; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := webrtc_example 7 | 8 | include $(IDF_PATH)/make/project.mk 9 | 10 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # amazon-kinesis-video-streams-webrtc-sdk-c-for-freertos 2 | 3 | This project demonstrate how to port [Amazon Kinesis Video WebRTC C SDK](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c) to FreeRTOS. It uses the [ESP-Wrover-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-wrover-kit.html) as a reference platform. You may follow the same procedure to port to other hardware platforms. 4 | 5 | ## Clone projects 6 | 7 | Please git clone this project using the command below. This will git sub-module all depended submodules under main/lib. 8 | 9 | ``` 10 | git submodule update --init --recursive 11 | ``` 12 | 13 | ## Reference platform 14 | 15 | We use [ESP IDF 4.4.2](https://github.com/espressif/esp-idf/releases/tag/v4.4.2) and the [ESP-Wrover-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-wrover-kit.html) as the reference platform. 16 | 17 | Please git clone the ESP IDF 4.4.2 with following command 18 | 19 | ``` 20 | git clone -b v4.4.2 --recursive https://github.com/espressif/esp-idf.git esp-idf-v4.4.2 21 | ``` 22 | make change on file 23 | 24 | components/esp_rom/include/esp32/rom/ets_sys.h 25 | 26 | line 638 to 644 to following 27 | 28 | +#ifndef STATUS 29 | typedef enum { 30 | OK = 0, 31 | FAIL, 32 | PENDING, 33 | BUSY, 34 | CANCEL, 35 | } STATUS; 36 | +#endif 37 | 38 | Please follow the [Espressif instructions](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html) to set up the environment. 39 | 40 | ESP IDF 4.4.2 only supports Python version 3.10 and below and was tested on version 3.9.16. 41 | 42 | ## Apply patches 43 | 44 | Next, patch depended libraries for using with WebRTC. 45 | 46 | ### [wslay](https://github.com/tatsuhiro-t/wslay) 47 | 48 | This project uses wslay as the websocket client. Please apply patches located in patch/wslay directory. 49 | 50 | ``` 51 | main/lib/wslay$ git am ../../../patch/wslay/* 52 | ``` 53 | 54 | ### [libsrtp](https://github.com/cisco/libsrtp/releases/tag/v2.3.0) 55 | 56 | This project uses v2.3.0 of libsrtp. Please apply patches located in patch/libsrtp directory. 57 | 58 | ``` 59 | main/lib/libsrtp$ git am ../../../patch/libsrtp/* 60 | ``` 61 | 62 | ### [usrsctp](https://github.com/sctplab/usrsctp/commit/939d48f9632d69bf170c7a84514b312b6b42257d) 63 | 64 | Please apply patches as below. 65 | 66 | ``` 67 | main/lib/usrsctp$ git am ../../../patch/usrsctp/* 68 | ``` 69 | 70 | ### [amazon-kinesis-video-streams-webrtc-sdk-c] 71 | 72 | Please apply patches as below. 73 | 74 | ``` 75 | main/lib/amazon-kinesis-video-streams-webrtc-sdk-c$ git am ../../../patch/amazon-kinesis-video-streams-webrtc-sdk-c/* 76 | ``` 77 | 78 | If you run into problems when "git am" patches, you can use the following commands to resolve the problem. Or try "git am --abort" the process of git am, then "git apply" individual patches sequentially (in the order of the sequence number indicated by the file name). 79 | 80 | ``` 81 | $git apply --reject ../../../patch/problem-lib/problems.patch 82 | // fix *.rej 83 | $git add . 84 | $git am --continue 85 | ``` 86 | 87 | ## Configure the project 88 | 89 | Use menuconfig of ESP IDF to configure the project. 90 | 91 | ``` 92 | idf.py menuconfig 93 | ``` 94 | 95 | - These parameters under Example Configuration Options must be set. 96 | 97 | - - ESP_WIFI_SSID 98 | - ESP_WIFI_PASSWORD 99 | - ESP_MAXIMUM_RETRY 100 | - AWS_ACCESS_KEY_ID 101 | - AWS_SECRET_ACCESS_KEY 102 | - AWS_DEFAULT_REGION 103 | - AWS_KVS_CHANNEL 104 | - AWS_KVS_LOG_LEVEL 105 | 106 | - The modifications needed by this project can be seen in the sdkconfig file located at the root directory. 107 | 108 | ### Video source 109 | 110 | This project uses pre-recorded h.264 frame files for video streaming. Please put the files on a SD card. The files should look like: 111 | 112 | /sdcard/h264SampleFrames/frame-%04d.h264. 113 | 114 | The “%04d” part of the file name should be replaced by a sequence number of the frame. 115 | 116 | There are pre-generated video frame files under 117 | 118 | main/lib/amazon-kinesis-video-streams-webrtc-sdk-c/samples/h264SampleFrames/ 119 | 120 | ready to be copied to sdcard. 121 | 122 | Please note that you can not use J-TAG and SD card simultaneously on ESP-Wrover-Kit because they share some pins. 123 | 124 | [Generate video source](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c/blob/master/samples/h264SampleFrames/README.md) 125 | 126 | Given a video file videotestsrc, the following GStreamer command generates video frame files. If you want to reduce the number of video files, please modify related setting in sample code. 127 | 128 | 129 | 130 | ``` 131 | sh 132 | gst-launch-1.0 videotestsrc pattern=ball num-buffers=1500 ! timeoverlay ! videoconvert ! video/x-raw,format=I420,width=1280,height=720,framerate=5/1 ! queue ! x264enc bframes=0 speed-preset=veryfast bitrate=128 byte-stream=TRUE tune=zerolatency ! video/x-h264,stream-format=byte-stream,alignment=au,profile=baseline ! multifilesink location="frame-%04d.h264" index=1 133 | ``` 134 | 135 | ### Build and Flash 136 | 137 | Build the project and flash it to the board, then run monitor tool to view serial output: 138 | 139 | ``` 140 | idf.py -p PORT flash monitor 141 | ``` 142 | 143 | (To exit the serial monitor, type `Ctrl-]`.) 144 | 145 | See the Getting Started Guide of ESP IDF for full steps to configure and use ESP-IDF to build projects. 146 | 147 | ### Known limitations and issues 148 | 149 | This project does not use audio at this point of time. When running on the ESP-Wrover-Kit, this project can only run at low frame rate and low bit rate. 150 | 151 | The current implementation does not support data channel. Please check back later for availability of the data channel feature. 152 | 153 | **[The m-line mismatch](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c/issues/803)** 154 | 155 | When using the [WebRTC SDK Test Page](https://awslabs.github.io/amazon-kinesis-video-streams-webrtc-sdk-js/examples/index.html) to validate the demo, you may get m-line mismatch errors. Different browsers have different behaviors. To work around such errors, you need to run the [sample](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js/#Development) in [amazon-kinesis-video-streams-webrtc-sdk-js](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js), and disable audio functionality of audio. This patch disables the audio functionality. A later release of this project may eliminate the need for this. 156 | 157 | patch/amazon-kinesis-video-streams-webrtc-sdk-js/0001-diable-offerToReceiveAudio.patch` 158 | 159 | Quickly steps to do above 160 | 161 | 1. Click https://awslabs.github.io/amazon-kinesis-video-streams-webrtc-sdk-js/examples/index.html 162 | 163 | 2. Right click on the page, click 'save as', make sure the format is 'Webpage, Complete" and save. The 'KVS WebRTC Test Page.html' file and 'KVS WebRTC Test Page_files' directory are save. 164 | 165 | 3. Enter the 'KVS WebRTC Test Page_files' directory and patch the 'viewer.js' file by commented out SDP offer to receive audio. 166 | 167 | console.log('[VIEWER] Creating SDP offer'); 168 | await viewer.peerConnection.setLocalDescription( 169 | await viewer.peerConnection.createOffer({ 170 | // offerToReceiveAudio: true, 171 | offerToReceiveVideo: true, 172 | }), 173 | ); 174 | 175 | 4. Load the page 176 | 177 | KVS WebRTC Test Page.html 178 | 179 | for WebRTC testing 180 | 181 | ## Security 182 | 183 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 184 | 185 | ## License 186 | 187 | This project is licensed under the Apache-2.0 License. 188 | 189 | -------------------------------------------------------------------------------- /main/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Chromium 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveMacros: true 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Right 9 | AlignOperands: false 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: false 12 | AllowShortBlocksOnASingleLine: Never 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: None 15 | AllowShortIfStatementsOnASingleLine: Never 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | BinPackArguments: true 21 | BinPackParameters: true 22 | BraceWrapping: 23 | AfterCaseLabel: false 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterStruct: false 29 | AfterUnion: false 30 | AfterExternBlock: false 31 | BeforeCatch: false 32 | BeforeElse: false 33 | IndentBraces: false 34 | SplitEmptyFunction: false 35 | AfterNamespace: false 36 | BreakBeforeBinaryOperators: None 37 | BreakBeforeBraces: WebKit 38 | BreakBeforeTernaryOperators: true 39 | BreakStringLiterals: true 40 | ColumnLimit: 150 41 | CommentPragmas: '^ IWYU pragma:' 42 | ContinuationIndentWidth: 4 43 | DerivePointerAlignment: false 44 | IncludeBlocks: Preserve 45 | IndentCaseLabels: true 46 | IndentGotoLabels: true 47 | IndentPPDirectives: None 48 | IndentWidth: 4 49 | IndentWrappedFunctionNames: false 50 | CompactNamespaces: false 51 | KeepEmptyLinesAtTheStartOfBlocks: false 52 | PenaltyBreakAssignment: 2 53 | PenaltyBreakBeforeFirstCallParameter: 19 54 | PenaltyBreakComment: 300 55 | PenaltyBreakFirstLessLess: 120 56 | PenaltyBreakString: 1000 57 | PenaltyExcessCharacter: 1000000 58 | PenaltyReturnTypeOnItsOwnLine: 200 59 | PointerAlignment: Left 60 | ReflowComments: true 61 | SortIncludes: false 62 | SpaceAfterCStyleCast: true 63 | SpaceAfterLogicalNot: false 64 | SpaceBeforeAssignmentOperators: true 65 | SpaceBeforeParens: ControlStatements 66 | SpaceInEmptyBlock: false 67 | SpaceInEmptyParentheses: false 68 | SpacesBeforeTrailingComments: 1 69 | SpacesInAngles: false 70 | SpacesInConditionalStatement: false 71 | SpacesInCStyleCastParentheses: false 72 | SpacesInParentheses: false 73 | SpacesInSquareBrackets: false 74 | SpaceBeforeSquareBrackets: false 75 | Standard: Auto 76 | TabWidth: 4 77 | UseTab: Never 78 | ... 79 | 80 | -------------------------------------------------------------------------------- /main/AppCredential.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | /****************************************************************************** 16 | * HEADERS 17 | ******************************************************************************/ 18 | #define LOG_CLASS "AppCredential" 19 | #include "AppCredential.h" 20 | #include "stack_queue.h" 21 | #include "directory.h" 22 | #include "iot_credential_provider.h" 23 | #include "static_credential_provider.h" 24 | 25 | /****************************************************************************** 26 | * FUNCTIONS 27 | ******************************************************************************/ 28 | static STATUS traverseDirectoryPEMFileScan(UINT64 userData, DIR_ENTRY_TYPES entryType, PCHAR fullPath, PCHAR fileName) 29 | { 30 | UNUSED_PARAM(entryType); 31 | UNUSED_PARAM(fullPath); 32 | 33 | PCHAR certName = (PCHAR) userData; 34 | UINT32 fileNameLen = STRLEN(fileName); 35 | 36 | if (fileNameLen > ARRAY_SIZE(APP_CA_CERT_PEM_FILE_EXTENSION) + 1 && 37 | (STRCMPI(APP_CA_CERT_PEM_FILE_EXTENSION, &fileName[fileNameLen - ARRAY_SIZE(APP_CA_CERT_PEM_FILE_EXTENSION) + 1]) == 0)) { 38 | certName[0] = FPATHSEPARATOR; 39 | certName++; 40 | STRNCPY(certName, fileName, MAX_PATH_LEN); 41 | } 42 | 43 | return STATUS_SUCCESS; 44 | } 45 | 46 | STATUS searchSslCert(PAppCredential pAppCredential) 47 | { 48 | STATUS retStatus = STATUS_SUCCESS; 49 | struct stat pathStat; 50 | CHAR certName[MAX_PATH_LEN]; 51 | 52 | CHK(pAppCredential != NULL, STATUS_APP_CREDENTIAL_NULL_ARG); 53 | MEMSET(certName, 0x0, ARRAY_SIZE(certName)); 54 | pAppCredential->pCaCertPath = GETENV(CACERT_PATH_ENV_VAR); 55 | 56 | // if ca cert path is not set from the environment, try to use the one that cmake detected 57 | // if ca cert path is not set from the environment, try to use the one that cmake detected 58 | if (pAppCredential->pCaCertPath == NULL) { 59 | CHK_ERR(STRNLEN(DEFAULT_KVS_CACERT_PATH, MAX_PATH_LEN) > 0, STATUS_INVALID_OPERATION, "No ca cert path given (error:%s)", strerror(errno)); 60 | pAppCredential->pCaCertPath = DEFAULT_KVS_CACERT_PATH; 61 | } else { 62 | CHK(pAppCredential->pCaCertPath != NULL, STATUS_APP_CREDENTIAL_MISS_CACERT_PATH); 63 | // Check if the environment variable is a path 64 | CHK(0 == FSTAT(pAppCredential->pCaCertPath, &pathStat), STATUS_APP_CREDENTIAL_INVALID_CACERT_PATH); 65 | 66 | if (S_ISDIR(pathStat.st_mode)) { 67 | CHK_STATUS((directory_traverse(pAppCredential->pCaCertPath, (UINT64) &certName, /* iterate */ FALSE, traverseDirectoryPEMFileScan))); 68 | CHK(certName[0] != 0x0, STATUS_APP_CREDENTIAL_CACERT_NOT_FOUND); 69 | STRCAT(pAppCredential->pCaCertPath, certName); 70 | } 71 | } 72 | 73 | CleanUp: 74 | CHK_LOG_ERR((retStatus)); 75 | return retStatus; 76 | } 77 | 78 | STATUS app_credential_generateCertRoutine(PAppCredential pAppCredential) 79 | { 80 | STATUS retStatus = STATUS_SUCCESS; 81 | BOOL locked = FALSE; 82 | UINT32 certCount; 83 | PRtcCertificate pRtcCertificate = NULL; 84 | 85 | CHK(pAppCredential != NULL, STATUS_APP_CREDENTIAL_NULL_ARG); 86 | 87 | MUTEX_LOCK(pAppCredential->generateCertLock); 88 | locked = TRUE; 89 | 90 | // Quick check if there is anything that needs to be done. 91 | CHK_STATUS((stack_queue_getCount(pAppCredential->generatedCertificates, &certCount))); 92 | CHK(certCount <= MAX_RTCCONFIGURATION_CERTIFICATES, retStatus); 93 | 94 | // Generate the certificate with the keypair 95 | CHK(rtc_certificate_create(&pRtcCertificate) == STATUS_SUCCESS, STATUS_APP_CREDENTIAL_CERT_CREATE); 96 | 97 | // Add to the stack queue 98 | CHK(stack_queue_enqueue(pAppCredential->generatedCertificates, (UINT64) pRtcCertificate) == STATUS_SUCCESS, STATUS_APP_CREDENTIAL_CERT_STACK); 99 | 100 | DLOGD("New certificate has been pre-generated and added to the queue"); 101 | 102 | // Reset it so it won't be freed on exit 103 | pRtcCertificate = NULL; 104 | 105 | MUTEX_UNLOCK(pAppCredential->generateCertLock); 106 | locked = FALSE; 107 | 108 | CleanUp: 109 | 110 | if (pRtcCertificate != NULL) { 111 | rtc_certificate_free(pRtcCertificate); 112 | } 113 | 114 | if (locked) { 115 | MUTEX_UNLOCK(pAppCredential->generateCertLock); 116 | } 117 | 118 | return retStatus; 119 | } 120 | 121 | STATUS popGeneratedCert(PAppCredential pAppCredential, PRtcCertificate* ppRtcCertificate) 122 | { 123 | STATUS retStatus = STATUS_SUCCESS; 124 | BOOL locked = FALSE; 125 | UINT64 data; 126 | PRtcCertificate pRtcCertificate = NULL; 127 | 128 | CHK((pAppCredential != NULL) && (ppRtcCertificate != NULL), STATUS_APP_CREDENTIAL_NULL_ARG); 129 | 130 | *ppRtcCertificate = NULL; 131 | 132 | MUTEX_LOCK(pAppCredential->generateCertLock); 133 | locked = TRUE; 134 | // Check if we have any pregenerated certs and use them 135 | // NOTE: We are running under the config lock 136 | retStatus = stack_queue_dequeue(pAppCredential->generatedCertificates, &data); 137 | CHK(retStatus == STATUS_SUCCESS || retStatus == STATUS_NOT_FOUND, retStatus); 138 | 139 | if (retStatus == STATUS_NOT_FOUND) { 140 | retStatus = STATUS_SUCCESS; 141 | } else { 142 | // Use the pre-generated cert and get rid of it to not reuse again 143 | pRtcCertificate = (PRtcCertificate) data; 144 | } 145 | 146 | *ppRtcCertificate = pRtcCertificate; 147 | MUTEX_UNLOCK(pAppCredential->generateCertLock); 148 | locked = FALSE; 149 | 150 | CleanUp: 151 | if (locked) { 152 | MUTEX_UNLOCK(pAppCredential->generateCertLock); 153 | } 154 | return retStatus; 155 | } 156 | 157 | STATUS app_credential_create(PAppCredential pAppCredential) 158 | { 159 | STATUS retStatus = STATUS_SUCCESS; 160 | PCHAR pAccessKey, pSecretKey, pSessionToken; 161 | PCHAR pIotCoreCredentialEndPoint, pIotCoreCert, pIotCorePrivateKey, pIotCoreRoleAlias, pIotCoreThingName; 162 | PCHAR pEcsToken, pEcsCredentialFullUri; 163 | 164 | CHK(pAppCredential != NULL, STATUS_APP_CREDENTIAL_NULL_ARG); 165 | pAppCredential->credentialType = APP_CREDENTIAL_TYPE_NA; 166 | pAppCredential->pCredentialProvider = NULL; 167 | pAppCredential->generateCertLock = INVALID_MUTEX_VALUE; 168 | pAppCredential->generatedCertificates = NULL; 169 | 170 | CHK_STATUS((searchSslCert(pAppCredential))); 171 | 172 | if (((pAccessKey = GETENV(ACCESS_KEY_ENV_VAR)) != NULL) && ((pSecretKey = GETENV(SECRET_KEY_ENV_VAR)) != NULL)) { 173 | pSessionToken = GETENV(SESSION_TOKEN_ENV_VAR); 174 | CHK(static_credential_provider_create(pAccessKey, 0, pSecretKey, 0, pSessionToken, 0, MAX_UINT64, &pAppCredential->pCredentialProvider) == 175 | STATUS_SUCCESS, 176 | STATUS_APP_CREDENTIAL_ALLOCATE_STATIC); 177 | pAppCredential->credentialType = APP_CREDENTIAL_TYPE_STATIC; 178 | } else if (((pIotCoreThingName = GETENV(APP_IOT_CORE_THING_NAME)) != NULL) && 179 | ((pIotCoreCredentialEndPoint = GETENV(APP_IOT_CORE_CREDENTIAL_ENDPOINT)) != NULL) && ((pIotCoreCert = GETENV(APP_IOT_CORE_CERT))) && 180 | ((pIotCorePrivateKey = GETENV(APP_IOT_CORE_PRIVATE_KEY)) != NULL) && ((pIotCoreRoleAlias = GETENV(APP_IOT_CORE_ROLE_ALIAS)) != NULL)) { 181 | CHK(iot_credential_provider_create(pIotCoreCredentialEndPoint, pIotCoreCert, pIotCorePrivateKey, pAppCredential->pCaCertPath, 182 | pIotCoreRoleAlias, pIotCoreThingName, &pAppCredential->pCredentialProvider) == STATUS_SUCCESS, 183 | STATUS_APP_CREDENTIAL_ALLOCATE_IOT); 184 | pAppCredential->credentialType = APP_CREDENTIAL_TYPE_IOT_CERT; 185 | } else { 186 | CHK(FALSE, STATUS_APP_CREDENTIAL_ALLOCATE_NA); 187 | } 188 | 189 | pAppCredential->generateCertLock = MUTEX_CREATE(FALSE); 190 | CHK(IS_VALID_MUTEX_VALUE(pAppCredential->generateCertLock), STATUS_APP_CREDENTIAL_INVALID_MUTEX); 191 | CHK(stack_queue_create(&pAppCredential->generatedCertificates) == STATUS_SUCCESS, STATUS_APP_CREDENTIAL_PREGENERATED_CERT_QUEUE); 192 | 193 | CleanUp: 194 | 195 | if (STATUS_FAILED(retStatus)) { 196 | if (pAppCredential != NULL) { 197 | app_credential_destroy(pAppCredential); 198 | } 199 | } 200 | 201 | return retStatus; 202 | } 203 | 204 | STATUS app_credential_destroy(PAppCredential pAppCredential) 205 | { 206 | STATUS retStatus = STATUS_SUCCESS; 207 | StackQueueIterator iterator; 208 | UINT64 data; 209 | CHK(pAppCredential != NULL, STATUS_APP_CREDENTIAL_NULL_ARG); 210 | 211 | if (pAppCredential->generatedCertificates != NULL) { 212 | stack_queue_iterator_get(pAppCredential->generatedCertificates, &iterator); 213 | while (IS_VALID_ITERATOR(iterator)) { 214 | stack_queue_iterator_getItem(iterator, &data); 215 | stack_queue_iterator_getNext(&iterator); 216 | rtc_certificate_free((PRtcCertificate) data); 217 | } 218 | 219 | CHK_LOG_ERR((stack_queue_clear(pAppCredential->generatedCertificates, FALSE))); 220 | CHK_LOG_ERR((stack_queue_free(pAppCredential->generatedCertificates))); 221 | pAppCredential->generatedCertificates = NULL; 222 | } 223 | 224 | if (pAppCredential->credentialType == APP_CREDENTIAL_TYPE_STATIC) { 225 | CHK(static_credential_provider_free(&pAppCredential->pCredentialProvider) == STATUS_SUCCESS, STATUS_APP_CREDENTIAL_DESTROY_STATIC); 226 | } else if (pAppCredential->credentialType == APP_CREDENTIAL_TYPE_IOT_CERT) { 227 | CHK(iot_credential_provider_free(&pAppCredential->pCredentialProvider) == STATUS_SUCCESS, STATUS_APP_CREDENTIAL_DESTROY_IOT); 228 | } else { 229 | retStatus = STATUS_APP_CREDENTIAL_DESTROY_NA; 230 | } 231 | 232 | if (IS_VALID_MUTEX_VALUE(pAppCredential->generateCertLock)) { 233 | MUTEX_FREE(pAppCredential->generateCertLock); 234 | pAppCredential->generateCertLock = INVALID_MUTEX_VALUE; 235 | } 236 | 237 | CleanUp: 238 | if (pAppCredential != NULL) { 239 | pAppCredential->credentialType = APP_CREDENTIAL_TYPE_NA; 240 | } 241 | return retStatus; 242 | } 243 | -------------------------------------------------------------------------------- /main/AppDataChannel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #define LOG_CLASS "AppDataChannel" 16 | #include "AppDataChannel.h" 17 | #include "AppCommon.h" 18 | 19 | #ifdef ENABLE_DATA_CHANNEL 20 | VOID onDataChannelMessageMaster(UINT64 customData, PRtcDataChannel pDataChannel, BOOL isBinary, PBYTE pMessage, UINT32 pMessageLen) 21 | { 22 | UNUSED_PARAM(customData); 23 | UNUSED_PARAM(pDataChannel); 24 | if (isBinary) { 25 | DLOGI("DataChannel Binary Message"); 26 | } else { 27 | DLOGI("xDataChannel String Message: %.*s\n", pMessageLen, pMessage); 28 | } 29 | } 30 | 31 | static VOID onDataChannelMessage(UINT64 userData, PRtcDataChannel pDataChannel, BOOL isBinary, PBYTE pMessage, UINT32 pMessageLen) 32 | { 33 | PStreamingSession session = (PStreamingSession) userData; 34 | UNUSED_PARAM(pDataChannel); 35 | if (isBinary) { 36 | DLOGI("DataChannel Binary Message"); 37 | } else { 38 | // DLOGI("DataChannel String Message: %.*s\n", pMessageLen, pMessage); 39 | char c = *(pMessage + pMessageLen - 1); 40 | *(pMessage + pMessageLen - 1) = 0; 41 | printf("DataChannel String Message: %s%c\n\r", pMessage, c); 42 | *(pMessage + pMessageLen - 1) = c; 43 | // master echo 44 | data_channel_send(session->pRtcDataChannel, isBinary, pMessage, pMessageLen); 45 | } 46 | } 47 | 48 | VOID onDataChannel(UINT64 userData, PRtcDataChannel pRtcDataChannel) 49 | { 50 | DLOGI("New DataChannel has been opened %s \n", pRtcDataChannel->name); 51 | data_channel_onMessage(pRtcDataChannel, userData, onDataChannelMessage); 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /main/AppMain.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #define LOG_CLASS "AppMain" 16 | #include "AppCommon.h" 17 | #include "instrumented_allocators.h" 18 | 19 | INT32 WebRTCAppMain(PAppMediaSrc pAppMediaSrc) 20 | { 21 | STATUS retStatus = STATUS_SUCCESS; 22 | PAppConfiguration pAppConfiguration = NULL; 23 | SET_INSTRUMENTED_ALLOCATORS(); 24 | 25 | printf("[WebRTC] Starting\n"); 26 | UINT64 startTime, endTime; 27 | 28 | startTime = GETTIME(); 29 | retStatus = initApp(TRUE, TRUE, pAppMediaSrc, &pAppConfiguration); 30 | if (retStatus != STATUS_SUCCESS) { 31 | printf("[WebRTC] initApp(): operation returned status code: 0x%08x \n", retStatus); 32 | goto CleanUp; 33 | } 34 | 35 | retStatus = runApp(pAppConfiguration); 36 | if (retStatus != STATUS_SUCCESS) { 37 | printf("[WebRTC] runApp(): operation returned status code: 0x%08x \n", retStatus); 38 | } 39 | endTime = GETTIME(); 40 | 41 | DLOGD("The bootup time of webrtc is %"PRIu64" ms", (endTime-startTime)/HUNDREDS_OF_NANOS_IN_A_MILLISECOND); 42 | 43 | // Checking for termination 44 | retStatus = pollApp(pAppConfiguration); 45 | if (retStatus != STATUS_SUCCESS) { 46 | printf("[WebRTC] pollApp(): operation returned status code: 0x%08x \n", retStatus); 47 | goto CleanUp; 48 | } 49 | printf("[WebRTC] streaming session terminated\n"); 50 | 51 | CleanUp: 52 | 53 | if (retStatus != STATUS_SUCCESS) { 54 | printf("[WebRTC] terminated with status code 0x%08x \n", retStatus); 55 | } 56 | 57 | printf("[WebRTC] cleaning up....\n"); 58 | 59 | if (pAppConfiguration != NULL) { 60 | retStatus = freeApp(&pAppConfiguration); 61 | if (retStatus != STATUS_SUCCESS) { 62 | printf("[WebRTC] freeApp(): operation returned status code: 0x%08x \n", retStatus); 63 | } 64 | } 65 | printf("[WebRTC] cleanup done\n"); 66 | 67 | RESET_INSTRUMENTED_ALLOCATORS(); 68 | // https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html 69 | // We can only return with 0 - 127. Some platforms treat exit code >= 128 70 | // to be a success code, which might give an unintended behaviour. 71 | // Some platforms also treat 1 or 0 differently, so it's better to use 72 | // EXIT_FAILURE and EXIT_SUCCESS macros for portability. 73 | return STATUS_FAILED(retStatus) ? EXIT_FAILURE : EXIT_SUCCESS; 74 | } 75 | -------------------------------------------------------------------------------- /main/AppMediaSrc_ESP32_FileSrc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #define LOG_CLASS "AppFileSrc" 16 | #include "AppMediaSrc_ESP32_FileSrc.h" 17 | #include "AppCommon.h" 18 | #include "fileio.h" 19 | 20 | #define NUMBER_OF_H264_FRAME_FILES 1500 21 | #define NUMBER_OF_OPUS_FRAME_FILES 618 22 | #define DEFAULT_FPS_VALUE 25 23 | 24 | #define FILESRC_AUDIO_FRAME_DURATION (20 * HUNDREDS_OF_NANOS_IN_A_MILLISECOND) 25 | #define FILESRC_VIDEO_FRAME_DURATION (HUNDREDS_OF_NANOS_IN_A_SECOND / DEFAULT_FPS_VALUE) 26 | 27 | typedef struct { 28 | RTC_CODEC codec; 29 | PBYTE pFrameBuffer; 30 | UINT32 frameBufferSize; 31 | } CodecStreamConf, *PCodecStreamConf; 32 | 33 | typedef struct { 34 | STATUS codecStatus; 35 | CodecStreamConf videoStream; 36 | CodecStreamConf audioStream; 37 | } CodecConfiguration, *PCodecConfiguration; 38 | 39 | typedef struct { 40 | MUTEX codecConfLock; 41 | CodecConfiguration codecConfiguration; //!< the configuration of gstreamer. 42 | // the codec. 43 | volatile ATOMIC_BOOL shutdownFileSrc; 44 | volatile ATOMIC_BOOL codecConfigLatched; 45 | // for meida output. 46 | PVOID mediaSinkHookUserdata; 47 | MediaSinkHook mediaSinkHook; 48 | PVOID mediaEosHookUserdata; 49 | MediaEosHook mediaEosHook; 50 | 51 | } FileSrcContext, *PFileSrcContext; 52 | 53 | STATUS readFrameFromDisk(PBYTE pFrame, PUINT32 pSize, PCHAR frameFilePath) 54 | { 55 | STATUS retStatus = STATUS_SUCCESS; 56 | UINT64 size = 0; 57 | 58 | if (pSize == NULL) { 59 | printf("[KVS Master] readFrameFromDisk(): operation returned status code: 0x%08x \n", STATUS_MEDIA_NULL_ARG); 60 | goto CleanUp; 61 | } 62 | 63 | size = *pSize; 64 | 65 | // Get the size and read into frame 66 | retStatus = fileio_read(frameFilePath, TRUE, pFrame, &size); 67 | if (retStatus != STATUS_SUCCESS) { 68 | printf("[KVS Master] readFile(): operation returned status code: 0x%08x \n", retStatus); 69 | goto CleanUp; 70 | } 71 | 72 | CleanUp: 73 | 74 | if (pSize != NULL) { 75 | *pSize = (UINT32) size; 76 | } 77 | 78 | return retStatus; 79 | } 80 | 81 | PVOID sendVideoPackets(PVOID args) 82 | { 83 | STATUS retStatus = STATUS_SUCCESS; 84 | PFileSrcContext pFileSrcContext = (PFileSrcContext) args; 85 | PCodecStreamConf pCodecStreamConf = NULL; 86 | Frame frame; 87 | UINT32 fileIndex = 0, frameSize; 88 | CHAR filePath[MAX_PATH_LEN + 1]; 89 | STATUS status; 90 | UINT64 startTime, lastFrameTime, elapsed; 91 | 92 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 93 | 94 | pCodecStreamConf = &pFileSrcContext->codecConfiguration.videoStream; 95 | pCodecStreamConf->pFrameBuffer = (PBYTE) MEMALLOC(7*1024); 96 | pCodecStreamConf->frameBufferSize = 7*1024; 97 | frame.presentationTs = 0; 98 | startTime = GETTIME(); 99 | lastFrameTime = startTime; 100 | 101 | while (!ATOMIC_LOAD_BOOL(&pFileSrcContext->shutdownFileSrc)) { 102 | fileIndex = fileIndex % NUMBER_OF_H264_FRAME_FILES + 1; 103 | snprintf(filePath, MAX_PATH_LEN, "/sdcard/h264SampleFrames/frame-%04d.h264", fileIndex); 104 | 105 | CHK(readFrameFromDisk(NULL, &frameSize, filePath) == STATUS_SUCCESS, STATUS_MEDIA_VIDEO_SINK); 106 | 107 | // Re-alloc if needed 108 | if (frameSize > pCodecStreamConf->frameBufferSize) { 109 | CHK((pCodecStreamConf->pFrameBuffer = (UINT8*) MEMREALLOC(pCodecStreamConf->pFrameBuffer, frameSize)) != NULL, STATUS_MEDIA_NOT_ENOUGH_MEMORY); 110 | pCodecStreamConf->frameBufferSize = frameSize; 111 | } 112 | 113 | // #TBD 114 | frame.flags = FRAME_FLAG_KEY_FRAME; 115 | frame.frameData = pCodecStreamConf->pFrameBuffer; 116 | frame.size = frameSize; 117 | 118 | CHK(readFrameFromDisk(frame.frameData, &frameSize, filePath) == STATUS_SUCCESS, STATUS_MEDIA_VIDEO_SINK); 119 | 120 | frame.presentationTs += FILESRC_VIDEO_FRAME_DURATION; 121 | frame.trackId = DEFAULT_VIDEO_TRACK_ID; 122 | frame.duration = 0; 123 | frame.version = FRAME_CURRENT_VERSION; 124 | frame.decodingTs = frame.presentationTs; 125 | if (pFileSrcContext->mediaSinkHook != NULL) { 126 | retStatus = pFileSrcContext->mediaSinkHook(pFileSrcContext->mediaSinkHookUserdata, &frame); 127 | } 128 | 129 | // Adjust sleep in the case the sleep itself and writeFrame take longer than expected. Since sleep makes sure that the thread 130 | // will be paused at least until the given amount, we can assume that there's no too early frame scenario. 131 | // Also, it's very unlikely to have a delay greater than FILESRC_VIDEO_FRAME_DURATION, so the logic assumes that this is always 132 | // true for simplicity. 133 | elapsed = lastFrameTime - startTime; 134 | THREAD_SLEEP(FILESRC_VIDEO_FRAME_DURATION - elapsed % FILESRC_VIDEO_FRAME_DURATION); 135 | lastFrameTime = GETTIME(); 136 | } 137 | 138 | CleanUp: 139 | if(pCodecStreamConf != NULL){ 140 | SAFE_MEMFREE(pCodecStreamConf->pFrameBuffer); 141 | } 142 | CHK_LOG_ERR(retStatus); 143 | /* free resources */ 144 | DLOGD("terminating media source"); 145 | if (pFileSrcContext->mediaEosHook != NULL) { 146 | retStatus = pFileSrcContext->mediaEosHook(pFileSrcContext->mediaEosHookUserdata); 147 | } 148 | return (PVOID) (ULONG_PTR) retStatus; 149 | } 150 | 151 | PVOID sendAudioPackets(PVOID args) 152 | { 153 | STATUS retStatus = STATUS_SUCCESS; 154 | PFileSrcContext pFileSrcContext = (PFileSrcContext) args; 155 | PCodecStreamConf pCodecStreamConf = NULL; 156 | Frame frame; 157 | UINT32 fileIndex = 0, frameSize; 158 | CHAR filePath[MAX_PATH_LEN + 1]; 159 | STATUS status; 160 | 161 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 162 | 163 | pCodecStreamConf = &pFileSrcContext->codecConfiguration.audioStream; 164 | pCodecStreamConf->pFrameBuffer = NULL; 165 | pCodecStreamConf->frameBufferSize = 0; 166 | frame.presentationTs = 0; 167 | 168 | while (!ATOMIC_LOAD_BOOL(&pFileSrcContext->shutdownFileSrc)) { 169 | fileIndex = fileIndex % NUMBER_OF_OPUS_FRAME_FILES + 1; 170 | snprintf(filePath, MAX_PATH_LEN, "/sdcard/opusSampleFrames/sample-%03d.opus", fileIndex); 171 | 172 | CHK(readFrameFromDisk(NULL, &frameSize, filePath) == STATUS_SUCCESS, STATUS_MEDIA_AUDIO_SINK); 173 | // Re-alloc if needed 174 | if (frameSize > pCodecStreamConf->frameBufferSize) { 175 | CHK((pCodecStreamConf->pFrameBuffer = (UINT8*) MEMREALLOC(pCodecStreamConf->pFrameBuffer, frameSize)) != NULL, STATUS_MEDIA_NOT_ENOUGH_MEMORY); 176 | pCodecStreamConf->frameBufferSize = frameSize; 177 | } 178 | frame.flags = FRAME_FLAG_KEY_FRAME; 179 | frame.frameData = pCodecStreamConf->pFrameBuffer; 180 | frame.size = frameSize; 181 | 182 | CHK(readFrameFromDisk(frame.frameData, &frameSize, filePath) == STATUS_SUCCESS, STATUS_MEDIA_AUDIO_SINK); 183 | 184 | frame.presentationTs += FILESRC_AUDIO_FRAME_DURATION; 185 | frame.trackId = DEFAULT_AUDIO_TRACK_ID; 186 | frame.duration = 0; 187 | frame.version = FRAME_CURRENT_VERSION; 188 | frame.decodingTs = frame.presentationTs; 189 | if (pFileSrcContext->mediaSinkHook != NULL) { 190 | retStatus = pFileSrcContext->mediaSinkHook(pFileSrcContext->mediaSinkHookUserdata, &frame); 191 | } 192 | 193 | THREAD_SLEEP(FILESRC_AUDIO_FRAME_DURATION); 194 | } 195 | 196 | CleanUp: 197 | 198 | if(pCodecStreamConf != NULL){ 199 | SAFE_MEMFREE(pCodecStreamConf->pFrameBuffer); 200 | } 201 | CHK_LOG_ERR(retStatus); 202 | /* free resources */ 203 | DLOGD("terminating media source"); 204 | if (pFileSrcContext->mediaEosHook != NULL) { 205 | retStatus = pFileSrcContext->mediaEosHook(pFileSrcContext->mediaEosHookUserdata); 206 | } 207 | return (PVOID) (ULONG_PTR) retStatus; 208 | } 209 | 210 | STATUS app_media_source_detroy(PMediaContext* ppMediaContext) 211 | { 212 | STATUS retStatus = STATUS_SUCCESS; 213 | PFileSrcContext pFileSrcContext; 214 | 215 | CHK(ppMediaContext != NULL, STATUS_MEDIA_NULL_ARG); 216 | pFileSrcContext = (PFileSrcContext) *ppMediaContext; 217 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 218 | if (IS_VALID_MUTEX_VALUE(pFileSrcContext->codecConfLock)) { 219 | MUTEX_FREE(pFileSrcContext->codecConfLock); 220 | } 221 | 222 | MEMFREE(pFileSrcContext); 223 | *ppMediaContext = pFileSrcContext = NULL; 224 | CleanUp: 225 | return retStatus; 226 | } 227 | 228 | STATUS app_media_source_init(PMediaContext* ppMediaContext) 229 | { 230 | STATUS retStatus = STATUS_SUCCESS; 231 | PFileSrcContext pFileSrcContext = NULL; 232 | PCodecConfiguration pGstConfiguration; 233 | PCodecStreamConf pVideoStream; 234 | PCodecStreamConf pAudioStream; 235 | 236 | CHK(ppMediaContext != NULL, STATUS_MEDIA_NULL_ARG); 237 | *ppMediaContext = NULL; 238 | CHK(NULL != (pFileSrcContext = (PFileSrcContext) MEMCALLOC(1, SIZEOF(FileSrcContext))), STATUS_MEDIA_NOT_ENOUGH_MEMORY); 239 | ATOMIC_STORE_BOOL(&pFileSrcContext->shutdownFileSrc, FALSE); 240 | ATOMIC_STORE_BOOL(&pFileSrcContext->codecConfigLatched, TRUE); 241 | 242 | pGstConfiguration = &pFileSrcContext->codecConfiguration; 243 | pGstConfiguration->codecStatus = STATUS_SUCCESS; 244 | pVideoStream = &pGstConfiguration->videoStream; 245 | pAudioStream = &pGstConfiguration->audioStream; 246 | pVideoStream->codec = RTC_CODEC_H264_PROFILE_42E01F_LEVEL_ASYMMETRY_ALLOWED_PACKETIZATION_MODE; 247 | pAudioStream->codec = RTC_CODEC_OPUS; 248 | 249 | pFileSrcContext->codecConfLock = MUTEX_CREATE(TRUE); 250 | CHK(IS_VALID_MUTEX_VALUE(pFileSrcContext->codecConfLock), STATUS_MEDIA_INVALID_MUTEX); 251 | 252 | // get the sdp information of rtsp server. 253 | //CHK_STATUS((discoverMediaSource(pFileSrcContext))); 254 | *ppMediaContext = pFileSrcContext; 255 | 256 | CleanUp: 257 | 258 | if (STATUS_FAILED(retStatus)) { 259 | if (pFileSrcContext != NULL) { 260 | app_media_source_detroy(pFileSrcContext); 261 | } 262 | } 263 | 264 | return retStatus; 265 | } 266 | 267 | STATUS app_media_source_isReady(PMediaContext pMediaContext) 268 | { 269 | STATUS retStatus = STATUS_SUCCESS; 270 | PFileSrcContext pFileSrcContext = (PFileSrcContext) pMediaContext; 271 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 272 | //if (!ATOMIC_LOAD_BOOL(&pFileSrcContext->codecConfigLatched)) { 273 | // discoverMediaSource(pFileSrcContext); 274 | //} 275 | 276 | if (ATOMIC_LOAD_BOOL(&pFileSrcContext->codecConfigLatched)) { 277 | retStatus = STATUS_SUCCESS; 278 | } else { 279 | retStatus = STATUS_MEDIA_NOT_READY; 280 | } 281 | 282 | CleanUp: 283 | 284 | return retStatus; 285 | } 286 | 287 | STATUS app_media_source_queryVideoCap(PMediaContext pMediaContext, RTC_CODEC* pCodec) 288 | { 289 | STATUS retStatus = STATUS_SUCCESS; 290 | PFileSrcContext pFileSrcContext = (PFileSrcContext) pMediaContext; 291 | PCodecStreamConf pVideoStream; 292 | CHK((pFileSrcContext != NULL) && (pCodec != NULL), STATUS_MEDIA_NULL_ARG); 293 | CHK(ATOMIC_LOAD_BOOL(&pFileSrcContext->codecConfigLatched), STATUS_MEDIA_NOT_READY); 294 | pVideoStream = &pFileSrcContext->codecConfiguration.videoStream; 295 | *pCodec = pVideoStream->codec; 296 | CleanUp: 297 | return retStatus; 298 | } 299 | 300 | STATUS app_media_source_queryAudioCap(PMediaContext pMediaContext, RTC_CODEC* pCodec) 301 | { 302 | STATUS retStatus = STATUS_SUCCESS; 303 | PFileSrcContext pFileSrcContext = (PFileSrcContext) pMediaContext; 304 | PCodecStreamConf pAudioStream; 305 | CHK((pFileSrcContext != NULL), STATUS_MEDIA_NULL_ARG); 306 | CHK(ATOMIC_LOAD_BOOL(&pFileSrcContext->codecConfigLatched), STATUS_MEDIA_NOT_READY); 307 | pAudioStream = &pFileSrcContext->codecConfiguration.audioStream; 308 | *pCodec = pAudioStream->codec; 309 | CleanUp: 310 | return retStatus; 311 | } 312 | 313 | STATUS app_media_source_linkSinkHook(PMediaContext pMediaContext, MediaSinkHook mediaSinkHook, PVOID udata) 314 | { 315 | STATUS retStatus = STATUS_SUCCESS; 316 | PFileSrcContext pFileSrcContext = (PFileSrcContext) pMediaContext; 317 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 318 | pFileSrcContext->mediaSinkHook = mediaSinkHook; 319 | pFileSrcContext->mediaSinkHookUserdata = udata; 320 | CleanUp: 321 | return retStatus; 322 | } 323 | 324 | STATUS app_media_source_linkEosHook(PMediaContext pMediaContext, MediaEosHook mediaEosHook, PVOID udata) 325 | { 326 | STATUS retStatus = STATUS_SUCCESS; 327 | PFileSrcContext pFileSrcContext = (PFileSrcContext) pMediaContext; 328 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 329 | pFileSrcContext->mediaEosHook = mediaEosHook; 330 | pFileSrcContext->mediaEosHookUserdata = udata; 331 | CleanUp: 332 | return retStatus; 333 | } 334 | 335 | PVOID app_media_source_run(PVOID args) 336 | { 337 | STATUS retStatus = STATUS_SUCCESS; 338 | PFileSrcContext pFileSrcContext = (PFileSrcContext) args; 339 | TID videoSenderTid = INVALID_TID_VALUE, audioSenderTid = INVALID_TID_VALUE; 340 | 341 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 342 | 343 | ATOMIC_STORE_BOOL(&pFileSrcContext->shutdownFileSrc, FALSE); 344 | DLOGI("media source is starting"); 345 | 346 | THREAD_CREATE_EX(&videoSenderTid, APP_MEDIA_VIDEO_SENDER_THREAD_NAME, APP_MEDIA_VIDEO_SENDER_THREAD_SIZE, TRUE, sendVideoPackets, (PVOID) pFileSrcContext); 347 | //THREAD_CREATE_EX(&audioSenderTid, APP_MEDIA_AUDIO_SENDER_THREAD_NAME, APP_MEDIA_AUDIO_SENDER_THREAD_SIZE, TRUE, sendAudioPackets, (PVOID) pFileSrcContext); 348 | 349 | if (videoSenderTid != INVALID_TID_VALUE) { 350 | //#TBD, the thread_join does not work. 351 | THREAD_JOIN(videoSenderTid, NULL); 352 | } 353 | 354 | if (audioSenderTid != INVALID_TID_VALUE) { 355 | THREAD_JOIN(audioSenderTid, NULL); 356 | } 357 | CleanUp: 358 | return (PVOID)(ULONG_PTR) retStatus; 359 | } 360 | 361 | STATUS app_media_source_shutdown(PMediaContext pMediaContext) 362 | { 363 | STATUS retStatus = STATUS_SUCCESS; 364 | PFileSrcContext pFileSrcContext = (PFileSrcContext) pMediaContext; 365 | CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG); 366 | ATOMIC_STORE_BOOL(&pFileSrcContext->shutdownFileSrc, TRUE); 367 | DLOGD("shutdown media source"); 368 | CleanUp: 369 | return retStatus; 370 | } 371 | 372 | AppMediaSrc gAppMediaSrc = { 373 | .app_media_source_init = app_media_source_init, 374 | .app_media_source_isReady = app_media_source_isReady, 375 | .app_media_source_queryVideoCap = app_media_source_queryVideoCap, 376 | .app_media_source_queryAudioCap = app_media_source_queryAudioCap, 377 | .app_media_source_linkSinkHook = app_media_source_linkSinkHook, 378 | .app_media_source_linkEosHook = app_media_source_linkEosHook, 379 | .app_media_source_run = app_media_source_run, 380 | .app_media_source_shutdown = app_media_source_shutdown, 381 | .app_media_source_isShutdown = NULL, 382 | .app_media_source_detroy = app_media_source_detroy 383 | }; -------------------------------------------------------------------------------- /main/AppMessageQueue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | /****************************************************************************** 16 | * HEADERS 17 | ******************************************************************************/ 18 | #define LOG_CLASS "AppMessageQueue" 19 | #include "AppMessageQueue.h" 20 | 21 | /****************************************************************************** 22 | * DEFINITIONS 23 | ******************************************************************************/ 24 | /****************************************************************************** 25 | * FUNCTIONS 26 | ******************************************************************************/ 27 | STATUS app_msg_q_createPendingMsgQ(PConnectionMsgQ pConnectionMsgQ, UINT64 hashValue, PPendingMessageQueue* ppPendingMessageQueue) 28 | { 29 | STATUS retStatus = STATUS_SUCCESS; 30 | PStackQueue pConnection = NULL; 31 | PPendingMessageQueue pPendingMessageQueue = NULL; 32 | 33 | CHK((pConnectionMsgQ != NULL) && (ppPendingMessageQueue != NULL), STATUS_APP_MSGQ_NULL_ARG); 34 | pConnection = pConnectionMsgQ->pMsqQueue; 35 | CHK(pConnection != NULL, STATUS_APP_MSGQ_NULL_ARG); 36 | 37 | CHK(NULL != (pPendingMessageQueue = (PPendingMessageQueue) MEMCALLOC(1, SIZEOF(PendingMessageQueue))), STATUS_APP_MSGQ_NOT_ENOUGH_MEMORY); 38 | pPendingMessageQueue->hashValue = hashValue; 39 | pPendingMessageQueue->createTime = GETTIME(); 40 | CHK(stack_queue_create(&pPendingMessageQueue->messageQueue) == STATUS_SUCCESS, STATUS_APP_MSGQ_CREATE_PENDING_MSQ); 41 | CHK(stack_queue_enqueue(pConnection, (UINT64) pPendingMessageQueue) == STATUS_SUCCESS, STATUS_APP_MSGQ_PUSH_CONN_MSQ); 42 | 43 | CleanUp: 44 | if (STATUS_FAILED(retStatus) && pPendingMessageQueue != NULL) { 45 | app_msg_q_freePendingMsgQ(pPendingMessageQueue); 46 | pPendingMessageQueue = NULL; 47 | } 48 | 49 | if (ppPendingMessageQueue != NULL) { 50 | *ppPendingMessageQueue = pPendingMessageQueue; 51 | } 52 | 53 | return retStatus; 54 | } 55 | 56 | STATUS app_msg_q_pushMsqIntoPendingMsgQ(PPendingMessageQueue pPendingMsgQ, PReceivedSignalingMessage pMsg) 57 | { 58 | STATUS retStatus = STATUS_SUCCESS; 59 | PReceivedSignalingMessage pReceivedSignalingMessageCopy = NULL; 60 | 61 | CHK((pPendingMsgQ != NULL) && (pMsg != NULL), STATUS_APP_MSGQ_NULL_ARG); 62 | CHK(NULL != (pReceivedSignalingMessageCopy = (PReceivedSignalingMessage) MEMCALLOC(1, SIZEOF(ReceivedSignalingMessage))), 63 | STATUS_APP_MSGQ_NOT_ENOUGH_MEMORY); 64 | *pReceivedSignalingMessageCopy = *pMsg; 65 | CHK(stack_queue_enqueue(pPendingMsgQ->messageQueue, (UINT64) pReceivedSignalingMessageCopy) == STATUS_SUCCESS, STATUS_APP_MSGQ_PUSH_PENDING_MSGQ); 66 | 67 | CleanUp: 68 | if (STATUS_FAILED(retStatus)) { 69 | SAFE_MEMFREE(pReceivedSignalingMessageCopy); 70 | } 71 | 72 | return retStatus; 73 | } 74 | 75 | STATUS app_msg_q_handlePendingMsgQ(PPendingMessageQueue pPendingMsgQ, MsgHandleHook msgHandleHook, PVOID uData) 76 | { 77 | STATUS retStatus = STATUS_SUCCESS; 78 | BOOL isEmpty = FALSE; 79 | PStackQueue pMessageQueue = NULL; 80 | PReceivedSignalingMessage pReceivedSignalingMessage = NULL; 81 | UINT64 pendingMsg; 82 | 83 | CHK(pPendingMsgQ != NULL, STATUS_APP_MSGQ_NULL_ARG); 84 | pMessageQueue = pPendingMsgQ->messageQueue; 85 | 86 | do { 87 | CHK(stack_queue_isEmpty(pMessageQueue, &isEmpty) == STATUS_SUCCESS, STATUS_APP_MSGQ_EMPTY_PENDING_MSGQ); 88 | if (!isEmpty) { 89 | pendingMsg = 0; 90 | CHK(stack_queue_dequeue(pMessageQueue, &pendingMsg) == STATUS_SUCCESS, STATUS_APP_MSGQ_POP_PENDING_MSGQ); 91 | CHK(pendingMsg != NULL, STATUS_APP_MSGQ_NULL_PENDING_MSG); 92 | pReceivedSignalingMessage = (PReceivedSignalingMessage) pendingMsg; 93 | if (msgHandleHook != NULL) { 94 | CHK(msgHandleHook(uData, &pReceivedSignalingMessage->signalingMessage) == STATUS_SUCCESS, STATUS_APP_MSGQ_HANDLE_PENDING_MSG); 95 | } 96 | SAFE_MEMFREE(pReceivedSignalingMessage); 97 | } 98 | } while (!isEmpty); 99 | 100 | CleanUp: 101 | app_msg_q_freePendingMsgQ(pPendingMsgQ); 102 | SAFE_MEMFREE(pReceivedSignalingMessage); 103 | CHK_LOG_ERR((retStatus)); 104 | return retStatus; 105 | } 106 | 107 | STATUS app_msg_q_freePendingMsgQ(PPendingMessageQueue pPendingMessageQueue) 108 | { 109 | STATUS retStatus = STATUS_SUCCESS; 110 | 111 | // free is idempotent 112 | CHK(pPendingMessageQueue != NULL, STATUS_APP_MSGQ_NULL_ARG); 113 | 114 | if (pPendingMessageQueue->messageQueue != NULL) { 115 | stack_queue_clear(pPendingMessageQueue->messageQueue, TRUE); 116 | stack_queue_free(pPendingMessageQueue->messageQueue); 117 | pPendingMessageQueue->messageQueue = NULL; 118 | } 119 | 120 | MEMFREE(pPendingMessageQueue); 121 | 122 | CleanUp: 123 | return retStatus; 124 | } 125 | 126 | STATUS app_msg_q_createConnectionMsqQ(PConnectionMsgQ* ppConnectionMsgQ) 127 | { 128 | STATUS retStatus = STATUS_SUCCESS; 129 | PConnectionMsgQ pConnectionMsgQ = NULL; 130 | 131 | CHK(ppConnectionMsgQ != NULL, STATUS_APP_MSGQ_NULL_ARG); 132 | pConnectionMsgQ = MEMCALLOC(1, SIZEOF(ConnectionMsgQ)); 133 | CHK(pConnectionMsgQ != NULL, STATUS_APP_MSGQ_NOT_ENOUGH_MEMORY); 134 | CHK(stack_queue_create(&pConnectionMsgQ->pMsqQueue) == STATUS_SUCCESS, STATUS_APP_MSGQ_CREATE_CONN_MSQ); 135 | 136 | CleanUp: 137 | 138 | if (STATUS_FAILED(retStatus) && pConnectionMsgQ != NULL) { 139 | app_msg_q_freeConnectionMsgQ(&pConnectionMsgQ); 140 | } 141 | 142 | if (ppConnectionMsgQ != NULL) { 143 | *ppConnectionMsgQ = pConnectionMsgQ; 144 | } 145 | 146 | return retStatus; 147 | } 148 | 149 | STATUS app_msg_q_getPendingMsgQByHashVal(PConnectionMsgQ pConnectionMsgQ, UINT64 clientHash, BOOL remove, PPendingMessageQueue* ppPendingMsgQ) 150 | { 151 | STATUS retStatus = STATUS_SUCCESS; 152 | PStackQueue pConnections = NULL; 153 | PPendingMessageQueue pPendingMsgQ = NULL; 154 | 155 | StackQueueIterator iterator; 156 | UINT64 data; 157 | BOOL iterate = TRUE; 158 | 159 | CHK((pConnectionMsgQ != NULL) && (ppPendingMsgQ != NULL), STATUS_APP_MSGQ_NULL_ARG); 160 | 161 | pConnections = pConnectionMsgQ->pMsqQueue; 162 | 163 | CHK_STATUS((stack_queue_iterator_get(pConnections, &iterator))); 164 | while (iterate && IS_VALID_ITERATOR(iterator)) { 165 | CHK_STATUS((stack_queue_iterator_getItem(iterator, &data))); 166 | CHK_STATUS((stack_queue_iterator_getNext(&iterator))); 167 | 168 | pPendingMsgQ = (PPendingMessageQueue) data; 169 | if (clientHash == pPendingMsgQ->hashValue) { 170 | *ppPendingMsgQ = pPendingMsgQ; 171 | iterate = FALSE; 172 | 173 | // Check if the item needs to be removed 174 | if (remove) { 175 | // This is OK to do as we are terminating the iterator anyway 176 | CHK_STATUS((stack_queue_removeItem(pConnections, data))); 177 | } 178 | } 179 | } 180 | 181 | CleanUp: 182 | 183 | if (ppPendingMsgQ != NULL) { 184 | *ppPendingMsgQ = pPendingMsgQ; 185 | } 186 | 187 | return retStatus; 188 | } 189 | 190 | STATUS app_msg_q_removeExpiredPendingMsgQ(PConnectionMsgQ pConnectionMsgQ, UINT64 interval) 191 | { 192 | STATUS retStatus = STATUS_SUCCESS; 193 | PStackQueue pConnection = NULL; 194 | PPendingMessageQueue pPendingMessageQueue = NULL; 195 | UINT32 i, count; 196 | UINT64 data, curTime; 197 | 198 | CHK(pConnectionMsgQ != NULL, STATUS_APP_MSGQ_NULL_ARG); 199 | pConnection = pConnectionMsgQ->pMsqQueue; 200 | 201 | curTime = GETTIME(); 202 | CHK_STATUS((stack_queue_getCount(pConnection, &count))); 203 | 204 | // Dequeue and enqueue in order to not break the iterator while removing an item 205 | for (i = 0; i < count; i++) { 206 | CHK_STATUS((stack_queue_dequeue(pConnection, &data))); 207 | 208 | // Check for expiry 209 | pPendingMessageQueue = (PPendingMessageQueue) data; 210 | CHK(pPendingMessageQueue != NULL, STATUS_APP_MSGQ_NULL_PENDING_MSGQ); 211 | if (pPendingMessageQueue->createTime + interval < curTime) { 212 | // Message queue has expired and needs to be freed 213 | app_msg_q_freePendingMsgQ(pPendingMessageQueue); 214 | DLOGD("Remove expired pending msgQ."); 215 | } else { 216 | // Enqueue back again as it's still valued 217 | CHK_STATUS((stack_queue_enqueue(pConnection, data))); 218 | } 219 | } 220 | 221 | CleanUp: 222 | 223 | return retStatus; 224 | } 225 | 226 | STATUS app_msg_q_freeConnectionMsgQ(PConnectionMsgQ* ppConnectionMsgQ) 227 | { 228 | STATUS retStatus = STATUS_SUCCESS; 229 | PConnectionMsgQ pConnectionMsgQ = NULL; 230 | PStackQueue pConnection = NULL; 231 | StackQueueIterator iterator; 232 | UINT64 data; 233 | 234 | CHK(ppConnectionMsgQ != NULL, STATUS_APP_MSGQ_NULL_ARG); 235 | pConnectionMsgQ = *ppConnectionMsgQ; 236 | CHK(pConnectionMsgQ != NULL, STATUS_APP_MSGQ_NULL_ARG); 237 | pConnection = pConnectionMsgQ->pMsqQueue; 238 | 239 | CHK(pConnection != NULL, STATUS_APP_MSGQ_NULL_ARG); 240 | 241 | // Iterate and free all the pending queues 242 | stack_queue_iterator_get(pConnection, &iterator); 243 | while (IS_VALID_ITERATOR(iterator)) { 244 | stack_queue_iterator_getItem(iterator, &data); 245 | stack_queue_iterator_getNext(&iterator); 246 | app_msg_q_freePendingMsgQ((PPendingMessageQueue) data); 247 | } 248 | 249 | stack_queue_clear(pConnection, FALSE); 250 | stack_queue_free(pConnection); 251 | pConnection = NULL; 252 | 253 | CleanUp: 254 | 255 | SAFE_MEMFREE(pConnectionMsgQ); 256 | if (ppConnectionMsgQ != NULL) { 257 | *ppConnectionMsgQ = pConnectionMsgQ; 258 | } 259 | return retStatus; 260 | } 261 | -------------------------------------------------------------------------------- /main/AppMetrics.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #define LOG_CLASS "AppMetrics" 16 | #include "AppMetrics.h" 17 | #include "filelogger.h" 18 | UINT32 getLogLevel(VOID) 19 | { 20 | PCHAR pLogLevel; 21 | UINT32 logLevel = LOG_LEVEL_DEBUG; 22 | // Set the logger log level 23 | if (NULL == (pLogLevel = GETENV(DEBUG_LOG_LEVEL_ENV_VAR)) || STATUS_SUCCESS != STRTOUI32(pLogLevel, NULL, 10, &logLevel) || 24 | logLevel < LOG_LEVEL_VERBOSE || logLevel > LOG_LEVEL_SILENT) { 25 | logLevel = LOG_LEVEL_WARN; 26 | } 27 | return logLevel; 28 | } 29 | 30 | STATUS app_metrics_setupFileLogging(PBOOL pEnable) 31 | { 32 | STATUS retStatus = STATUS_SUCCESS; 33 | BOOL enable = FALSE; 34 | // setup the file logging. 35 | 36 | if (NULL != GETENV(ENABLE_FILE_LOGGING)) { 37 | enable = TRUE; 38 | } else { 39 | CHK(FALSE, STATUS_SUCCESS); 40 | } 41 | retStatus = file_logger_create(APP_METRICS_FILE_LOGGING_BUFFER_SIZE, APP_METRICS_LOG_FILES_MAX_NUMBER, 42 | (PCHAR) FILE_LOGGER_LOG_FILE_DIRECTORY_PATH, TRUE, TRUE, NULL); 43 | if (retStatus != STATUS_SUCCESS) { 44 | DLOGI("peration returned status code: 0x%08x \n", retStatus); 45 | enable = FALSE; 46 | retStatus = STATUS_APP_METRICS_SETUP_LOGGER; 47 | } 48 | 49 | CleanUp: 50 | *pEnable = enable; 51 | return retStatus; 52 | } 53 | 54 | STATUS app_metrics_closeFileLogging(VOID) 55 | { 56 | STATUS retStatus = STATUS_SUCCESS; 57 | retStatus = file_logger_free(); 58 | if (retStatus != STATUS_SUCCESS) { 59 | retStatus = STATUS_APP_METRICS_FREE_LOGGER; 60 | } 61 | return retStatus; 62 | } 63 | 64 | STATUS app_metrics_logIceServerStats(PRtcPeerConnection pRtcPeerConnection, UINT32 index) 65 | { 66 | ENTERS(); 67 | STATUS retStatus = STATUS_SUCCESS; 68 | PRtcStats pRtcMetrics = NULL; 69 | CHK(pRtcPeerConnection != NULL, STATUS_APP_METRICS_NULL_ARG); 70 | CHK(NULL != (pRtcMetrics = (PRtcStats) MEMCALLOC(1, SIZEOF(RtcStats))), STATUS_APP_COMMON_NOT_ENOUGH_MEMORY); 71 | 72 | pRtcMetrics->requestedTypeOfStats = RTC_STATS_TYPE_ICE_SERVER; 73 | pRtcMetrics->rtcStatsObject.iceServerStats.iceServerIndex = index; 74 | CHK(metrics_get(pRtcPeerConnection, NULL, pRtcMetrics) == STATUS_SUCCESS, STATUS_APP_METRICS_ICE_SERVER); 75 | DLOGD("ICE Server URL: %s", pRtcMetrics->rtcStatsObject.iceServerStats.url); 76 | DLOGD("ICE Server port: %d", pRtcMetrics->rtcStatsObject.iceServerStats.port); 77 | DLOGD("ICE Server protocol: %s", pRtcMetrics->rtcStatsObject.iceServerStats.protocol); 78 | DLOGD("Total requests sent:%" PRIu64, pRtcMetrics->rtcStatsObject.iceServerStats.totalRequestsSent); 79 | DLOGD("Total responses received: %" PRIu64, pRtcMetrics->rtcStatsObject.iceServerStats.totalResponsesReceived); 80 | DLOGD("Total round trip time: %" PRIu64 "ms", pRtcMetrics->rtcStatsObject.iceServerStats.totalRoundTripTime / HUNDREDS_OF_NANOS_IN_A_MILLISECOND); 81 | 82 | CleanUp: 83 | SAFE_MEMFREE(pRtcMetrics); 84 | LEAVES(); 85 | return retStatus; 86 | } 87 | 88 | STATUS logSelectedIceCandidatesInformation(PRtcPeerConnection pRtcPeerConnection) 89 | { 90 | ENTERS(); 91 | STATUS retStatus = STATUS_SUCCESS; 92 | PRtcStats pRtcMetrics = NULL; 93 | 94 | CHK(NULL != (pRtcMetrics = (PRtcStats) MEMCALLOC(1, SIZEOF(RtcStats))), STATUS_NOT_ENOUGH_MEMORY); 95 | 96 | CHK(pRtcPeerConnection != NULL, STATUS_APP_METRICS_NULL_ARG); 97 | pRtcMetrics->requestedTypeOfStats = RTC_STATS_TYPE_LOCAL_CANDIDATE; 98 | CHK(metrics_get(pRtcPeerConnection, NULL, pRtcMetrics) == STATUS_SUCCESS, STATUS_APP_METRICS_LOCAL_ICE_CANDIDATE); 99 | DLOGD("Local Candidate IP Address: %s", pRtcMetrics->rtcStatsObject.localIceCandidateStats.address); 100 | DLOGD("Local Candidate type: %s", pRtcMetrics->rtcStatsObject.localIceCandidateStats.candidateType); 101 | DLOGD("Local Candidate port: %d", pRtcMetrics->rtcStatsObject.localIceCandidateStats.port); 102 | DLOGD("Local Candidate priority: %d", pRtcMetrics->rtcStatsObject.localIceCandidateStats.priority); 103 | DLOGD("Local Candidate transport protocol: %s", pRtcMetrics->rtcStatsObject.localIceCandidateStats.protocol); 104 | DLOGD("Local Candidate relay protocol: %s", pRtcMetrics->rtcStatsObject.localIceCandidateStats.relayProtocol); 105 | DLOGD("Local Candidate Ice server source: %s", pRtcMetrics->rtcStatsObject.localIceCandidateStats.url); 106 | 107 | pRtcMetrics->requestedTypeOfStats = RTC_STATS_TYPE_REMOTE_CANDIDATE; 108 | CHK(metrics_get(pRtcPeerConnection, NULL, pRtcMetrics) == STATUS_SUCCESS, STATUS_APP_METRICS_REMOTE_ICE_CANDIDATE); 109 | DLOGD("Remote Candidate IP Address: %s", pRtcMetrics->rtcStatsObject.remoteIceCandidateStats.address); 110 | DLOGD("Remote Candidate type: %s", pRtcMetrics->rtcStatsObject.remoteIceCandidateStats.candidateType); 111 | DLOGD("Remote Candidate port: %d", pRtcMetrics->rtcStatsObject.remoteIceCandidateStats.port); 112 | DLOGD("Remote Candidate priority: %d", pRtcMetrics->rtcStatsObject.remoteIceCandidateStats.priority); 113 | DLOGD("Remote Candidate transport protocol: %s", pRtcMetrics->rtcStatsObject.remoteIceCandidateStats.protocol); 114 | CleanUp: 115 | SAFE_MEMFREE(pRtcMetrics); 116 | LEAVES(); 117 | return retStatus; 118 | } 119 | 120 | STATUS logSignalingClientStats(PSignalingClientMetrics pSignalingClientMetrics) 121 | { 122 | ENTERS(); 123 | STATUS retStatus = STATUS_SUCCESS; 124 | CHK(pSignalingClientMetrics != NULL, STATUS_APP_METRICS_NULL_ARG); 125 | DLOGD("Signaling client connection duration: %" PRIu64 " ms", 126 | (pSignalingClientMetrics->signalingClientStats.connectionDuration / HUNDREDS_OF_NANOS_IN_A_MILLISECOND)); 127 | DLOGD("Number of signaling client API errors: %d", pSignalingClientMetrics->signalingClientStats.numberOfErrors); 128 | DLOGD("Number of runtime errors in the session: %d", pSignalingClientMetrics->signalingClientStats.numberOfRuntimeErrors); 129 | DLOGD("Signaling client uptime: %" PRIu64 " ms", 130 | (pSignalingClientMetrics->signalingClientStats.connectionDuration / HUNDREDS_OF_NANOS_IN_A_MILLISECOND)); 131 | // This gives the EMA of the createChannel, describeChannel, getChannelEndpoint and deleteChannel calls 132 | DLOGD("Control Plane API call latency: %" PRIu64 " ms", 133 | (pSignalingClientMetrics->signalingClientStats.cpApiCallLatency / HUNDREDS_OF_NANOS_IN_A_MILLISECOND)); 134 | // This gives the EMA of the getIceConfig() call. 135 | DLOGD("Data Plane API call latency: %" PRIu64 " ms", 136 | (pSignalingClientMetrics->signalingClientStats.dpApiCallLatency / HUNDREDS_OF_NANOS_IN_A_MILLISECOND)); 137 | CleanUp: 138 | LEAVES(); 139 | return retStatus; 140 | } 141 | -------------------------------------------------------------------------------- /main/AppSignaling.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #define LOG_CLASS "AppSignaling" 16 | #include "AppSignaling.h" 17 | #include "kvs/common_defs.h" 18 | 19 | STATUS app_signaling_init(PAppSignaling pAppSignaling, SignalingClientMessageReceivedFunc onMessageReceived, 20 | SignalingClientStateChangedFunc onStateChanged, SignalingClientErrorReportFunc pOnError, UINT64 udata, BOOL useTurn) 21 | { 22 | STATUS retStatus = STATUS_SUCCESS; 23 | pAppSignaling->signalingClientHandle = INVALID_SIGNALING_CLIENT_HANDLE_VALUE; 24 | pAppSignaling->useTurn = useTurn; 25 | pAppSignaling->signalingSendMessageLock = MUTEX_CREATE(FALSE); 26 | CHK(IS_VALID_MUTEX_VALUE(pAppSignaling->signalingSendMessageLock), STATUS_APP_SIGNALING_INVALID_MUTEX); 27 | pAppSignaling->signalingClientCallbacks.version = SIGNALING_CLIENT_CALLBACKS_CURRENT_VERSION; 28 | pAppSignaling->signalingClientCallbacks.messageReceivedFn = onMessageReceived; 29 | pAppSignaling->signalingClientCallbacks.stateChangeFn = onStateChanged; 30 | pAppSignaling->signalingClientCallbacks.errorReportFn = pOnError; 31 | pAppSignaling->signalingClientCallbacks.customData = (UINT64) udata; 32 | 33 | CleanUp: 34 | return retStatus; 35 | } 36 | 37 | SIGNALING_CHANNEL_ROLE_TYPE app_signaling_getRole(PAppSignaling pAppSignaling) 38 | { 39 | return pAppSignaling->channelInfo.channelRoleType; 40 | } 41 | 42 | STATUS app_signaling_queryServer(PAppSignaling pAppSignaling, PRtcIceServer pIceServer, PUINT32 pServerNum) 43 | { 44 | STATUS retStatus = STATUS_SUCCESS; 45 | UINT32 i, j, iceConfigCount, uriCount = 0, maxTurnServer = 1; 46 | PIceConfigInfo pIceConfigInfo; 47 | *pServerNum = 0; 48 | 49 | // Set the STUN server 50 | PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; 51 | // If region is in CN, add CN region uri postfix 52 | if (STRSTR(pAppSignaling->channelInfo.pRegion, "cn-")) { 53 | pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX_CN; 54 | } 55 | SNPRINTF(pIceServer[0].urls, MAX_ICE_CONFIG_URI_LEN, KINESIS_VIDEO_STUN_URL, pAppSignaling->channelInfo.pRegion, 56 | pKinesisVideoStunUrlPostFix); 57 | *pServerNum = 1; 58 | 59 | if (pAppSignaling->useTurn) { 60 | // Set the URIs from the configuration 61 | CHK(signaling_client_getIceConfigInfoCount(pAppSignaling->signalingClientHandle, &iceConfigCount) == STATUS_SUCCESS, 62 | STATUS_APP_SIGNALING_INVALID_INFO_COUNT); 63 | 64 | // signaling_client_getIceConfigInfoCount can return more than one turn server. Use only one to optimize 65 | // candidate gathering latency. But user can also choose to use more than 1 turn server. 66 | for (uriCount = 0, i = 0; i < maxTurnServer; i++) { 67 | CHK(signaling_client_getIceConfigInfo(pAppSignaling->signalingClientHandle, i, &pIceConfigInfo) == STATUS_SUCCESS, 68 | STATUS_APP_SIGNALING_INVALID_INFO); 69 | 70 | for (j = 0; j < pIceConfigInfo->uriCount; j++) { 71 | /* 72 | * if pIceServer[uriCount + 1].urls is "turn:ip:port?transport=udp" then ICE will try TURN over UDP 73 | * if pIceServer[uriCount + 1].urls is "turn:ip:port?transport=tcp" then ICE will try TURN over TCP/TLS 74 | * if pIceServer[uriCount + 1].urls is "turns:ip:port?transport=udp", it's currently ignored because sdk dont do TURN 75 | * over DTLS yet. if pIceServer[uriCount + 1].urls is "turns:ip:port?transport=tcp" then ICE will try TURN over TCP/TLS 76 | * if pIceServer[uriCount + 1].urls is "turn:ip:port" then ICE will try both TURN over UPD and TCP/TLS 77 | * 78 | * It's recommended to not pass too many TURN iceServers to configuration because it will slow down ice gathering in non-trickle mode. 79 | */ 80 | 81 | STRNCPY(pIceServer[uriCount + 1].urls, pIceConfigInfo->uris[j], MAX_ICE_CONFIG_URI_LEN); 82 | STRNCPY(pIceServer[uriCount + 1].credential, pIceConfigInfo->password, MAX_ICE_CONFIG_CREDENTIAL_LEN); 83 | STRNCPY(pIceServer[uriCount + 1].username, pIceConfigInfo->userName, MAX_ICE_CONFIG_USER_NAME_LEN); 84 | uriCount++; 85 | } 86 | } 87 | } 88 | // add one for stun server. 89 | *pServerNum = uriCount + 1; 90 | CleanUp: 91 | 92 | return retStatus; 93 | } 94 | 95 | STATUS app_signaling_create(PAppSignaling pAppSignaling) 96 | { 97 | STATUS retStatus = STATUS_SUCCESS; 98 | CHK(signaling_client_create(&pAppSignaling->clientInfo, &pAppSignaling->channelInfo, &pAppSignaling->signalingClientCallbacks, 99 | pAppSignaling->pAppCredential->pCredentialProvider, &pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, 100 | STATUS_APP_SIGNALING_CREATE); 101 | DLOGD("Signaling client created successfully\n"); 102 | 103 | CleanUp: 104 | return retStatus; 105 | } 106 | 107 | STATUS app_signaling_fetch(PAppSignaling pAppSignaling) 108 | { 109 | STATUS retStatus = STATUS_SUCCESS; 110 | CHK(signaling_client_fetch(pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, STATUS_APP_SIGNALING_FETCH); 111 | 112 | CleanUp: 113 | return retStatus; 114 | } 115 | 116 | STATUS app_signaling_connect(PAppSignaling pAppSignaling) 117 | { 118 | STATUS retStatus = STATUS_SUCCESS; 119 | // Enable the processing of the messages 120 | CHK(signaling_client_connect(pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, STATUS_APP_SIGNALING_CONNECT); 121 | 122 | CleanUp: 123 | return retStatus; 124 | } 125 | 126 | STATUS app_signaling_shutdown(PAppSignaling pAppSignaling) 127 | { 128 | STATUS retStatus = STATUS_SUCCESS; 129 | CHK(signaling_client_shutdown(pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, STATUS_APP_SIGNALING_SHUTDOWN); 130 | 131 | CleanUp: 132 | return retStatus; 133 | } 134 | 135 | STATUS app_signaling_check(PAppSignaling pAppSignaling) 136 | { 137 | STATUS retStatus = STATUS_APP_SIGNALING_INVALID_HANDLE; 138 | SIGNALING_CLIENT_STATE signalingClientState; 139 | 140 | // Check the signaling client state and connect if needed 141 | if (IS_VALID_SIGNALING_CLIENT_HANDLE(pAppSignaling->signalingClientHandle)) { 142 | CHK(signaling_client_getCurrentState(pAppSignaling->signalingClientHandle, &signalingClientState) == STATUS_SUCCESS, 143 | STATUS_APP_SIGNALING_NOT_READY); 144 | retStatus = STATUS_SUCCESS; 145 | if (signalingClientState == SIGNALING_CLIENT_STATE_READY) { 146 | CHK(signaling_client_connect(pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, STATUS_APP_SIGNALING_CONNECT); 147 | } 148 | } 149 | 150 | CleanUp: 151 | 152 | return retStatus; 153 | } 154 | 155 | STATUS app_signaling_sendMsg(PAppSignaling pAppSignaling, PSignalingMessage pMessage) 156 | { 157 | STATUS retStatus = STATUS_SUCCESS; 158 | BOOL locked = FALSE; 159 | 160 | // Validate the input params 161 | CHK((pAppSignaling != NULL) && (pMessage != NULL), STATUS_APP_SIGNALING_NULL_ARG); 162 | CHK(IS_VALID_MUTEX_VALUE(pAppSignaling->signalingSendMessageLock), STATUS_APP_SIGNALING_INVALID_MUTEX); 163 | CHK(IS_VALID_SIGNALING_CLIENT_HANDLE(pAppSignaling->signalingClientHandle), STATUS_APP_SIGNALING_INVALID_HANDLE); 164 | 165 | MUTEX_LOCK(pAppSignaling->signalingSendMessageLock); 166 | locked = TRUE; 167 | CHK(signaling_client_sendMsg(pAppSignaling->signalingClientHandle, pMessage) == STATUS_SUCCESS, STATUS_APP_SIGNALING_SEND); 168 | 169 | CleanUp: 170 | 171 | if (locked) { 172 | MUTEX_UNLOCK(pAppSignaling->signalingSendMessageLock); 173 | } 174 | 175 | CHK_LOG_ERR((retStatus)); 176 | return retStatus; 177 | } 178 | 179 | STATUS app_signaling_restart(PAppSignaling pAppSignaling) 180 | { 181 | STATUS retStatus = STATUS_SUCCESS; 182 | DLOGD("Restart app signaling"); 183 | // Check if we need to re-create the signaling client on-the-fly 184 | CHK(signaling_client_free(&pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, STATUS_APP_SIGNALING_RESTART); 185 | CHK(signaling_client_create(&pAppSignaling->clientInfo, &pAppSignaling->channelInfo, &pAppSignaling->signalingClientCallbacks, 186 | pAppSignaling->pAppCredential->pCredentialProvider, &pAppSignaling->signalingClientHandle) == STATUS_SUCCESS, 187 | STATUS_APP_SIGNALING_RESTART); 188 | 189 | CleanUp: 190 | 191 | return retStatus; 192 | } 193 | 194 | STATUS app_signaling_free(PAppSignaling pAppSignaling) 195 | { 196 | STATUS retStatus = STATUS_SUCCESS; 197 | DLOGD("Free app signaling"); 198 | if (pAppSignaling->signalingClientHandle != INVALID_SIGNALING_CLIENT_HANDLE_VALUE) { 199 | retStatus = signaling_client_free(&pAppSignaling->signalingClientHandle); 200 | if (retStatus != STATUS_SUCCESS) { 201 | retStatus = STATUS_APP_SIGNALING_FREE; 202 | } 203 | } 204 | 205 | if (IS_VALID_MUTEX_VALUE(pAppSignaling->signalingSendMessageLock)) { 206 | MUTEX_FREE(pAppSignaling->signalingSendMessageLock); 207 | pAppSignaling->signalingSendMessageLock = INVALID_MUTEX_VALUE; 208 | } 209 | 210 | return retStatus; 211 | } 212 | -------------------------------------------------------------------------------- /main/AppWebRTC.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #define LOG_CLASS "AppWebRTC" 16 | #include "AppWebRTC.h" 17 | 18 | STATUS app_webrtc_init(PAppConfiguration pAppConfiguration) 19 | { 20 | STATUS retStatus = STATUS_SUCCESS; 21 | retStatus = pc_initWebRtc(); 22 | if (retStatus != STATUS_SUCCESS) { 23 | retStatus = STATUS_APP_WEBRTC_INIT; 24 | } 25 | return retStatus; 26 | } 27 | 28 | STATUS app_webrtc_deinit(PAppConfiguration pAppConfiguration) 29 | { 30 | STATUS retStatus = STATUS_SUCCESS; 31 | retStatus = pc_deinitWebRtc(); 32 | if (retStatus != STATUS_SUCCESS) { 33 | retStatus = STATUS_APP_WEBRTC_DEINIT; 34 | } 35 | return retStatus; 36 | } 37 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | option(ENABLE_STREAMING "enable the streaming" ON) 2 | option(ENABLE_DATA_CHANNEL "enable the data channel" ON) 3 | option(ENABLE_HEADER_CONFIG_CLIENT_INFO "enable config app client info with config header" OFF) 4 | 5 | set(LIB_SOURCE_DIR "${CMAKE_SOURCE_DIR}/main/lib") 6 | 7 | set(LIBKVSWEBRTC_NAME "amazon-kinesis-video-streams-webrtc-sdk-c") 8 | set(LIBKVSWEBRTC_INCLUDE_DIRS "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/include" 9 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source" 10 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/api_call" 11 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/credential" 12 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/crypto" 13 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/ice" 14 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/Json" 15 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/net" 16 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/PeerConnection" 17 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/Rtcp" 18 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/Rtp" 19 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/Rtp/Codecs" 20 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/sctp" 21 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/Sdp" 22 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/signaling" 23 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/srtp" 24 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/state_machine" 25 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/stun" 26 | "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/utils") 27 | 28 | set(OPEN_SRC_INCLUDE_DIRS "${LIBKVSWEBRTC_INCLUDE_DIRS}") 29 | set(APP_INCLUDE_DIRS "./include") 30 | idf_component_register(SRCS "kvswebrtc_example_main.c" 31 | "AppCommon.c" 32 | "AppCredential.c" 33 | "AppDataChannel.c" 34 | "AppMediaSrc_ESP32_FileSrc.c" 35 | "AppMain.c" 36 | "AppMessageQueue.c" 37 | "AppMetrics.c" 38 | "AppSignaling.c" 39 | "AppWebRTC.c" 40 | INCLUDE_DIRS "." "${OPEN_SRC_INCLUDE_DIRS}" "${APP_INCLUDE_DIRS}" 41 | REQUIRES nvs_flash mbedtls lwip fatfs esp_common pthread 42 | ) 43 | 44 | 45 | idf_component_get_property(nvs_flash_lib nvs_flash COMPONENT_LIB) 46 | idf_component_get_property(mbedtls_lib mbedtls COMPONENT_LIB) 47 | idf_component_get_property(esp_common_lib esp_common COMPONENT_LIB) 48 | idf_component_get_property(pthread_lib pthread COMPONENT_LIB) 49 | 50 | set(KVS_PLAT_ESP_FREERTOS ON CACHE BOOL "Build for ESP FreeRTOS") 51 | add_definitions(-DKVS_PLAT_ESP_FREERTOS) 52 | if (ENABLE_STREAMING) 53 | add_definitions(-DENABLE_STREAMING) 54 | set(ENABLE_STREAMING ON CACHE BOOL "Enable support for streaming") 55 | set(LIBKVSWEBRTC_INCLUDE_DIRS "${LIBKVSWEBRTC_INCLUDE_DIRS}" "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/srtp") 56 | else() 57 | set(ENABLE_STREAMING OFF CACHE BOOL "Enable support for streaming") 58 | endif() 59 | if (ENABLE_DATA_CHANNEL) 60 | add_definitions(-DENABLE_DATA_CHANNEL) 61 | set(ENABLE_DATA_CHANNEL ON CACHE BOOL "Enable support for data channel") 62 | set(LIBKVSWEBRTC_INCLUDE_DIRS "${LIBKVSWEBRTC_INCLUDE_DIRS}" "${LIB_SOURCE_DIR}/${LIBKVSWEBRTC_NAME}/src/source/sctp") 63 | else() 64 | set(ENABLE_DATA_CHANNEL OFF CACHE BOOL "Enable support for data channel") 65 | endif() 66 | 67 | 68 | message("############################## start llhttp ##############################") 69 | add_subdirectory(lib/libllhttp) 70 | set_property(TARGET llhttp APPEND PROPERTY LINK_LIBRARIES 71 | ${nvs_flash_lib} 72 | ${mbedtls_lib}) 73 | set_property(TARGET llhttp APPEND PROPERTY INTERFACE_LINK_LIBRARIES 74 | ${nvs_flash_lib} 75 | ${mbedtls_lib}) 76 | target_link_libraries(${COMPONENT_LIB} PUBLIC llhttp) 77 | set(KVS_LIBLLHTTP_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/esp-idf/main/lib/libllhttp/include" "${LIB_SOURCE_DIR}/libllhttp/include") 78 | 79 | 80 | message("############################## start wslay ##############################") 81 | 82 | add_subdirectory(lib/wslay) 83 | set_property(TARGET wslay APPEND PROPERTY LINK_LIBRARIES 84 | ${nvs_flash_lib} 85 | ${mbedtls_lib}) 86 | set_property(TARGET wslay APPEND PROPERTY INTERFACE_LINK_LIBRARIES 87 | ${nvs_flash_lib} 88 | ${mbedtls_lib}) 89 | target_link_libraries(${COMPONENT_LIB} PUBLIC wslay) 90 | set(KVS_LIBWSLAY_INCLUDE_DIRS "${LIB_SOURCE_DIR}/wslay/lib/includes" "${CMAKE_BINARY_DIR}/esp-idf/main/lib/wslay/lib/includes") 91 | message("KVS_LIBWSLAY_INCLUDE_DIRS:${KVS_LIBWSLAY_INCLUDE_DIRS}") 92 | 93 | 94 | if(ENABLE_STREAMING) 95 | message("############################## start srtp ##############################") 96 | add_subdirectory(lib/libsrtp) 97 | set_property(TARGET srtp2 APPEND PROPERTY LINK_LIBRARIES ${mbedtls_lib}) 98 | set_property(TARGET srtp2 APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${mbedtls_lib}) 99 | target_link_libraries(${COMPONENT_LIB} PUBLIC srtp2) 100 | set(KVS_LIBSRTP_INCLUDE_DIRS "${LIB_SOURCE_DIR}/libsrtp/include") 101 | endif() 102 | 103 | if(ENABLE_DATA_CHANNEL) 104 | message("############################## start sctp ##############################") 105 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format-truncation") 106 | add_definitions(-DSCTP_USE_LWIP) 107 | add_definitions(-DSCTP_USE_RTOS) 108 | set(sctp_link_programs_static ON CACHE BOOL "Link example programs static") 109 | add_subdirectory(lib/usrsctp) 110 | set_property(TARGET usrsctp-static APPEND PROPERTY LINK_LIBRARIES ${mbedtls_lib} ${esp_common_lib} ${pthread_lib}) 111 | set_property(TARGET usrsctp-static APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${mbedtls_lib} ${esp_common_lib} ${pthread_lib}) 112 | target_link_libraries(${COMPONENT_LIB} PUBLIC usrsctp-static) 113 | set(KVS_USRSCTP_INCLUDE_DIRS "${LIB_SOURCE_DIR}/usrsctp/usrsctplib") 114 | endif() 115 | 116 | message("############################## start webrtc ##############################") 117 | set(BUILD_DEPENDENCIES OFF CACHE BOOL "Whether or not to build depending libraries from source") 118 | set(BUILD_STATIC_LIBS ON CACHE BOOL "Build all libraries statically. (This includes third-party libraries.)") 119 | set(BUILD_SAMPLE OFF CACHE BOOL "Build available samples") 120 | set(OPEN_SRC_INCLUDE_DIRS "${OPEN_SRC_INCLUDE_DIRS}" "${KVS_LIBWSLAY_INCLUDE_DIRS}" "${KVS_LIBLLHTTP_INCLUDE_DIRS}" "${KVS_LIBSRTP_INCLUDE_DIRS}" "${KVS_USRSCTP_INCLUDE_DIRS}") 121 | 122 | add_subdirectory(lib/amazon-kinesis-video-streams-webrtc-sdk-c) 123 | 124 | set_property(TARGET kvsWebrtcStateMachine APPEND PROPERTY LINK_LIBRARIES 125 | ${esp_common_lib} ${pthread_lib} ${mbedtls_lib} ${nvs_flash_lib}) 126 | set_property(TARGET kvsWebrtcStateMachine APPEND PROPERTY INTERFACE_LINK_LIBRARIES 127 | ${esp_common_lib} ${pthread_lib} ${mbedtls_lib} ${nvs_flash_lib}) 128 | 129 | set_property(TARGET kvsWebrtcUtils APPEND PROPERTY LINK_LIBRARIES 130 | ${esp_common_lib} ${pthread_lib} ${mbedtls_lib} ${nvs_flash_lib}) 131 | set_property(TARGET kvsWebrtcUtils APPEND PROPERTY INTERFACE_LINK_LIBRARIES 132 | ${esp_common_lib} ${pthread_lib} ${mbedtls_lib} ${nvs_flash_lib}) 133 | 134 | set_property(TARGET kvsWebrtcSignalingClient APPEND PROPERTY LINK_LIBRARIES 135 | ${esp_common_lib} ${pthread_lib} 136 | wslay 137 | llhttp 138 | ${mbedtls_lib}) 139 | set_property(TARGET kvsWebrtcSignalingClient APPEND PROPERTY INTERFACE_LINK_LIBRARIES 140 | ${esp_common_lib} ${pthread_lib} 141 | wslay 142 | llhttp 143 | ${mbedtls_lib}) 144 | target_link_libraries(${COMPONENT_LIB} PUBLIC kvsWebrtcSignalingClient) 145 | 146 | set_property(TARGET kvsWebrtcClient APPEND PROPERTY LINK_LIBRARIES 147 | ${esp_common_lib} ${pthread_lib} 148 | mbedtls 149 | ${mbedtls_lib} 150 | ${nvs_flash_lib}) 151 | 152 | if(ENABLE_STREAMING) 153 | set_property(TARGET kvsWebrtcClient APPEND PROPERTY LINK_LIBRARIES srtp2) 154 | endif() 155 | if(ENABLE_DATA_CHANNEL) 156 | set_property(TARGET kvsWebrtcClient APPEND PROPERTY LINK_LIBRARIES usrsctp-static) 157 | endif() 158 | 159 | set_property(TARGET kvsWebrtcClient APPEND PROPERTY INTERFACE_LINK_LIBRARIES 160 | ${esp_common_lib} ${pthread_lib} 161 | mbedtls 162 | ${mbedtls_lib} 163 | ${nvs_flash_lib}) 164 | 165 | if(ENABLE_STREAMING) 166 | set_property(TARGET kvsWebrtcClient APPEND PROPERTY INTERFACE_LINK_LIBRARIES srtp2) 167 | endif() 168 | if(ENABLE_DATA_CHANNEL) 169 | set_property(TARGET kvsWebrtcClient APPEND PROPERTY INTERFACE_LINK_LIBRARIES usrsctp-static) 170 | endif() 171 | target_link_libraries(${COMPONENT_LIB} PUBLIC kvsWebrtcClient) 172 | -------------------------------------------------------------------------------- /main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Example Configuration" 2 | 3 | config ESP_WIFI_SSID 4 | string "WiFi SSID" 5 | default "myssid" 6 | help 7 | SSID (network name) for the example to connect to. 8 | 9 | config ESP_WIFI_PASSWORD 10 | string "WiFi Password" 11 | default "mypassword" 12 | help 13 | WiFi password (WPA or WPA2) for the example to use. 14 | 15 | config ESP_MAXIMUM_RETRY 16 | int "Maximum retry" 17 | default 5 18 | help 19 | Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. 20 | 21 | config AWS_ACCESS_KEY_ID 22 | string "AWS Access Key ID" 23 | default "aws-access-key-id" 24 | help 25 | Set AWS_ACCESS_KEY_ID for kvs webrtc. 26 | 27 | config AWS_SECRET_ACCESS_KEY 28 | string "AWS Secret Access Key" 29 | default "aws-secret-access-key" 30 | help 31 | Set AWS_SECRET_ACCESS_KEY for kvs webrtc. 32 | 33 | config AWS_IOT_CORE_CREDENTIAL_ENDPOINT 34 | string "AWS Iot Core Credential Endpoint" 35 | default "aws-iot-core-credential-endpoint" 36 | help 37 | Set AWS_IOT_CORE_CREDENTIAL_ENDPOINT for kvs webrtc. 38 | 39 | config AWS_IOT_CORE_CERT 40 | string "AWS Iot Core Cert" 41 | default "aws-iot-core-cert" 42 | help 43 | Set AWS_IOT_CORE_CERT for kvs webrtc. 44 | 45 | config AWS_IOT_CORE_PRIVATE_KEY 46 | string "AWS Iot Core Private Key" 47 | default "aws-iot-core-private-key" 48 | help 49 | Set AWS_IOT_CORE_PRIVATE_KEY for kvs webrtc. 50 | 51 | config AWS_IOT_CORE_ROLE_ALIAS 52 | string "AWS Iot Core Role Alias" 53 | default "aws-iot-core-role-alias" 54 | help 55 | Set AWS_IOT_CORE_ROLE_ALIAS for kvs webrtc. 56 | 57 | config AWS_IOT_CORE_THING_NAME 58 | string "AWS Iot Core Thing Name" 59 | default "aws-iot-core-thing-name" 60 | help 61 | Set AWS_IOT_CORE_THING_NAME for kvs webrtc. 62 | 63 | config AWS_KVS_LOG_LEVEL 64 | string "AWS KVS Log Level" 65 | default "2" 66 | help 67 | Set AWS_KVS_LOG_LEVEL for kvs webrtc. 68 | 69 | config AWS_DEFAULT_REGION 70 | string "AWS Default Region" 71 | default "us-west-2" 72 | help 73 | Set AWS_DEFAULT_REGION for kvs webrtc. 74 | 75 | config AWS_KVS_CHANNEL 76 | string "AWS kvs channel" 77 | default "ScaryTestChannel" 78 | help 79 | Set AWS_KVS_CHANNEL for kvs webrtc. 80 | endmenu 81 | -------------------------------------------------------------------------------- /main/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx 3 | EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT 4 | HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs 5 | ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 6 | MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD 7 | VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy 8 | ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy 9 | dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI 10 | hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p 11 | OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 12 | 8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K 13 | Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe 14 | hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk 15 | 6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw 16 | DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q 17 | AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI 18 | bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB 19 | ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z 20 | qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd 21 | iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn 22 | 0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN 23 | sSi6 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Main component makefile. 3 | # 4 | # This Makefile can be left empty. By default, it will take the sources in the 5 | # src/ directory, compile them and link them into lib(subdirectory_name).a 6 | # in the build directory. This behaviour is entirely configurable, 7 | # please read the ESP-IDF documents if you need to do this. 8 | # 9 | -------------------------------------------------------------------------------- /main/include/AppCommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_COMMON_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_COMMON_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "hash_table.h" 24 | #include "AppConfig.h" 25 | #include "AppError.h" 26 | #include "AppCredential.h" 27 | #include "AppMediaSrc.h" 28 | #include "AppSignaling.h" 29 | #include "AppMessageQueue.h" 30 | #include "timer_queue.h" 31 | #include "hash_table.h" 32 | 33 | typedef struct __StreamingSession StreamingSession; 34 | typedef struct __StreamingSession* PStreamingSession; 35 | 36 | typedef struct { 37 | UINT64 prevNumberOfPacketsSent; 38 | UINT64 prevNumberOfPacketsReceived; 39 | UINT64 prevNumberOfBytesSent; 40 | UINT64 prevNumberOfBytesReceived; 41 | UINT64 prevPacketsDiscardedOnSend; 42 | UINT64 prevTs; 43 | } RtcMetricsHistory, *PRtcMetricsHistory; 44 | 45 | typedef struct { 46 | volatile ATOMIC_BOOL terminateApp; //!< terminate this app. 47 | volatile ATOMIC_BOOL sigInt; //!< the flag to indicate the system-level signal. 48 | volatile ATOMIC_BOOL mediaThreadStarted; //!< the flag to indicate the status of the media thread. 49 | volatile ATOMIC_BOOL restartSignalingClient; //!< the flag to indicate we need to re-sync the singal server. 50 | volatile ATOMIC_BOOL peerConnectionConnected; 51 | volatile ATOMIC_BOOL abortMediaControl; 52 | 53 | AppCredential appCredential; //!< the context of app credential. 54 | AppSignaling appSignaling; //!< the context of app signaling. 55 | PAppMediaSrc pAppMediaSrc; 56 | PVOID pMediaContext; //!< the context of media. 57 | 58 | TID mediaControlTid; 59 | startRoutine mediaSource; 60 | TIMER_QUEUE_HANDLE timerQueueHandle; 61 | UINT32 iceCandidatePairStatsTimerId; //!< the timer id. 62 | UINT32 pregenerateCertTimerId; 63 | 64 | PHashTable pRemoteRtcPeerConnections; 65 | PConnectionMsgQ pRemotePeerPendingSignalingMessages; //!< stores signaling messages before receiving offer or answer. 66 | 67 | MUTEX appConfigurationObjLock; 68 | CVAR cvar; 69 | BOOL trickleIce; //!< This is ignored for master. Master can extract the info from offer. Viewer has to know if peer can trickle or 70 | //!< not ahead of time. 71 | BOOL enableFileLogging; 72 | 73 | PStreamingSession streamingSessionList[APP_MAX_CONCURRENT_STREAMING_SESSION]; 74 | UINT32 streamingSessionCount; 75 | MUTEX streamingSessionListReadLock; //!< the lock of streaming session. 76 | UINT32 iceUriCount; //!< the number of ice server including stun and turn. 77 | 78 | } AppConfiguration, *PAppConfiguration; 79 | 80 | struct __StreamingSession { 81 | volatile ATOMIC_BOOL terminateFlag; //!< the flag indicates the termination of this streaming session. 82 | volatile ATOMIC_BOOL candidateGatheringDone; 83 | volatile ATOMIC_BOOL peerIdReceived; 84 | volatile SIZE_T frameIndex; 85 | PRtcPeerConnection pPeerConnection; 86 | PRtcRtpTransceiver pVideoRtcRtpTransceiver; 87 | PRtcRtpTransceiver pAudioRtcRtpTransceiver; 88 | RtcSessionDescriptionInit answerSessionDescriptionInit; 89 | PAppConfiguration pAppConfiguration; //!< the context of the app 90 | 91 | CHAR peerId[MAX_SIGNALING_CLIENT_ID_LEN + 92 | 1]; //!< https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-websocket-apis3.html 93 | 94 | UINT64 offerReceiveTime; 95 | UINT64 startUpLatency; 96 | BOOL firstFrame; 97 | BOOL firstKeyFrame; //!< the first key frame of this session is sent or not. 98 | RtcMetricsHistory rtcMetricsHistory; //!< the metrics of the previous packet. 99 | BOOL remoteCanTrickleIce; 100 | PRtcDataChannel pRtcDataChannel; 101 | }; 102 | /** 103 | * @brief The initialization of this app. 104 | * 105 | * @param[in] trickleIce Enable the trickle ICE. 106 | * @param[in] useTurn Use the turn servers. 107 | * @param[in, out] ppAppConfiguration the context of this app. 108 | * 109 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 110 | */ 111 | STATUS initApp(BOOL trickleIce, BOOL useTurn, PAppMediaSrc pAppMediaSrc, PAppConfiguration* ppAppConfiguration); 112 | /** 113 | * @brief start runnning the app. 114 | * 115 | * @param[in, out] ppAppConfiguration the context of the app. 116 | * 117 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 118 | */ 119 | STATUS runApp(PAppConfiguration pAppConfiguration); 120 | /** 121 | * @brief free the context of the app. 122 | * 123 | * @param[in, out] ppAppConfiguration the context of the app. 124 | * 125 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 126 | */ 127 | STATUS freeApp(PAppConfiguration* ppAppConfiguration); 128 | /** 129 | * @brief polling the status of every streaming session, and checking the status of the app. 130 | * 131 | * @param[in] pAppConfiguration the context of the app. 132 | * 133 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 134 | */ 135 | STATUS pollApp(PAppConfiguration pAppConfiguration); 136 | 137 | STATUS quitApp(VOID); 138 | 139 | STATUS getApp(PAppConfiguration* ppAppConfiguration); 140 | 141 | #ifdef __cplusplus 142 | } 143 | #endif 144 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_COMMON_INCLUDE__ */ 145 | -------------------------------------------------------------------------------- /main/include/AppConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_CONFIG_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_CONFIG_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | #define APP_MAX_CONCURRENT_STREAMING_SESSION 10 25 | #define APP_MASTER_CLIENT_ID "ProducerMaster" 26 | #define APP_VIEWER_CLIENT_ID "ConsumerViewer" 27 | #define APP_CLEANUP_WAIT_PERIOD (5 * HUNDREDS_OF_NANOS_IN_A_SECOND) 28 | #define APP_STATS_DURATION (60 * HUNDREDS_OF_NANOS_IN_A_SECOND) 29 | #define APP_PENDING_MESSAGE_CLEANUP_DURATION (20 * HUNDREDS_OF_NANOS_IN_A_SECOND) 30 | #define APP_PRE_GENERATE_CERT TRUE 31 | #define APP_PRE_GENERATE_CERT_PERIOD (5000 * HUNDREDS_OF_NANOS_IN_A_MILLISECOND) 32 | #define APP_CA_CERT_PEM_FILE_EXTENSION ".pem" 33 | 34 | #define APP_METRICS_FILE_LOGGING_BUFFER_SIZE (100 * 1024) 35 | #define APP_METRICS_LOG_FILES_MAX_NUMBER 5 36 | 37 | #define APP_HASH_TABLE_BUCKET_COUNT 50 38 | #define APP_HASH_TABLE_BUCKET_LENGTH 2 39 | 40 | #define APP_WEBRTC_CHANNEL ((PCHAR) "AWS_WEBRTC_CHANNEL") 41 | #define APP_IOT_CORE_CREDENTIAL_ENDPOINT ((PCHAR) "AWS_IOT_CORE_CREDENTIAL_ENDPOINT") 42 | #define APP_IOT_CORE_CERT ((PCHAR) "AWS_IOT_CORE_CERT") 43 | #define APP_IOT_CORE_PRIVATE_KEY ((PCHAR) "AWS_IOT_CORE_PRIVATE_KEY") 44 | #define APP_IOT_CORE_ROLE_ALIAS ((PCHAR) "AWS_IOT_CORE_ROLE_ALIAS") 45 | #define APP_IOT_CORE_THING_NAME ((PCHAR) "AWS_IOT_CORE_THING_NAME") 46 | #define APP_ECS_AUTH_TOKEN ((PCHAR) "AWS_CONTAINER_AUTHORIZATION_TOKEN") 47 | #define APP_ECS_CREDENTIALS_FULL_URI ((PCHAR) "AWS_CONTAINER_CREDENTIALS_FULL_URI") 48 | #define APP_MEDIA_RTSP_URL ((PCHAR) "AWS_RTSP_URL") 49 | #define APP_MEDIA_RTSP_USERNAME ((PCHAR) "AWS_RTSP_USERNAME") 50 | #define APP_MEDIA_RTSP_PASSWORD ((PCHAR) "AWS_RTSP_PASSWORD") 51 | #define APP_MEDIA_RTSP_USERNAME_LEN MAX_CHANNEL_NAME_LEN 52 | #define APP_MEDIA_RTSP_PASSWORD_LEN MAX_CHANNEL_NAME_LEN 53 | #define APP_MEDIA_GST_ELEMENT_NAME_MAX_LEN 256 54 | 55 | #define APP_VIDEO_TRACK_STREAM_ID "myKvsVideoStream" 56 | #define APP_VIDEO_TRACK_ID "myVideoTrack" 57 | #define APP_AUDIO_TRACK_STREAM_ID "myKvsVideoStream" 58 | #define APP_AUDIO_TRACK_ID "myAudioTrack" 59 | 60 | #define APP_MEDIA_CONTROL_THREAD_NAME "media_control" 61 | #define APP_MEDIA_CONTROL_THREAD_SIZE 4096 62 | #define APP_MEDIA_VIDEO_SENDER_THREAD_NAME "video_sender" 63 | #define APP_MEDIA_VIDEO_SENDER_THREAD_SIZE 8192 64 | #define APP_MEDIA_AUDIO_SENDER_THREAD_NAME "audio_sender" 65 | #define APP_MEDIA_AUDIO_SENDER_THREAD_SIZE 4096 66 | #define APP_COMMON_TIMER_NAME "app_common_timer" 67 | #define APP_COMMON_TIMER_SIZE 10240 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_CONFIG_INCLUDE__ */ 73 | -------------------------------------------------------------------------------- /main/include/AppCredential.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_CREDENTIAL_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_CREDENTIAL_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | #include 22 | #include "AppConfig.h" 23 | #include "AppError.h" 24 | 25 | typedef enum { APP_CREDENTIAL_TYPE_NA = 0, APP_CREDENTIAL_TYPE_STATIC, APP_CREDENTIAL_TYPE_IOT_CERT, APP_CREDENTIAL_TYPE_ECS } AppCredentialType; 26 | 27 | typedef struct { 28 | AppCredentialType credentialType; //!< the type of app credential. 29 | PCHAR pCaCertPath; //!< the path of rootCA. 30 | PAwsCredentialProvider pCredentialProvider; //!< the handler of aws credential provider. 31 | MUTEX generateCertLock; //!< the lock for the access of generated cert. 32 | PStackQueue generatedCertificates; // Max MAX_RTCCONFIGURATION_CERTIFICATES certificates. 33 | } AppCredential, *PAppCredential; 34 | /** 35 | * @brief search the ssl cert according to the environmental variable. 36 | * 37 | * @param[in] pAppCredential the context of the app credential. 38 | * 39 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 40 | */ 41 | STATUS searchSslCert(PAppCredential pAppCredential); 42 | /** 43 | * @brief the routine of generating the cert, and push the generated cert into the queue. 44 | * 45 | * @param[in] pAppCredential the context of the app credential. 46 | * 47 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 48 | */ 49 | STATUS app_credential_generateCertRoutine(PAppCredential pAppCredential); 50 | /** 51 | * @brief pop the generated cert out of the queue. 52 | * 53 | * @param[in] pAppCredential the context of the app credential. 54 | * 55 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 56 | */ 57 | STATUS popGeneratedCert(PAppCredential pAppCredential, PRtcCertificate* ppRtcCertificate); 58 | /** 59 | * @brief create the app credential according to environmental variables. 60 | * 61 | * @param[in] pAppCredential the context of the app credential. 62 | * 63 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 64 | */ 65 | STATUS app_credential_create(PAppCredential pAppCredential); 66 | /** 67 | * @brief destroy the app credential. 68 | * 69 | * @param[in] pAppCredential the context of the app credential. 70 | * 71 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 72 | */ 73 | STATUS app_credential_destroy(PAppCredential pAppCredential); 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_CREDENTIAL_INCLUDE__ */ 79 | -------------------------------------------------------------------------------- /main/include/AppDataChannel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_DATA_CHANNEL_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_DATA_CHANNEL_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | 26 | #ifdef ENABLE_DATA_CHANNEL 27 | VOID onDataChannelMessageMaster(UINT64 customData, PRtcDataChannel pDataChannel, BOOL isBinary, PBYTE pMessage, UINT32 pMessageLen); 28 | VOID onDataChannel(UINT64 userData, PRtcDataChannel pRtcDataChannel); 29 | #endif 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_DATA_CHANNEL_INCLUDE__ */ 34 | -------------------------------------------------------------------------------- /main/include/AppError.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_ERROR_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_ERROR_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | /** 0x70000000 */ 22 | #define STATUS_APP_BASE 0x70000000 23 | #define STATUS_APP_FAILED STATUS_APP_BASE + 0x00000001 24 | /** 0x71000000 */ 25 | #define STATUS_APP_COMMON_BASE STATUS_APP_BASE + 0x01000000 26 | #define STATUS_APP_COMMON_NULL_ARG STATUS_APP_COMMON_BASE + 0x00000001 27 | #define STATUS_APP_COMMON_NOT_ENOUGH_MEMORY STATUS_APP_COMMON_BASE + 0x00000002 28 | #define STATUS_APP_COMMON_SHUTDOWN_MEDIA STATUS_APP_COMMON_BASE + 0x00000003 29 | #define STATUS_APP_COMMON_CHANNEL_NAME STATUS_APP_COMMON_BASE + 0x00000004 30 | #define STATUS_APP_COMMON_TIMER STATUS_APP_COMMON_BASE + 0x00000005 31 | #define STATUS_APP_COMMON_INVALID_PEER_ID STATUS_APP_COMMON_BASE + 0x00000006 32 | #define STATUS_APP_COMMON_TRIGGER_MEDIA_SENDER_ROUTINE STATUS_APP_COMMON_BASE + 0x00000007 33 | #define STATUS_APP_COMMON_INVALID_MUTEX STATUS_APP_COMMON_BASE + 0x00000008 34 | #define STATUS_APP_COMMON_ACQUIRE_MUTEX STATUS_APP_COMMON_BASE + 0x00000009 35 | #define STATUS_APP_COMMON_QUIT_APP STATUS_APP_COMMON_BASE + 0x0000000A 36 | 37 | /** 0x72000000 */ 38 | #define STATUS_APP_CREDENTIAL_BASE STATUS_APP_BASE + 0x02000000 39 | #define STATUS_APP_CREDENTIAL_MISS_CACERT_PATH STATUS_APP_CREDENTIAL_BASE + 0x00000001 40 | #define STATUS_APP_CREDENTIAL_INVALID_CACERT_PATH STATUS_APP_CREDENTIAL_BASE + 0x00000002 41 | #define STATUS_APP_CREDENTIAL_CACERT_NOT_FOUND STATUS_APP_CREDENTIAL_BASE + 0x00000003 42 | #define STATUS_APP_CREDENTIAL_MISSING_ENV STATUS_APP_CREDENTIAL_BASE + 0x00000004 43 | #define STATUS_APP_CREDENTIAL_ALLOCATE_STATIC STATUS_APP_CREDENTIAL_BASE + 0x00000005 44 | #define STATUS_APP_CREDENTIAL_ALLOCATE_IOT STATUS_APP_CREDENTIAL_BASE + 0x00000006 45 | #define STATUS_APP_CREDENTIAL_ALLOCATE_ECS STATUS_APP_CREDENTIAL_BASE + 0x00000007 46 | #define STATUS_APP_CREDENTIAL_ALLOCATE_NA STATUS_APP_CREDENTIAL_BASE + 0x00000008 47 | #define STATUS_APP_CREDENTIAL_DESTROY_STATIC STATUS_APP_CREDENTIAL_BASE + 0x00000009 48 | #define STATUS_APP_CREDENTIAL_DESTROY_IOT STATUS_APP_CREDENTIAL_BASE + 0x0000000A 49 | #define STATUS_APP_CREDENTIAL_DESTROY_ECS STATUS_APP_CREDENTIAL_BASE + 0x0000000B 50 | #define STATUS_APP_CREDENTIAL_DESTROY_NA STATUS_APP_CREDENTIAL_BASE + 0x0000000C 51 | #define STATUS_APP_CREDENTIAL_PREGENERATED_CERT_QUEUE STATUS_APP_CREDENTIAL_BASE + 0x0000000D 52 | #define STATUS_APP_CREDENTIAL_NULL_ARG STATUS_APP_CREDENTIAL_BASE + 0x0000000E 53 | #define STATUS_APP_CREDENTIAL_INVALID_MUTEX STATUS_APP_CREDENTIAL_BASE + 0x0000000F 54 | #define STATUS_APP_CREDENTIAL_CERT_CREATE STATUS_APP_CREDENTIAL_BASE + 0x00000010 55 | #define STATUS_APP_CREDENTIAL_CERT_STACK STATUS_APP_CREDENTIAL_BASE + 0x00000011 56 | /** 0x73000000 */ 57 | #define STATUS_MEDIA_BASE STATUS_APP_BASE + 0x03000000 58 | #define STATUS_MEDIA_NULL_ARG STATUS_MEDIA_BASE + 0x00000001 59 | #define STATUS_MEDIA_NOT_ENOUGH_MEMORY STATUS_MEDIA_BASE + 0x00000002 60 | #define STATUS_MEDIA_INVALID_MUTEX STATUS_MEDIA_BASE + 0x00000003 61 | #define STATUS_MEDIA_FAILED STATUS_MEDIA_BASE + 0x00000004 62 | #define STATUS_MEDIA_INIT STATUS_MEDIA_BASE + 0x00000005 63 | #define STATUS_MEDIA_NOT_READY STATUS_MEDIA_BASE + 0x00000006 64 | #define STATUS_MEDIA_LINK_ELEMENT STATUS_MEDIA_BASE + 0x00000007 65 | #define STATUS_MEDIA_EMPTY_ELEMENT STATUS_MEDIA_BASE + 0x00000008 66 | #define STATUS_MEDIA_DUMMY_SINK STATUS_MEDIA_BASE + 0x00000009 67 | #define STATUS_MEDIA_DUMMY_ELEMENT STATUS_MEDIA_BASE + 0x0000000A 68 | #define STATUS_MEDIA_VIDEO_SINK STATUS_MEDIA_BASE + 0x0000000B 69 | #define STATUS_MEDIA_VIDEO_ELEMENT STATUS_MEDIA_BASE + 0x0000000C 70 | #define STATUS_MEDIA_VIDEO_CAPS STATUS_MEDIA_BASE + 0x0000000D 71 | #define STATUS_MEDIA_VIDEO_QUEUE STATUS_MEDIA_BASE + 0x0000000E 72 | #define STATUS_MEDIA_VIDEO_LINK STATUS_MEDIA_BASE + 0x0000000F 73 | #define STATUS_MEDIA_AUDIO_SINK STATUS_MEDIA_BASE + 0x00000010 74 | #define STATUS_MEDIA_AUDIO_ELEMENT STATUS_MEDIA_BASE + 0x00000011 75 | #define STATUS_MEDIA_AUDIO_CAPS STATUS_MEDIA_BASE + 0x00000012 76 | #define STATUS_MEDIA_AUDIO_QUEUE STATUS_MEDIA_BASE + 0x00000013 77 | #define STATUS_MEDIA_AUDIO_LINK STATUS_MEDIA_BASE + 0x00000014 78 | #define STATUS_MEDIA_UNSUPPORTED_VIDEO STATUS_MEDIA_BASE + 0x00000015 79 | #define STATUS_MEDIA_UNSUPPORTED_AUDIO STATUS_MEDIA_BASE + 0x00000016 80 | #define STATUS_MEDIA_RTSP_URL STATUS_MEDIA_BASE + 0x00000017 81 | #define STATUS_MEDIA_RTSP_CREDENTIAL STATUS_MEDIA_BASE + 0x00000018 82 | #define STATUS_MEDIA_RTSP_PASSWORD STATUS_MEDIA_BASE + 0x00000019 83 | #define STATUS_MEDIA_MISSING_RESOURCE STATUS_MEDIA_BASE + 0x0000001A 84 | #define STATUS_MEDIA_MISSING_PLUGIN STATUS_MEDIA_BASE + 0x0000001B 85 | #define STATUS_MEDIA_MISSING_BUS STATUS_MEDIA_BASE + 0x0000001C 86 | #define STATUS_MEDIA_MISSING_PIPELINE STATUS_MEDIA_BASE + 0x0000001D 87 | #define STATUS_MEDIA_PLAY STATUS_MEDIA_BASE + 0x0000001E 88 | #define STATUS_MEDIA_NOT_EXISTED STATUS_MEDIA_BASE + 0x0000001F 89 | #define STATUS_MEDIA_PAYLOAD_CONFLICT STATUS_MEDIA_BASE + 0x00000020 90 | #define STATUS_MEDIA_PAD_REMOVED STATUS_MEDIA_BASE + 0x00000021 91 | #define STATUS_MEDIA_BUS_ERROR STATUS_MEDIA_BASE + 0x00000022 92 | #define STATUS_MEDIA_BUS_EOS STATUS_MEDIA_BASE + 0x00000023 93 | #define STATUS_MEDIA_NOT_RUNNING STATUS_MEDIA_BASE + 0x00000024 94 | /** 0x74000000 */ 95 | #define STATUS_APP_SIGNALING_BASE STATUS_APP_BASE + 0x04000000 96 | #define STATUS_APP_SIGNALING_NULL_ARG STATUS_APP_SIGNALING_BASE + 0x00000001 97 | #define STATUS_APP_SIGNALING_NOT_ENOUGH_MEMORY STATUS_APP_SIGNALING_BASE + 0x00000002 98 | #define STATUS_APP_SIGNALING_INVALID_OPERATION STATUS_APP_SIGNALING_BASE + 0x00000003 99 | #define STATUS_APP_SIGNALING_INVALID_HANDLE STATUS_APP_SIGNALING_BASE + 0x00000004 100 | #define STATUS_APP_SIGNALING_INVALID_MUTEX STATUS_APP_SIGNALING_BASE + 0x00000005 101 | #define STATUS_APP_SIGNALING_INVALID_INFO_COUNT STATUS_APP_SIGNALING_BASE + 0x00000006 102 | #define STATUS_APP_SIGNALING_INVALID_INFO STATUS_APP_SIGNALING_BASE + 0x00000007 103 | #define STATUS_APP_SIGNALING_CREATE STATUS_APP_SIGNALING_BASE + 0x00000008 104 | #define STATUS_APP_SIGNALING_CONNECT STATUS_APP_SIGNALING_BASE + 0x00000009 105 | #define STATUS_APP_SIGNALING_FREE STATUS_APP_SIGNALING_BASE + 0x0000000A 106 | #define STATUS_APP_SIGNALING_NOT_READY STATUS_APP_SIGNALING_BASE + 0x0000000B 107 | #define STATUS_APP_SIGNALING_RESTART STATUS_APP_SIGNALING_BASE + 0x0000000C 108 | #define STATUS_APP_SIGNALING_SEND STATUS_APP_SIGNALING_BASE + 0x0000000D 109 | #define STATUS_APP_SIGNALING_ICE_SERVER_COUNT STATUS_APP_SIGNALING_BASE + 0x0000000E 110 | #define STATUS_APP_SIGNALING_FETCH STATUS_APP_SIGNALING_BASE + 0x0000000F 111 | #define STATUS_APP_SIGNALING_SHUTDOWN STATUS_APP_SIGNALING_BASE + 0x00000010 112 | /** 0x75000000 */ 113 | #define STATUS_APP_WEBRTC_BASE STATUS_APP_BASE + 0x05000000 114 | #define STATUS_APP_WEBRTC_INIT STATUS_APP_WEBRTC_BASE + 0x00000001 115 | #define STATUS_APP_WEBRTC_DEINIT STATUS_APP_WEBRTC_BASE + 0x00000002 116 | /** 0x76000000 */ 117 | #define STATUS_APP_METRICS_BASE STATUS_APP_BASE + 0x06000000 118 | #define STATUS_APP_METRICS_NULL_ARG STATUS_APP_METRICS_BASE + 0x00000001 119 | #define STATUS_APP_METRICS_SETUP_LOGGER STATUS_APP_METRICS_BASE + 0x00000002 120 | #define STATUS_APP_METRICS_FREE_LOGGER STATUS_APP_METRICS_BASE + 0x00000003 121 | #define STATUS_APP_METRICS_ICE_SERVER STATUS_APP_METRICS_BASE + 0x00000004 122 | #define STATUS_APP_METRICS_LOCAL_ICE_CANDIDATE STATUS_APP_METRICS_BASE + 0x00000005 123 | #define STATUS_APP_METRICS_REMOTE_ICE_CANDIDATE STATUS_APP_METRICS_BASE + 0x00000006 124 | /** 0x77000000 */ 125 | #define STATUS_APP_MSGQ_BASE STATUS_APP_BASE + 0x07000000 126 | #define STATUS_APP_MSGQ_NULL_ARG STATUS_APP_MSGQ_BASE + 0x00000001 127 | #define STATUS_APP_MSGQ_NOT_ENOUGH_MEMORY STATUS_APP_MSGQ_BASE + 0x00000002 128 | #define STATUS_APP_MSGQ_CREATE_CONN_MSQ STATUS_APP_MSGQ_BASE + 0x00000003 129 | #define STATUS_APP_MSGQ_PUSH_CONN_MSQ STATUS_APP_MSGQ_BASE + 0x00000004 130 | #define STATUS_APP_MSGQ_CREATE_PENDING_MSQ STATUS_APP_MSGQ_BASE + 0x00000005 131 | #define STATUS_APP_MSGQ_HANDLE_PENDING_MSG STATUS_APP_MSGQ_BASE + 0x00000006 132 | #define STATUS_APP_MSGQ_PUSH_PENDING_MSGQ STATUS_APP_MSGQ_BASE + 0x00000007 133 | #define STATUS_APP_MSGQ_EMPTY_PENDING_MSGQ STATUS_APP_MSGQ_BASE + 0x00000008 134 | #define STATUS_APP_MSGQ_POP_PENDING_MSGQ STATUS_APP_MSGQ_BASE + 0x00000009 135 | #define STATUS_APP_MSGQ_NULL_PENDING_MSGQ STATUS_APP_MSGQ_BASE + 0x0000000A 136 | #define STATUS_APP_MSGQ_NULL_PENDING_MSG STATUS_APP_MSGQ_BASE + 0x0000000B 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_ERROR_INCLUDE__ */ 142 | -------------------------------------------------------------------------------- /main/include/AppMain.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_MAIN_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_MAIN_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | #include "AppMediaSrc.h" 26 | 27 | INT32 WebRTCAppMain(PAppMediaSrc pAppMediaSrc); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_WEBRTC_INCLUDE__ */ 33 | -------------------------------------------------------------------------------- /main/include/AppMediaSink.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __AWS_KVS_WEBRTC_APP_MEDIA_SINK_INCLUDE__ 16 | #define __AWS_KVS_WEBRTC_APP_MEDIA_SINK_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | 26 | PVOID app_media_sink_onFrame(PVOID pArgs); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | #endif /* __AWS_KVS_WEBRTC_APP_MEDIA_SINK_INCLUDE__ */ 32 | -------------------------------------------------------------------------------- /main/include/AppMediaSrc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __AWS_KVS_WEBRTC_APP_MEDIA_SRC_INCLUDE__ 16 | #define __AWS_KVS_WEBRTC_APP_MEDIA_SRC_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | 26 | typedef STATUS (*MediaSinkHook)(PVOID udata, PFrame pFrame); 27 | typedef STATUS (*MediaEosHook)(PVOID udata); 28 | typedef PVOID PMediaContext; 29 | 30 | typedef struct __AppMediaSrc { 31 | STATUS (*app_media_source_init)(PMediaContext* ppMediaContext); 32 | STATUS (*app_media_source_isReady)(PMediaContext pMediaContext); 33 | STATUS (*app_media_source_queryVideoCap)(PMediaContext pMediaContext, RTC_CODEC* pCodec); 34 | STATUS (*app_media_source_queryAudioCap)(PMediaContext pMediaContext, RTC_CODEC* pCodec); 35 | STATUS (*app_media_source_linkSinkHook)(PMediaContext pMediaContext, MediaSinkHook mediaSinkHook, PVOID udata); 36 | STATUS (*app_media_source_linkEosHook)(PMediaContext pMediaContext, MediaEosHook mediaEosHook, PVOID udata); 37 | PVOID (*app_media_source_run)(PVOID pArgs); 38 | STATUS (*app_media_source_shutdown)(PMediaContext pMediaContext); 39 | STATUS (*app_media_source_isShutdown)(PMediaContext pMediaContext, PBOOL pShutdown); 40 | STATUS (*app_media_source_detroy)(PMediaContext* ppMediaContext); 41 | } AppMediaSrc, *PAppMediaSrc; 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | #endif /* __AWS_KVS_WEBRTC_APP_MEDIA_SRC_INCLUDE__ */ 47 | -------------------------------------------------------------------------------- /main/include/AppMediaSrc_ESP32_FileSrc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __AWS_KVS_WEBRTC_APP_MEDIA_ESP32_FILE_SRC_INCLUDE__ 16 | #define __AWS_KVS_WEBRTC_APP_MEDIA_ESP32_FILE_SRC_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | #include "AppMediaSrc.h" 26 | #include "AppMediaSink.h" 27 | 28 | extern AppMediaSrc gAppMediaSrc; 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif /* __AWS_KVS_WEBRTC_APP_MEDIA_ESP32_FILE_SRC_INCLUDE__ */ 34 | -------------------------------------------------------------------------------- /main/include/AppMessageQueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_MESSAGE_QUEUE_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_MESSAGE_QUEUE_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | /****************************************************************************** 22 | * HEADERS 23 | ******************************************************************************/ 24 | #include 25 | #include "AppConfig.h" 26 | #include "AppError.h" 27 | #include "stack_queue.h" 28 | 29 | /****************************************************************************** 30 | * DEFINITIONS 31 | ******************************************************************************/ 32 | typedef STATUS (*MsgHandleHook)(PVOID udata, PSignalingMessage pSignalingMessage); 33 | 34 | typedef struct { 35 | UINT64 hashValue; 36 | UINT64 createTime; 37 | PStackQueue messageQueue; 38 | MsgHandleHook msgHandleHook; 39 | PVOID uData; 40 | } PendingMessageQueue, *PPendingMessageQueue; 41 | 42 | typedef struct { 43 | PStackQueue pMsqQueue; 44 | } ConnectionMsgQ, *PConnectionMsgQ; 45 | 46 | /****************************************************************************** 47 | * FUNCTIONS 48 | ******************************************************************************/ 49 | /** 50 | * @brief create the pending message queue for the new connection. 51 | * 52 | * @param[in] pConnectionMsgQ the context of the connection message queue. 53 | * @param[in] hashValue the hashvalue of this pending message queue. 54 | * @param[in, out] ppPendingMessageQueue the context of this pending message queue. 55 | * 56 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 57 | */ 58 | STATUS app_msg_q_createPendingMsgQ(PConnectionMsgQ pConnectionMsgQ, UINT64 hashValue, PPendingMessageQueue* ppPendingMessageQueue); 59 | /** 60 | * @brief push message into the pending message queue. 61 | * 62 | * @param[in] pPendingMsgQ the context of the pending message queue. 63 | * @param[in] pMsg the buffer of the signaling message. 64 | * 65 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 66 | */ 67 | STATUS app_msg_q_pushMsqIntoPendingMsgQ(PPendingMessageQueue pPendingMsgQ, PReceivedSignalingMessage pMsg); 68 | /** 69 | * @brief This api handles all the pending message but you need to pop pending message queue from connection message queue. 70 | * It means you need to use this api with app_msg_q_getPendingMsgQByHashVal(). 71 | * 72 | * @param[in] pPendingMsgQ the context of the pending message queue. 73 | * @param[in] msgHandleHook the callback of handling the pending messages. 74 | * @param[in] uData the context of user data. 75 | * 76 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 77 | */ 78 | STATUS app_msg_q_handlePendingMsgQ(PPendingMessageQueue pPendingMsgQ, MsgHandleHook msgHandleHook, PVOID uData); 79 | /** 80 | * @brief free the pending message queue. 81 | * 82 | * @param[in] pPendingMessageQueue the context of the pending message queue. 83 | * 84 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 85 | */ 86 | STATUS app_msg_q_freePendingMsgQ(PPendingMessageQueue pPendingMessageQueue); 87 | /** 88 | * @brief create connection queue. 89 | * 90 | * @param[in] pConnectionMsgQ the context of the connnection message queue. 91 | * 92 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 93 | */ 94 | STATUS app_msg_q_createConnectionMsqQ(PConnectionMsgQ* ppConnectionMsgQ); 95 | /** 96 | * @brief get the target pending message queue according to the clientHash 97 | * 98 | * @param[in] pConnectionMsgQ the context of the connnection message queue. 99 | * @param[in] clientHash the hash value of the pending message queue. 100 | * @param[in] remove remove the target pending message queue. 101 | * @param[in, out] ppPendingMsgQ the context of the pending message queue. 102 | * 103 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 104 | */ 105 | STATUS app_msg_q_getPendingMsgQByHashVal(PConnectionMsgQ pConnectionMsgQ, UINT64 clientHash, BOOL remove, PPendingMessageQueue* ppPendingMsgQ); 106 | /** 107 | * @brief remove all the expired pending message queues. 108 | * 109 | * @param[in] pConnectionMsgQ the context of connection message queue. 110 | * @param[in] interval the expired interval 111 | * 112 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 113 | */ 114 | STATUS app_msg_q_removeExpiredPendingMsgQ(PConnectionMsgQ pConnectionMsgQ, UINT64 interval); 115 | /** 116 | * @brief freee the connection queues. 117 | * 118 | * @param[in] pConnectionMsgQ the context of connection message queue. 119 | * 120 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 121 | */ 122 | STATUS app_msg_q_freeConnectionMsgQ(PConnectionMsgQ* ppConnectionMsgQ); 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_MESSAGE_QUEUE_INCLUDE__ */ 128 | -------------------------------------------------------------------------------- /main/include/AppMetrics.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_METRICS_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_METRICS_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | 26 | UINT32 getLogLevel(VOID); 27 | STATUS app_metrics_setupFileLogging(PBOOL pEnable); 28 | STATUS app_metrics_closeFileLogging(VOID); 29 | STATUS app_metrics_logIceServerStats(PRtcPeerConnection pRtcPeerConnection, UINT32 index); 30 | STATUS logSelectedIceCandidatesInformation(PRtcPeerConnection pRtcPeerConnection); 31 | STATUS logSignalingClientStats(PSignalingClientMetrics pSignalingClientMetrics); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_METRICS_INCLUDE__ */ 37 | -------------------------------------------------------------------------------- /main/include/AppSignaling.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_SIGNALING_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_SIGNALING_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | #include 22 | #include "AppConfig.h" 23 | #include "AppError.h" 24 | #include "AppCredential.h" 25 | 26 | typedef struct __AppSignaling { 27 | PAppCredential pAppCredential; //!< the context of credential 28 | SIGNALING_CLIENT_HANDLE signalingClientHandle; 29 | SignalingClientCallbacks signalingClientCallbacks; 30 | ChannelInfo channelInfo; 31 | SignalingClientInfo clientInfo; 32 | MUTEX signalingSendMessageLock; //!< per signaling client 33 | BOOL useTurn; 34 | } AppSignaling, *PAppSignaling; 35 | /** 36 | * @brief initialize the context of app signaling 37 | * 38 | * @param[in] pAppSignaling the context of appSignaling 39 | * @param[in] onMessageReceived the callback of receiving the signaling messages 40 | * @param[in] onStateChanged the callback of the state 41 | * @param[in] pOnError the callback of error 42 | * @param[in] udata the user data for these callbacks 43 | * @param[in] useTurn use the turn server or not 44 | * 45 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 46 | */ 47 | STATUS app_signaling_init(PAppSignaling pAppSignaling, SignalingClientMessageReceivedFunc onMessageReceived, 48 | SignalingClientStateChangedFunc onStateChanged, SignalingClientErrorReportFunc pOnError, UINT64 udata, BOOL useTurn); 49 | /** 50 | * @brief initialize the context of app signaling 51 | * 52 | * @param[in] pAppSignaling the context of appSignaling 53 | * 54 | * @return the role type of signaling channel 55 | */ 56 | SIGNALING_CHANNEL_ROLE_TYPE app_signaling_getRole(PAppSignaling pAppSignaling); 57 | /** 58 | * @brief query the information of stun/turn servers 59 | * 60 | * @param[in] pAppSignaling the context of appSignaling 61 | * @param[in] pIceServer the structure of ice servers 62 | * @param[in] pServerNum the number of servers 63 | * 64 | * @return STATUS code of the execution. STATUS_SUCCESS on success. 65 | */ 66 | STATUS app_signaling_queryServer(PAppSignaling pAppSignaling, PRtcIceServer pIceServer, PUINT32 pServerNum); 67 | /** 68 | * @brief connect to the signaling server 69 | * 70 | * @param[in] pAppSignaling the context of appSignaling 71 | * 72 | * @return STATUS code of the execution. STATUS_SUCCESS on success 73 | */ 74 | STATUS app_signaling_connect(PAppSignaling pAppSignaling); 75 | STATUS app_signaling_fetch(PAppSignaling pAppSignaling); 76 | 77 | STATUS app_signaling_create(PAppSignaling pAppSignaling); 78 | 79 | STATUS app_signaling_shutdown(PAppSignaling pAppSignaling); 80 | /** 81 | * @brief connect to the signaling server 82 | * 83 | * @param[in] pAppSignaling the context of appSignaling 84 | * 85 | * @return STATUS code of the execution. STATUS_SUCCESS on success 86 | */ 87 | STATUS app_signaling_check(PAppSignaling pAppSignaling); 88 | STATUS app_signaling_sendMsg(PAppSignaling pAppSignaling, PSignalingMessage pMessage); 89 | STATUS app_signaling_restart(PAppSignaling pAppSignaling); 90 | STATUS app_signaling_free(PAppSignaling pAppSignaling); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_SIGNALING_INCLUDE__ */ 96 | -------------------------------------------------------------------------------- /main/include/AppWebRTC.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | #ifndef __KINESIS_VIDEO_WEBRTC_APP_WEBRTC_INCLUDE__ 16 | #define __KINESIS_VIDEO_WEBRTC_APP_WEBRTC_INCLUDE__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include "AppConfig.h" 24 | #include "AppError.h" 25 | #include "AppCommon.h" 26 | 27 | STATUS app_webrtc_init(PAppConfiguration pAppConfiguration); 28 | STATUS app_webrtc_deinit(PAppConfiguration pAppConfiguration); 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif /* __KINESIS_VIDEO_WEBRTC_APP_WEBRTC_INCLUDE__ */ 33 | -------------------------------------------------------------------------------- /main/kvswebrtc_example_main.c: -------------------------------------------------------------------------------- 1 | /* WiFi station Example 2 | 3 | This example code is in the Public Domain (or CC0 licensed, at your option.) 4 | 5 | Unless required by applicable law or agreed to in writing, this 6 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 7 | CONDITIONS OF ANY KIND, either express or implied. 8 | */ 9 | #include 10 | #include "freertos/FreeRTOS.h" 11 | #include "freertos/task.h" 12 | #include "freertos/event_groups.h" 13 | #include "esp_system.h" 14 | #include "esp_wifi.h" 15 | #include "esp_event.h" 16 | #include "esp_log.h" 17 | #include "nvs_flash.h" 18 | 19 | #include "lwip/err.h" 20 | #include "lwip/sys.h" 21 | 22 | #include "esp_vfs_fat.h" 23 | #include "driver/sdmmc_host.h" 24 | #include "driver/sdspi_host.h" 25 | #include "sdmmc_cmd.h" 26 | 27 | #include "esp_sntp.h" 28 | #include "esp_heap_caps.h" 29 | 30 | #include "AppMain.h" 31 | #include "AppMediaSrc_ESP32_FileSrc.h" 32 | 33 | /* The examples use WiFi configuration that you can set via project configuration menu 34 | 35 | If you'd rather not, just change the below entries to strings with 36 | the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" 37 | */ 38 | #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID 39 | #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD 40 | #define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY 41 | 42 | /* FreeRTOS event group to signal when we are connected*/ 43 | static EventGroupHandle_t s_wifi_event_group; 44 | 45 | /* The event group allows multiple bits for each event, but we only care about two events: 46 | * - we are connected to the AP with an IP 47 | * - we failed to connect after the maximum amount of retries */ 48 | #define WIFI_CONNECTED_BIT BIT0 49 | #define WIFI_FAIL_BIT BIT1 50 | 51 | static const char *TAG = "wifi station"; 52 | 53 | static int s_retry_num = 0; 54 | 55 | static char wifi_ip[72]; 56 | 57 | static void event_handler(void* arg, esp_event_base_t event_base, 58 | int32_t event_id, void* event_data) 59 | { 60 | if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { 61 | esp_wifi_connect(); 62 | } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { 63 | if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { 64 | esp_wifi_connect(); 65 | s_retry_num++; 66 | ESP_LOGI(TAG, "retry to connect to the AP"); 67 | } else { 68 | xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); 69 | } 70 | ESP_LOGI(TAG,"connect to the AP fail"); 71 | } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { 72 | ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; 73 | 74 | memset(wifi_ip, 0, sizeof(wifi_ip)/sizeof(wifi_ip[0])); 75 | ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); 76 | memcpy(wifi_ip, &event->ip_info.ip, 4); 77 | s_retry_num = 0; 78 | xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); 79 | } 80 | } 81 | 82 | char* esp_get_ip(void) 83 | { 84 | return wifi_ip; 85 | } 86 | 87 | 88 | void wifi_init_sta(void) 89 | { 90 | s_wifi_event_group = xEventGroupCreate(); 91 | 92 | ESP_ERROR_CHECK(esp_netif_init()); 93 | 94 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 95 | esp_netif_create_default_wifi_sta(); 96 | 97 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 98 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 99 | 100 | ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); 101 | ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); 102 | 103 | wifi_config_t wifi_config = { 104 | .sta = { 105 | .ssid = EXAMPLE_ESP_WIFI_SSID, 106 | .password = EXAMPLE_ESP_WIFI_PASS, 107 | /* Setting a password implies station will connect to all security modes including WEP/WPA. 108 | * However these modes are deprecated and not advisable to be used. Incase your Access point 109 | * doesn't support WPA2, these mode can be enabled by commenting below line */ 110 | .threshold.authmode = WIFI_AUTH_WPA2_PSK, 111 | 112 | .pmf_cfg = { 113 | .capable = true, 114 | .required = false 115 | }, 116 | }, 117 | }; 118 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); 119 | ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); 120 | ESP_ERROR_CHECK(esp_wifi_start() ); 121 | 122 | ESP_LOGI(TAG, "wifi_init_sta finished."); 123 | 124 | /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum 125 | * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ 126 | EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, 127 | WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, 128 | pdFALSE, 129 | pdFALSE, 130 | portMAX_DELAY); 131 | 132 | /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually 133 | * happened. */ 134 | if (bits & WIFI_CONNECTED_BIT) { 135 | ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", 136 | EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); 137 | } else if (bits & WIFI_FAIL_BIT) { 138 | ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", 139 | EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); 140 | } else { 141 | ESP_LOGE(TAG, "UNEXPECTED EVENT"); 142 | } 143 | 144 | ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler)); 145 | ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler)); 146 | vEventGroupDelete(s_wifi_event_group); 147 | } 148 | 149 | 150 | 151 | void time_sync_notification_cb(struct timeval *tv) 152 | { 153 | ESP_LOGI(TAG, "Notification of a time synchronization event"); 154 | } 155 | static void initialize_sntp(void) 156 | { 157 | ESP_LOGI(TAG, "Initializing SNTP"); 158 | sntp_setoperatingmode(SNTP_OPMODE_POLL); 159 | sntp_setservername(0, "pool.ntp.org"); 160 | sntp_set_time_sync_notification_cb(time_sync_notification_cb); 161 | #ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH 162 | sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH); 163 | #endif 164 | sntp_init(); 165 | } 166 | 167 | void app_main(void) 168 | { 169 | //Initialize NVS 170 | esp_err_t ret = nvs_flash_init(); 171 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 172 | ESP_ERROR_CHECK(nvs_flash_erase()); 173 | ret = nvs_flash_init(); 174 | } 175 | ESP_ERROR_CHECK(ret); 176 | 177 | ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); 178 | wifi_init_sta(); 179 | 180 | // initialize the fatfs and sd card. 181 | { 182 | ESP_LOGI(TAG, "Initializing SD card"); 183 | 184 | #ifndef USE_SPI_MODE 185 | ESP_LOGI(TAG, "Using SDMMC peripheral"); 186 | sdmmc_host_t host = SDMMC_HOST_DEFAULT(); 187 | 188 | // This initializes the slot without card detect (CD) and write protect (WP) signals. 189 | // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. 190 | sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); 191 | 192 | // To use 1-line SD mode, uncomment the following line: 193 | // slot_config.width = 1; 194 | 195 | // GPIOs 15, 2, 4, 12, 13 should have external 10k pull-ups. 196 | // Internal pull-ups are not sufficient. However, enabling internal pull-ups 197 | // does make a difference some boards, so we do that here. 198 | gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes 199 | gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes 200 | gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only 201 | gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only 202 | gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes 203 | 204 | #else 205 | ESP_LOGI(TAG, "Using SPI peripheral"); 206 | 207 | sdmmc_host_t host = SDSPI_HOST_DEFAULT(); 208 | sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); 209 | slot_config.gpio_miso = PIN_NUM_MISO; 210 | slot_config.gpio_mosi = PIN_NUM_MOSI; 211 | slot_config.gpio_sck = PIN_NUM_CLK; 212 | slot_config.gpio_cs = PIN_NUM_CS; 213 | // This initializes the slot without card detect (CD) and write protect (WP) signals. 214 | // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. 215 | #endif //USE_SPI_MODE 216 | 217 | // Options for mounting the filesystem. 218 | // If format_if_mount_failed is set to true, SD card will be partitioned and 219 | // formatted in case when mounting fails. 220 | esp_vfs_fat_sdmmc_mount_config_t mount_config = { 221 | .format_if_mount_failed = false, 222 | .max_files = 5, 223 | .allocation_unit_size = 16 * 1024 224 | }; 225 | 226 | // Use settings defined above to initialize SD card and mount FAT filesystem. 227 | // Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function. 228 | // Please check its source code and implement error recovery when developing 229 | // production applications. 230 | sdmmc_card_t* card; 231 | esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card); 232 | 233 | if (ret != ESP_OK) { 234 | if (ret == ESP_FAIL) { 235 | ESP_LOGE(TAG, "Failed to mount filesystem. " 236 | "If you want the card to be formatted, set format_if_mount_failed = true."); 237 | } else { 238 | ESP_LOGE(TAG, "Failed to initialize the card (%s). " 239 | "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); 240 | } 241 | return; 242 | } 243 | // Card has been initialized, print its properties 244 | sdmmc_card_print_info(stdout, card); 245 | } 246 | 247 | // using ntp to acquire the current time. 248 | { 249 | initialize_sntp(); 250 | 251 | // wait for time to be set 252 | time_t now = 0; 253 | struct tm timeinfo = { 0 }; 254 | int retry = 0; 255 | const int retry_count = 10; 256 | while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) { 257 | ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count); 258 | vTaskDelay(2000 / portTICK_PERIOD_MS); 259 | } 260 | time(&now); 261 | localtime_r(&now, &timeinfo); 262 | } 263 | { 264 | uint32_t freeSize = esp_get_free_heap_size(); 265 | printf("The available size of heap:%d\n", freeSize); 266 | } 267 | 268 | setenv("AWS_KVS_LOG_LEVEL", CONFIG_AWS_KVS_LOG_LEVEL, 1); 269 | setenv("AWS_DEFAULT_REGION", CONFIG_AWS_DEFAULT_REGION, 1); 270 | setenv("AWS_WEBRTC_CHANNEL", CONFIG_AWS_KVS_CHANNEL, 1); 271 | #define IOT_CREDENTIAL (0) 272 | #if (IOT_CREDENTIAL == 0) 273 | setenv("AWS_ACCESS_KEY_ID", CONFIG_AWS_ACCESS_KEY_ID, 1); 274 | setenv("AWS_SECRET_ACCESS_KEY", CONFIG_AWS_SECRET_ACCESS_KEY, 1); 275 | #else 276 | setenv("AWS_IOT_CORE_CREDENTIAL_ENDPOINT", CONFIG_AWS_IOT_CORE_CREDENTIAL_ENDPOINT, 1); 277 | setenv("AWS_IOT_CORE_CERT", CONFIG_AWS_IOT_CORE_CERT, 1); 278 | setenv("AWS_IOT_CORE_PRIVATE_KEY", CONFIG_AWS_IOT_CORE_PRIVATE_KEY, 1); 279 | setenv("AWS_IOT_CORE_ROLE_ALIAS", CONFIG_AWS_IOT_CORE_ROLE_ALIAS, 1); 280 | setenv("AWS_IOT_CORE_THING_NAME", CONFIG_AWS_IOT_CORE_THING_NAME, 1); 281 | #endif 282 | 283 | WebRTCAppMain(&gAppMediaSrc); 284 | 285 | // All done, unmount partition and disable SDMMC or SPI peripheral 286 | esp_vfs_fat_sdmmc_unmount(); 287 | ESP_LOGI(TAG, "Card unmounted"); 288 | } 289 | -------------------------------------------------------------------------------- /main/lib/libllhttp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(llhttp LANGUAGES C) 4 | 5 | 6 | # download release tarball of llhttp if it doesn't exist 7 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src") 8 | else() 9 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src") 10 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include") 11 | file(DOWNLOAD 12 | https://github.com/nodejs/llhttp/archive/release/v4.0.0.tar.gz 13 | ${CMAKE_CURRENT_BINARY_DIR}/llhttp.tar.gz 14 | ) 15 | execute_process(COMMAND tar -zxf ${CMAKE_CURRENT_BINARY_DIR}/llhttp.tar.gz -C ${CMAKE_CURRENT_BINARY_DIR}) 16 | 17 | set(llhttp_release_folder llhttp-release-v4.0.0) 18 | file(GLOB llhttp_c_files ${CMAKE_CURRENT_BINARY_DIR}/${llhttp_release_folder}/src/*.c) 19 | 20 | 21 | file(COPY ${llhttp_c_files} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/src) 22 | file(GLOB llhttp_h_files ${CMAKE_CURRENT_BINARY_DIR}/${llhttp_release_folder}/include/*.h) 23 | file(COPY ${llhttp_h_files} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include) 24 | file(COPY ${CMAKE_CURRENT_BINARY_DIR}/${llhttp_release_folder}/README.md DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) 25 | file(COPY ${CMAKE_CURRENT_BINARY_DIR}/${llhttp_release_folder}/LICENSE-MIT DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) 26 | endif() 27 | # #TBD, 28 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 29 | 30 | add_library(llhttp STATIC 31 | ${CMAKE_CURRENT_SOURCE_DIR}/src/api.c 32 | ${CMAKE_CURRENT_SOURCE_DIR}/src/http.c 33 | ${CMAKE_CURRENT_SOURCE_DIR}/src/llhttp.c 34 | ${CMAKE_CURRENT_SOURCE_DIR}/include/llhttp.h 35 | ) 36 | 37 | include_directories(llhttp 38 | ${CMAKE_CURRENT_SOURCE_DIR}/include 39 | ) 40 | 41 | target_link_directories(llhttp PUBLIC 42 | ${CMAKE_CURRENT_SOURCE_DIR}/include 43 | ) 44 | 45 | install(TARGETS llhttp DESTINATION lib) 46 | install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/llhttp.h DESTINATION include) -------------------------------------------------------------------------------- /main/scripts/clang-format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | parse_args() { 3 | while [[ $# -gt 0 ]] 4 | do 5 | key="$1" 6 | case $key in 7 | -f) 8 | echo "Clang formatting the files specified" 9 | clang-format -style=file -i -fallback-style=none $2 10 | shift # past argument 11 | shift # past value 12 | ;; 13 | -d) 14 | echo "Clang formatting all files in the directory" 15 | find $2 -iname *.h -o -iname *.c -o -iname *.h | xargs clang-format -style=file -i -fallback-style=none 16 | shift # past argument 17 | shift # past value 18 | ;; 19 | -g) 20 | echo "Clang formatting only git diff'ed output" 21 | clang-format -style=file -fallback-style=none -i `git ls-files -om "*.[ch]"` 22 | shift # past argument 23 | ;; 24 | -h|--help) 25 | echo "-f: Pass list of files to be clang formatted" 26 | echo "-a: Clang format all files in the project" 27 | echo "-d: Clang format all files in the directory passed after this option" 28 | echo "-g: Clang formatting only git diff'ed output" 29 | exit 0 30 | ;; 31 | *) # unknown option 32 | echo "Unknown option $key" 33 | exit 1 34 | ;; 35 | esac 36 | done 37 | } 38 | 39 | parse_args $@ 40 | -------------------------------------------------------------------------------- /patch/amazon-kinesis-video-streams-webrtc-sdk-c/0001-fix-mbedtls.patch: -------------------------------------------------------------------------------- 1 | From f7959b989d9cc2f1564fbb8d40f5525342c9cd7d Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Tue, 4 Jul 2023 15:52:59 +0800 4 | Subject: [PATCH] fix mbedtls. 5 | 6 | --- 7 | src/source/crypto/crypto.h | 4 ++-- 8 | src/source/crypto/dtls_mbedtls.c | 18 +++++++++--------- 9 | 2 files changed, 11 insertions(+), 11 deletions(-) 10 | 11 | diff --git a/src/source/crypto/crypto.h b/src/source/crypto/crypto.h 12 | index e73df839c..f8168e6ad 100644 13 | --- a/src/source/crypto/crypto.h 14 | +++ b/src/source/crypto/crypto.h 15 | @@ -87,8 +87,8 @@ typedef enum { 16 | } while (0) 17 | 18 | typedef enum { 19 | - KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_80 = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80, 20 | - KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_32 = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32, 21 | + KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_80 = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80, 22 | + KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_32 = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32, 23 | } KVS_SRTP_PROFILE; 24 | #else 25 | #error "A Crypto implementation is required." 26 | diff --git a/src/source/crypto/dtls_mbedtls.c b/src/source/crypto/dtls_mbedtls.c 27 | index 8670c615d..2b7e50629 100644 28 | --- a/src/source/crypto/dtls_mbedtls.c 29 | +++ b/src/source/crypto/dtls_mbedtls.c 30 | @@ -6,8 +6,9 @@ 31 | 32 | /** https://tools.ietf.org/html/rfc5764#section-4.1.2 */ 33 | mbedtls_ssl_srtp_profile DTLS_SRTP_SUPPORTED_PROFILES[] = { 34 | - MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80, 35 | - MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32, 36 | + MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80, 37 | + MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32, 38 | + MBEDTLS_TLS_SRTP_UNSET, 39 | }; 40 | 41 | STATUS dtls_session_create(PDtlsSessionCallbacks pDtlsSessionCallbacks, TIMER_QUEUE_HANDLE timerQueueHandle, INT32 certificateBits, 42 | @@ -281,8 +282,7 @@ STATUS dtls_session_start(PDtlsSession pDtlsSession, BOOL isServer) 43 | CHK(mbedtls_ssl_conf_own_cert(&pDtlsSession->sslCtxConfig, &pCertInfo->cert, &pCertInfo->privateKey) == 0, STATUS_DTLS_CREATE_SSL_FAILED); 44 | } 45 | mbedtls_ssl_conf_dtls_cookies(&pDtlsSession->sslCtxConfig, NULL, NULL, NULL); 46 | - CHK(mbedtls_ssl_conf_dtls_srtp_protection_profiles(&pDtlsSession->sslCtxConfig, DTLS_SRTP_SUPPORTED_PROFILES, 47 | - ARRAY_SIZE(DTLS_SRTP_SUPPORTED_PROFILES)) == 0, 48 | + CHK(mbedtls_ssl_conf_dtls_srtp_protection_profiles(&pDtlsSession->sslCtxConfig, DTLS_SRTP_SUPPORTED_PROFILES) == 0, 49 | STATUS_DTLS_CREATE_SSL_FAILED); 50 | mbedtls_ssl_conf_export_keys_ext_cb(&pDtlsSession->sslCtxConfig, (mbedtls_ssl_export_keys_ext_t*) dtls_session_deriveKeyCallback, pDtlsSession); 51 | 52 | @@ -477,7 +477,7 @@ STATUS dtls_session_populateKeyingMaterial(PDtlsSession pDtlsSession, PDtlsKeyin 53 | BOOL locked = FALSE; 54 | PTlsKeys pKeys; 55 | BYTE keyingMaterialBuffer[MAX_SRTP_MASTER_KEY_LEN * 2 + MAX_SRTP_SALT_KEY_LEN * 2]; 56 | - mbedtls_ssl_srtp_profile negotiatedSRTPProfile; 57 | + mbedtls_dtls_srtp_info negotiatedSRTPProfile; 58 | 59 | CHK(pDtlsSession != NULL && pDtlsKeyingMaterial != NULL, STATUS_DTLS_NULL_ARG); 60 | pKeys = &pDtlsSession->tlsKeys; 61 | @@ -502,12 +502,12 @@ STATUS dtls_session_populateKeyingMaterial(PDtlsSession pDtlsSession, PDtlsKeyin 62 | 63 | MEMCPY(pDtlsKeyingMaterial->serverWriteKey + MAX_SRTP_MASTER_KEY_LEN, &keyingMaterialBuffer[offset], MAX_SRTP_SALT_KEY_LEN); 64 | 65 | - negotiatedSRTPProfile = mbedtls_ssl_get_dtls_srtp_protection_profile(&pDtlsSession->sslCtx); 66 | - switch (negotiatedSRTPProfile) { 67 | - case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80: 68 | + mbedtls_ssl_get_dtls_srtp_negotiation_result(&pDtlsSession->sslCtx, &negotiatedSRTPProfile); 69 | + switch (negotiatedSRTPProfile.chosen_dtls_srtp_profile) { 70 | + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: 71 | pDtlsKeyingMaterial->srtpProfile = KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_80; 72 | break; 73 | - case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32: 74 | + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: 75 | pDtlsKeyingMaterial->srtpProfile = KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_32; 76 | break; 77 | default: 78 | -- 79 | 2.34.1 80 | 81 | -------------------------------------------------------------------------------- /patch/amazon-kinesis-video-streams-webrtc-sdk-js/0001-diable-offerToReceiveAudio.patch: -------------------------------------------------------------------------------- 1 | From d0fe711b29e2798fc5f2c33d7bfce5f8b58b0a0b Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Thu, 15 Oct 2020 10:30:23 +0800 4 | Subject: [PATCH] diable offerToReceiveAudio. 5 | 6 | --- 7 | examples/viewer.js | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/examples/viewer.js b/examples/viewer.js 11 | index 872f94d..d8e9a4e 100644 12 | --- a/examples/viewer.js 13 | +++ b/examples/viewer.js 14 | @@ -128,7 +128,7 @@ async function startViewer(localView, remoteView, formValues, onStatsReport, onR 15 | console.log('[VIEWER] Creating SDP offer'); 16 | await viewer.peerConnection.setLocalDescription( 17 | await viewer.peerConnection.createOffer({ 18 | - offerToReceiveAudio: true, 19 | + //offerToReceiveAudio: true, 20 | offerToReceiveVideo: true, 21 | }), 22 | ); 23 | -- 24 | 2.17.1 25 | 26 | -------------------------------------------------------------------------------- /patch/libsrtp/0001-disable-the-test-apps.patch: -------------------------------------------------------------------------------- 1 | From 8bd1077c99b7484bad28f8a8c3b6dc08380e5dd2 Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Tue, 6 Oct 2020 16:54:30 +0800 4 | Subject: [PATCH 1/8] disable the test apps. 5 | 6 | --- 7 | CMakeLists.txt | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/CMakeLists.txt b/CMakeLists.txt 11 | index 5ce9f56..ad3737b 100644 12 | --- a/CMakeLists.txt 13 | +++ b/CMakeLists.txt 14 | @@ -54,7 +54,7 @@ set(ENABLE_DEBUG_LOGGING OFF CACHE BOOL "Enable debug logging in all modules") 15 | set(ERR_REPORTING_STDOUT OFF CACHE BOOL "Enable logging to stdout") 16 | set(ERR_REPORTING_FILE "" CACHE FILEPATH "Use file for logging") 17 | set(ENABLE_OPENSSL OFF CACHE BOOL "Enable OpenSSL crypto engine") 18 | -set(TEST_APPS ON CACHE BOOL "Build test applications") 19 | +set(TEST_APPS OFF CACHE BOOL "Build test applications") 20 | option(BUILD_SHARED_LIBS "Build shared library" OFF) 21 | 22 | if(ENABLE_OPENSSL) 23 | -- 24 | 2.17.1 25 | 26 | -------------------------------------------------------------------------------- /patch/libsrtp/0002-fix-the-compile-error-for-esp32.patch: -------------------------------------------------------------------------------- 1 | From d2a79262eb86d79c4cb391f6a3234f48f1fb148d Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Wed, 14 Oct 2020 12:59:33 +0800 4 | Subject: [PATCH 2/8] fix the compile error for esp32. 5 | 6 | --- 7 | crypto/include/datatypes.h | 4 ++++ 8 | crypto/kernel/crypto_kernel.c | 2 +- 9 | srtp/srtp.c | 2 ++ 10 | 3 files changed, 7 insertions(+), 1 deletion(-) 11 | 12 | diff --git a/crypto/include/datatypes.h b/crypto/include/datatypes.h 13 | index 6a588d0..0037968 100644 14 | --- a/crypto/include/datatypes.h 15 | +++ b/crypto/include/datatypes.h 16 | @@ -59,8 +59,12 @@ 17 | #elif defined HAVE_WINSOCK2_H 18 | #include 19 | #else 20 | +#ifdef KVS_PLAT_ESP_FREERTOS 21 | +#include 22 | +#else 23 | #error "Platform not recognized" 24 | #endif 25 | +#endif 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | diff --git a/crypto/kernel/crypto_kernel.c b/crypto/kernel/crypto_kernel.c 30 | index df6af7d..cba6922 100644 31 | --- a/crypto/kernel/crypto_kernel.c 32 | +++ b/crypto/kernel/crypto_kernel.c 33 | @@ -277,7 +277,7 @@ static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type( 34 | srtp_cipher_type_id_t id, 35 | int replace) 36 | { 37 | - srtp_kernel_cipher_type_t *ctype, *new_ctype; 38 | + srtp_kernel_cipher_type_t *ctype, *new_ctype = NULL; 39 | srtp_err_status_t status; 40 | 41 | /* defensive coding */ 42 | diff --git a/srtp/srtp.c b/srtp/srtp.c 43 | index b45cee0..eff328f 100644 44 | --- a/srtp/srtp.c 45 | +++ b/srtp/srtp.c 46 | @@ -3151,6 +3151,7 @@ srtp_err_status_t srtp_update_stream(srtp_t session, 47 | * 48 | * The default policy is defined in RFC 3711 49 | * (Section 5. Default and mandatory-to-implement Transforms) 50 | + * https://tools.ietf.org/html/rfc3711#section-5 51 | * 52 | */ 53 | 54 | @@ -3188,6 +3189,7 @@ void srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p) 55 | * corresponds to RFC 4568 56 | * 57 | * note that this crypto policy is intended for SRTP, but not SRTCP 58 | + * https://tools.ietf.org/html/rfc4568#section-6.2 59 | */ 60 | 61 | p->cipher_type = SRTP_AES_ICM_128; 62 | -- 63 | 2.17.1 64 | 65 | -------------------------------------------------------------------------------- /patch/libsrtp/0004-use-angle-brackets-for-consistency.patch: -------------------------------------------------------------------------------- 1 | From 138523445d8d1f1d2eff9285094a6c3ce197a9d0 Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Tue, 5 Jan 2021 10:21:06 +0800 4 | Subject: [PATCH 4/8] use angle brackets for consistency. 5 | 6 | --- 7 | crypto/hash/hmac_mbedtls.c | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/crypto/hash/hmac_mbedtls.c b/crypto/hash/hmac_mbedtls.c 11 | index 78ad71c..c3ee648 100644 12 | --- a/crypto/hash/hmac_mbedtls.c 13 | +++ b/crypto/hash/hmac_mbedtls.c 14 | @@ -48,7 +48,7 @@ 15 | #include "auth.h" 16 | #include "alloc.h" 17 | #include "err.h" /* for srtp_debug */ 18 | -#include "mbedtls/md.h" 19 | +#include 20 | 21 | #define SHA1_DIGEST_SIZE 20 22 | 23 | -- 24 | 2.17.1 25 | 26 | -------------------------------------------------------------------------------- /patch/libsrtp/0005-change-the-order-of-mbedtls.patch: -------------------------------------------------------------------------------- 1 | From 95b5b6bee5ea40c962eee4f421bad206bc8c1a19 Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Fri, 8 Jan 2021 18:32:06 +0800 4 | Subject: [PATCH 5/8] change the order of mbedtls. 5 | 6 | --- 7 | config_in_cmake.h | 5 +++-- 8 | 1 file changed, 3 insertions(+), 2 deletions(-) 9 | 10 | diff --git a/config_in_cmake.h b/config_in_cmake.h 11 | index 3e66531..7e0936c 100644 12 | --- a/config_in_cmake.h 13 | +++ b/config_in_cmake.h 14 | @@ -18,11 +18,12 @@ 15 | /* Define this to use OpenSSL crypto. */ 16 | #cmakedefine OPENSSL 1 17 | 18 | +/* Define this to use MBEDTLS. */ 19 | +#cmakedefine MBEDTLS 1 20 | + 21 | /* Define this to use AES-GCM. */ 22 | #cmakedefine GCM 1 23 | 24 | -/* Define this to use MBEDTLS. */ 25 | -#cmakedefine MBEDTLS 1 26 | 27 | /* Define if building for a CISC machine (e.g. Intel). */ 28 | #define CPU_CISC 1 29 | -- 30 | 2.17.1 31 | 32 | -------------------------------------------------------------------------------- /patch/libsrtp/0006-remove-the-wordy-define.patch: -------------------------------------------------------------------------------- 1 | From 3f63b63761a4fa6eec5ac9ec336c760de2abc9ad Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Fri, 8 Jan 2021 18:37:06 +0800 4 | Subject: [PATCH 6/8] remove the wordy define. 5 | 6 | --- 7 | crypto/include/cipher_types.h | 10 ++-------- 8 | 1 file changed, 2 insertions(+), 8 deletions(-) 9 | 10 | diff --git a/crypto/include/cipher_types.h b/crypto/include/cipher_types.h 11 | index f6abd02..089e705 100644 12 | --- a/crypto/include/cipher_types.h 13 | +++ b/crypto/include/cipher_types.h 14 | @@ -71,17 +71,11 @@ extern srtp_debug_module_t srtp_mod_alloc; 15 | 16 | /* debug modules for cipher types */ 17 | extern srtp_debug_module_t srtp_mod_aes_icm; 18 | -#ifdef OPENSSL 19 | -extern srtp_debug_module_t srtp_mod_aes_gcm; 20 | -#endif 21 | -#ifdef MBEDTLS 22 | -extern srtp_debug_module_t srtp_mod_aes_gcm; 23 | -#endif 24 | -#ifdef NSS 25 | + 26 | +#if (defined(OPENSSL) || defined(MBEDTLS) || defined(NSS)) 27 | extern srtp_debug_module_t srtp_mod_aes_gcm; 28 | #endif 29 | 30 | /* debug modules for auth types */ 31 | extern srtp_debug_module_t srtp_mod_hmac; 32 | - 33 | #endif 34 | -- 35 | 2.17.1 36 | 37 | -------------------------------------------------------------------------------- /patch/libsrtp/0007-remove-unnecessary-parentheses.patch: -------------------------------------------------------------------------------- 1 | From 39833d7151aba2d2fc9733ed7d0e42c428c2a4ce Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Fri, 8 Jan 2021 19:03:32 +0800 4 | Subject: [PATCH 7/8] remove unnecessary parentheses. 5 | 6 | --- 7 | crypto/include/cipher_types.h | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/crypto/include/cipher_types.h b/crypto/include/cipher_types.h 11 | index 089e705..7221b30 100644 12 | --- a/crypto/include/cipher_types.h 13 | +++ b/crypto/include/cipher_types.h 14 | @@ -72,7 +72,7 @@ extern srtp_debug_module_t srtp_mod_alloc; 15 | /* debug modules for cipher types */ 16 | extern srtp_debug_module_t srtp_mod_aes_icm; 17 | 18 | -#if (defined(OPENSSL) || defined(MBEDTLS) || defined(NSS)) 19 | +#if defined(OPENSSL) || defined(MBEDTLS) || defined(NSS) 20 | extern srtp_debug_module_t srtp_mod_aes_gcm; 21 | #endif 22 | 23 | -- 24 | 2.17.1 25 | 26 | -------------------------------------------------------------------------------- /patch/libsrtp/0008-fix-compile-error.patch: -------------------------------------------------------------------------------- 1 | From a976c8233836972f0f561b7f662a890c8373e937 Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Wed, 19 May 2021 12:14:54 +0800 4 | Subject: [PATCH 8/8] fix compile error. 5 | 6 | --- 7 | CMakeLists.txt | 5 ++++- 8 | 1 file changed, 4 insertions(+), 1 deletion(-) 9 | 10 | diff --git a/CMakeLists.txt b/CMakeLists.txt 11 | index 115f6f4..90c54ce 100644 12 | --- a/CMakeLists.txt 13 | +++ b/CMakeLists.txt 14 | @@ -57,6 +57,7 @@ set(ENABLE_OPENSSL OFF CACHE BOOL "Enable OpenSSL crypto engine") 15 | set(ENABLE_MBEDTLS ON CACHE BOOL "Enable MbedTLS crypto engine") 16 | set(TEST_APPS OFF CACHE BOOL "Build test applications") 17 | option(BUILD_SHARED_LIBS "Build shared library" OFF) 18 | +option(KVS_PLAT_ESP_FREERTOS "Build for ESP FreeRTOS" OFF) 19 | 20 | if(ENABLE_OPENSSL AND ENABLE_MBEDTLS) 21 | message(FATAL_ERROR "ssl conflict. can not enable openssl and mbedtls simultaneously.") 22 | @@ -70,7 +71,9 @@ if(ENABLE_OPENSSL) 23 | endif() 24 | 25 | if(ENABLE_MBEDTLS) 26 | - find_package(MbedTLS REQUIRED) 27 | + if(NOT KVS_PLAT_ESP_FREERTOS) 28 | + find_package(MbedTLS REQUIRED) 29 | + endif() 30 | include_directories(${MBEDTLS_INCLUDE_DIRS}) 31 | set(MBEDTLS ${ENABLE_MBEDTLS} CACHE BOOL INTERNAL) 32 | set(GCM ${ENABLE_MBEDTLS} CACHE BOOL INTERNAL) 33 | -- 34 | 2.17.1 35 | 36 | -------------------------------------------------------------------------------- /patch/usrsctp/0002-disable-ipv6-and-program.patch: -------------------------------------------------------------------------------- 1 | From 0149f44fe89dbf460773ff82736febcf36eddf96 Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Thu, 29 Apr 2021 17:25:17 +0800 4 | Subject: [PATCH 2/7] disable ipv6 and program. 5 | 6 | --- 7 | CMakeLists.txt | 6 +++--- 8 | 1 file changed, 3 insertions(+), 3 deletions(-) 9 | 10 | diff --git a/CMakeLists.txt b/CMakeLists.txt 11 | index 64c0061..bc0efe4 100644 12 | --- a/CMakeLists.txt 13 | +++ b/CMakeLists.txt 14 | @@ -62,16 +62,16 @@ if (sctp_inet) 15 | add_definitions(-DINET) 16 | endif () 17 | 18 | -option(sctp_inet6 "Support IPv6" 1) 19 | +option(sctp_inet6 "Support IPv6" 0) 20 | if (sctp_inet6) 21 | add_definitions(-DINET6) 22 | endif () 23 | 24 | -option(sctp_werror "Treat warning as error" 1) 25 | +option(sctp_werror "Treat warning as error" 0) 26 | 27 | option(sctp_link_programs_static "Link example programs static" 0) 28 | 29 | -option(sctp_build_programs "Build example programs" 1) 30 | +option(sctp_build_programs "Build example programs" 0) 31 | 32 | option(sctp_sanitizer_address "Compile with address sanitizer" 0) 33 | 34 | -- 35 | 2.34.1 36 | 37 | -------------------------------------------------------------------------------- /patch/usrsctp/0003-add-mbedtls-sha1-support.patch: -------------------------------------------------------------------------------- 1 | From 4d610f33085e570b89f5f9fbff699af30b735e9d Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Fri, 23 Apr 2021 16:50:39 +0800 4 | Subject: [PATCH 3/7] add-mbedtls-sha1-support. 5 | 6 | --- 7 | CMakeLists.txt | 2 ++ 8 | cmake/FindMbedTLS.cmake | 38 ++++++++++++++++++++++++++++++++++ 9 | usrsctplib/CMakeLists.txt | 16 ++++++++++++++ 10 | usrsctplib/netinet/sctp_sha1.c | 18 ++++++++++++++++ 11 | usrsctplib/netinet/sctp_sha1.h | 4 ++++ 12 | 5 files changed, 78 insertions(+) 13 | create mode 100644 cmake/FindMbedTLS.cmake 14 | 15 | diff --git a/CMakeLists.txt b/CMakeLists.txt 16 | index bc0efe4..31afb47 100644 17 | --- a/CMakeLists.txt 18 | +++ b/CMakeLists.txt 19 | @@ -38,6 +38,8 @@ if (NOT CMAKE_BUILD_TYPE) 20 | set(CMAKE_BUILD_TYPE "DEBUG") 21 | endif () 22 | 23 | +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 24 | + 25 | include(CheckStructHasMember) 26 | include(CheckIncludeFile) 27 | include(CheckIncludeFiles) 28 | diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake 29 | new file mode 100644 30 | index 0000000..b3ed046 31 | --- /dev/null 32 | +++ b/cmake/FindMbedTLS.cmake 33 | @@ -0,0 +1,38 @@ 34 | +find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h) 35 | + 36 | +find_library(MBEDTLS_LIBRARY mbedtls) 37 | +find_library(MBEDX509_LIBRARY mbedx509) 38 | +find_library(MBEDCRYPTO_LIBRARY mbedcrypto) 39 | + 40 | +set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}") 41 | + 42 | +include(FindPackageHandleStandardArgs) 43 | +find_package_handle_standard_args(MbedTLS DEFAULT_MSG 44 | + MBEDTLS_LIBRARY MBEDTLS_INCLUDE_DIRS MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) 45 | + 46 | +mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) 47 | + 48 | +if(NOT TARGET MbedTLS) 49 | + message("in mbedtls ${MBEDTLS_LIBRARY}") 50 | + add_library(MbedTLS UNKNOWN IMPORTED) 51 | + set_target_properties(MbedTLS PROPERTIES 52 | + INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIRS}" 53 | + IMPORTED_LINK_INTERFACE_LANGUAGES "C" 54 | + IMPORTED_LOCATION "${MBEDTLS_LIBRARY}") 55 | +endif() 56 | + 57 | +if(NOT TARGET MbedCrypto) 58 | + add_library(MbedCrypto UNKNOWN IMPORTED) 59 | + set_target_properties(MbedCrypto PROPERTIES 60 | + INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIRS}" 61 | + IMPORTED_LINK_INTERFACE_LANGUAGES "C" 62 | + IMPORTED_LOCATION "${MBEDCRYPTO_LIBRARY}") 63 | +endif() 64 | + 65 | +if(NOT TARGET MbedX509) 66 | + add_library(MbedX509 UNKNOWN IMPORTED) 67 | + set_target_properties(MbedX509 PROPERTIES 68 | + INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIRS}" 69 | + IMPORTED_LINK_INTERFACE_LANGUAGES "C" 70 | + IMPORTED_LOCATION "${MBEDX509_LIBRARY}") 71 | +endif() 72 | diff --git a/usrsctplib/CMakeLists.txt b/usrsctplib/CMakeLists.txt 73 | index 6eb0f36..bd6c521 100644 74 | --- a/usrsctplib/CMakeLists.txt 75 | +++ b/usrsctplib/CMakeLists.txt 76 | @@ -45,6 +45,9 @@ set(CMAKE_MACOSX_RPATH 1) 77 | 78 | include(CheckCCompilerFlag) 79 | 80 | + 81 | +option(SCTP_USE_MBEDTLS_SHA1 "Build with mbedtls sha1 support." ON) 82 | + 83 | add_definitions(-D__Userspace__) 84 | add_definitions(-DSCTP_SIMPLE_ALLOCATOR) 85 | add_definitions(-DSCTP_PROCESS_LEVEL_LOCKS) 86 | @@ -52,6 +55,11 @@ if(NOT sctp_use_lwip) 87 | add_definitions(-D__native_client__) 88 | endif() 89 | 90 | +if(SCTP_USE_MBEDTLS_SHA1) 91 | + add_definitions(-DSCTP_USE_MBEDTLS_SHA1) 92 | + find_package(MbedTLS REQUIRED) 93 | +endif() 94 | + 95 | 96 | ################################################# 97 | # OS DEPENDENT 98 | @@ -175,12 +183,20 @@ add_library(usrsctp-static STATIC ${usrsctp_sources} ${usrsctp_headers}) 99 | target_include_directories(usrsctp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 100 | target_include_directories(usrsctp-static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 101 | 102 | +if(SCTP_USE_MBEDTLS_SHA1) 103 | + target_include_directories(usrsctp PRIVATE ${MBEDTLS_INCLUDE_DIRS}) 104 | +endif() 105 | + 106 | if (WIN32) 107 | message(STATUS "link library: ws2_32") 108 | target_link_libraries(usrsctp ws2_32 iphlpapi.lib) 109 | target_link_libraries(usrsctp-static ws2_32 iphlpapi.lib) 110 | endif () 111 | 112 | +if(SCTP_USE_MBEDTLS_SHA1) 113 | + target_link_libraries(usrsctp PRIVATE ${MBEDTLS_LIBRARIES}) 114 | +endif() 115 | + 116 | set_target_properties(usrsctp-static PROPERTIES OUTPUT_NAME "usrsctp") 117 | set_target_properties(usrsctp PROPERTIES IMPORT_SUFFIX "_import.lib") 118 | set_target_properties(usrsctp PROPERTIES SOVERSION 1 VERSION 1.0.0) 119 | diff --git a/usrsctplib/netinet/sctp_sha1.c b/usrsctplib/netinet/sctp_sha1.c 120 | index db0e753..8472c3a 100755 121 | --- a/usrsctplib/netinet/sctp_sha1.c 122 | +++ b/usrsctplib/netinet/sctp_sha1.c 123 | @@ -80,7 +80,25 @@ sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx) 124 | { 125 | SHA1_Final(digest, &ctx->sha_ctx); 126 | } 127 | +#elif defined(SCTP_USE_MBEDTLS_SHA1) 128 | +void 129 | +sctp_sha1_init(struct sctp_sha1_context *ctx) 130 | +{ 131 | + mbedtls_sha1_init(&ctx->sha1_ctx); 132 | + mbedtls_sha1_starts_ret(&ctx->sha1_ctx); 133 | +} 134 | 135 | +void 136 | +sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz) 137 | +{ 138 | + mbedtls_sha1_update_ret(&ctx->sha1_ctx, ptr, siz); 139 | +} 140 | + 141 | +void 142 | +sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx) 143 | +{ 144 | + mbedtls_sha1_finish_ret(&ctx->sha1_ctx, digest); 145 | +} 146 | #else 147 | 148 | #include 149 | diff --git a/usrsctplib/netinet/sctp_sha1.h b/usrsctplib/netinet/sctp_sha1.h 150 | index d535ee4..9ff4ff7 100755 151 | --- a/usrsctplib/netinet/sctp_sha1.h 152 | +++ b/usrsctplib/netinet/sctp_sha1.h 153 | @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); 154 | #include 155 | #elif defined(SCTP_USE_OPENSSL_SHA1) 156 | #include 157 | +#elif defined(SCTP_USE_MBEDTLS_SHA1) 158 | +#include 159 | #endif 160 | 161 | struct sctp_sha1_context { 162 | @@ -53,6 +55,8 @@ struct sctp_sha1_context { 163 | struct PK11Context *pk11_ctx; 164 | #elif defined(SCTP_USE_OPENSSL_SHA1) 165 | SHA_CTX sha_ctx; 166 | +#elif defined(SCTP_USE_MBEDTLS_SHA1) 167 | + mbedtls_sha1_context sha1_ctx; 168 | #else 169 | unsigned int A; 170 | unsigned int B; 171 | -- 172 | 2.34.1 173 | 174 | -------------------------------------------------------------------------------- /patch/usrsctp/0004-change-the-cmakefiles-for-esp32.patch: -------------------------------------------------------------------------------- 1 | From b31c1906d8cd8a9334ea34eaf124c0fddfebd905 Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Tue, 4 May 2021 11:38:40 +0800 4 | Subject: [PATCH 4/7] change the cmakefiles for esp32. 5 | 6 | --- 7 | CMakeLists.txt | 6 ++++++ 8 | usrsctplib/CMakeLists.txt | 4 +++- 9 | 2 files changed, 9 insertions(+), 1 deletion(-) 10 | 11 | diff --git a/CMakeLists.txt b/CMakeLists.txt 12 | index 31afb47..f04b944 100644 13 | --- a/CMakeLists.txt 14 | +++ b/CMakeLists.txt 15 | @@ -82,11 +82,17 @@ option(sctp_sanitizer_memory "Compile with memory sanitizer" 0) 16 | option(sctp_build_fuzzer "Compile in clang fuzzing mode" 0) 17 | 18 | option(sctp_use_lwip "build with lwip" ON) 19 | +option(sctp_use_rtos "build with rtos" ON) 20 | 21 | if(sctp_use_lwip) 22 | add_definitions(-DSCTP_USE_LWIP) 23 | endif() 24 | 25 | +if(sctp_use_rtos) 26 | + add_definitions(-DSCTP_USE_RTOS) 27 | +endif() 28 | + 29 | + 30 | if (sctp_sanitizer_address AND sctp_sanitizer_memory) 31 | message(FATAL_ERROR "Can not compile with both sanitizer options") 32 | endif () 33 | diff --git a/usrsctplib/CMakeLists.txt b/usrsctplib/CMakeLists.txt 34 | index bd6c521..3c62813 100644 35 | --- a/usrsctplib/CMakeLists.txt 36 | +++ b/usrsctplib/CMakeLists.txt 37 | @@ -57,7 +57,9 @@ endif() 38 | 39 | if(SCTP_USE_MBEDTLS_SHA1) 40 | add_definitions(-DSCTP_USE_MBEDTLS_SHA1) 41 | - find_package(MbedTLS REQUIRED) 42 | + if(NOT sctp_use_rtos) 43 | + find_package(MbedTLS REQUIRED) 44 | + endif() 45 | endif() 46 | 47 | 48 | -- 49 | 2.34.1 50 | 51 | -------------------------------------------------------------------------------- /patch/usrsctp/0005-add-the-name-and-size-of-threads.patch: -------------------------------------------------------------------------------- 1 | From 42d8b37dda2c817db0b626f6b8ea9f362c929439 Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Wed, 5 May 2021 11:17:39 +0800 4 | Subject: [PATCH 5/7] add the name and size of threads. 5 | 6 | --- 7 | usrsctplib/CMakeLists.txt | 1 + 8 | usrsctplib/netinet/sctp_bsd_addr.c | 5 ++- 9 | usrsctplib/netinet/sctp_callout.c | 5 ++- 10 | usrsctplib/netinet/sctp_os_userspace.h | 2 +- 11 | usrsctplib/netinet/sctp_userspace.c | 61 ++++++++++++++++++++++++- 12 | usrsctplib/user_config.h | 62 ++++++++++++++++++++++++++ 13 | usrsctplib/user_recv_thread.c | 21 ++++----- 14 | 7 files changed, 140 insertions(+), 17 deletions(-) 15 | create mode 100755 usrsctplib/user_config.h 16 | 17 | diff --git a/usrsctplib/CMakeLists.txt b/usrsctplib/CMakeLists.txt 18 | index 3c62813..7f45b47 100644 19 | --- a/usrsctplib/CMakeLists.txt 20 | +++ b/usrsctplib/CMakeLists.txt 21 | @@ -99,6 +99,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 22 | 23 | list(APPEND usrsctp_root_headers 24 | user_atomic.h 25 | + user_config.h 26 | user_environment.h 27 | user_inpcb.h 28 | user_ip_icmp.h 29 | diff --git a/usrsctplib/netinet/sctp_bsd_addr.c b/usrsctplib/netinet/sctp_bsd_addr.c 30 | index 76d40b8..71f82ca 100755 31 | --- a/usrsctplib/netinet/sctp_bsd_addr.c 32 | +++ b/usrsctplib/netinet/sctp_bsd_addr.c 33 | @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 358080 2020-02-18 19:41:55Z 34 | #include 35 | #include 36 | #include 37 | +#include 38 | #if defined(__FreeBSD__) && !defined(__Userspace__) 39 | #include 40 | #endif 41 | @@ -128,7 +129,7 @@ static void 42 | sctp_iterator_thread(void *v SCTP_UNUSED) 43 | { 44 | #if defined(__Userspace__) 45 | - sctp_userspace_set_threadname("SCTP iterator"); 46 | + sctp_userspace_set_threadname(SCTP_THREAD_ITERATOR_NAME); 47 | #endif 48 | SCTP_IPI_ITERATOR_WQ_LOCK(); 49 | /* In FreeBSD this thread never terminates. */ 50 | @@ -189,7 +190,7 @@ sctp_startup_iterator(void) 51 | SCTP_IPI_ITERATOR_WQ_INIT(); 52 | TAILQ_INIT(&sctp_it_ctl.iteratorhead); 53 | #if defined(__Userspace__) 54 | - if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread)) { 55 | + if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread, SCTP_THREAD_ITERATOR_NAME, SCTP_THREAD_ITERATOR_SIZE)) { 56 | SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n"); 57 | } else { 58 | SCTP_BASE_VAR(iterator_thread_started) = 1; 59 | diff --git a/usrsctplib/netinet/sctp_callout.c b/usrsctplib/netinet/sctp_callout.c 60 | index d66da73..0e780a8 100755 61 | --- a/usrsctplib/netinet/sctp_callout.c 62 | +++ b/usrsctplib/netinet/sctp_callout.c 63 | @@ -58,6 +58,7 @@ 64 | #include 65 | #include 66 | #endif 67 | +#include 68 | #include 69 | 70 | /* 71 | @@ -199,7 +200,7 @@ sctp_timeout(void *arg SCTP_UNUSED) 72 | void * 73 | user_sctp_timer_iterate(void *arg) 74 | { 75 | - sctp_userspace_set_threadname("SCTP timer"); 76 | + sctp_userspace_set_threadname(SCTP_THREAD_TIMER_NAME); 77 | for (;;) { 78 | #if defined(_WIN32) 79 | Sleep(TIMEOUT_INTERVAL); 80 | @@ -231,7 +232,7 @@ sctp_start_timer_thread(void) 81 | */ 82 | int rc; 83 | 84 | - rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(timer_thread), user_sctp_timer_iterate); 85 | + rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(timer_thread), user_sctp_timer_iterate, SCTP_THREAD_TIMER_NAME, SCTP_THREAD_TIMER_SIZE); 86 | if (rc) { 87 | SCTP_PRINTF("ERROR; return code from sctp_thread_create() is %d\n", rc); 88 | } else { 89 | diff --git a/usrsctplib/netinet/sctp_os_userspace.h b/usrsctplib/netinet/sctp_os_userspace.h 90 | index 87ced8b..b2a09e1 100755 91 | --- a/usrsctplib/netinet/sctp_os_userspace.h 92 | +++ b/usrsctplib/netinet/sctp_os_userspace.h 93 | @@ -1029,7 +1029,7 @@ struct sockaddr_conn { 94 | typedef void *(*start_routine_t)(void *); 95 | 96 | extern int 97 | -sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine); 98 | +sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine, const char* thread_name, uint32_t thread_size); 99 | 100 | void 101 | sctp_userspace_set_threadname(const char *name); 102 | diff --git a/usrsctplib/netinet/sctp_userspace.c b/usrsctplib/netinet/sctp_userspace.c 103 | index 8dd386f..2b4a533 100755 104 | --- a/usrsctplib/netinet/sctp_userspace.c 105 | +++ b/usrsctplib/netinet/sctp_userspace.c 106 | @@ -35,6 +35,12 @@ 107 | #pragma comment(lib, "IPHLPAPI.lib") 108 | #endif 109 | #endif 110 | +#include 111 | + 112 | +#if defined(SCTP_USE_RTOS) 113 | +#include 114 | +#include "esp_pthread.h" 115 | +#endif 116 | #include 117 | #if defined(__FreeBSD__) 118 | #include 119 | @@ -44,6 +50,8 @@ 120 | #include 121 | #endif 122 | 123 | + 124 | + 125 | #if defined(_WIN32) 126 | /* Adapter to translate Unix thread start routines to Windows thread start 127 | * routines. 128 | @@ -59,7 +67,7 @@ sctp_create_thread_adapter(void *arg) { 129 | } 130 | 131 | int 132 | -sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine) 133 | +sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine, const char* thread_name, uint32_t thread_size) 134 | { 135 | *thread = CreateThread(NULL, 0, sctp_create_thread_adapter, 136 | (void *)start_routine, 0, NULL); 137 | @@ -72,9 +80,58 @@ sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_ro 138 | #pragma GCC diagnostic pop 139 | #endif 140 | 141 | +#elif defined(SCTP_USE_RTOS) 142 | +#include "esp_pthread.h" 143 | + 144 | +int 145 | +sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine, const char* thread_name, uint32_t thread_size) 146 | +{ 147 | + esp_pthread_cfg_t pthread_cfg; 148 | + esp_err_t esp_err = esp_pthread_get_cfg(&pthread_cfg); 149 | + pthread_attr_t *pAttr = NULL; 150 | + pthread_attr_t attr; 151 | + pAttr = &attr; 152 | + int result = 0; 153 | + 154 | + result = pthread_attr_init(pAttr); 155 | + extern struct sctp_base_info system_base_info; 156 | + if(esp_err != ESP_OK){ 157 | + SCTPDBG(SCTP_DEBUG_USR, "get the esp pthread cfg failed.\n"); 158 | + //SCTP_PRINTF("get the esp pthread cfg failed.\n"); 159 | + return esp_err; 160 | + } 161 | + 162 | + if(thread_size == 0){ 163 | + pthread_cfg.stack_size = SCTP_THREAD_DEFAULT_SIZE; 164 | + }else{ 165 | + pthread_cfg.stack_size = thread_size; 166 | + } 167 | + 168 | + if(thread_name == NULL){ 169 | + pthread_cfg.thread_name = SCTP_THREAD_DEFAULT_NAME; 170 | + }else{ 171 | + pthread_cfg.thread_name = thread_name; 172 | + } 173 | + 174 | + esp_err = esp_pthread_set_cfg(&pthread_cfg); 175 | + 176 | + if(esp_err != ESP_OK){ 177 | + SCTPDBG(SCTP_DEBUG_USR, "set the esp pthread cfg failed.\n"); 178 | + //SCTP_PRINTF("set the esp pthread cfg failed.\n"); 179 | + return esp_err; 180 | + } 181 | + 182 | + if(thread_size == 0){ 183 | + pthread_attr_setstacksize(pAttr, SCTP_THREAD_DEFAULT_SIZE); 184 | + }else{ 185 | + pthread_attr_setstacksize(pAttr, thread_size); 186 | + } 187 | + 188 | + return pthread_create(thread, pAttr, start_routine, NULL); 189 | +} 190 | #else 191 | int 192 | -sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine) 193 | +sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine, const char* thread_name, uint32_t thread_size) 194 | { 195 | return pthread_create(thread, NULL, start_routine, NULL); 196 | } 197 | diff --git a/usrsctplib/user_config.h b/usrsctplib/user_config.h 198 | new file mode 100755 199 | index 0000000..10432a1 200 | --- /dev/null 201 | +++ b/usrsctplib/user_config.h 202 | @@ -0,0 +1,62 @@ 203 | +/*- 204 | + * SPDX-License-Identifier: BSD-3-Clause 205 | + * 206 | + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 207 | + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 208 | + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 209 | + * 210 | + * Redistribution and use in source and binary forms, with or without 211 | + * modification, are permitted provided that the following conditions are met: 212 | + * 213 | + * a) Redistributions of source code must retain the above copyright notice, 214 | + * this list of conditions and the following disclaimer. 215 | + * 216 | + * b) Redistributions in binary form must reproduce the above copyright 217 | + * notice, this list of conditions and the following disclaimer in 218 | + * the documentation and/or other materials provided with the distribution. 219 | + * 220 | + * c) Neither the name of Cisco Systems, Inc. nor the names of its 221 | + * contributors may be used to endorse or promote products derived 222 | + * from this software without specific prior written permission. 223 | + * 224 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 225 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 226 | + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 227 | + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 228 | + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 229 | + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 230 | + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231 | + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 232 | + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 233 | + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 234 | + * THE POSSIBILITY OF SUCH DAMAGE. 235 | + */ 236 | + 237 | +#if defined(__FreeBSD__) && !defined(__Userspace__) 238 | +#include 239 | +__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.h 359195 2020-03-21 16:12:19Z tuexen $"); 240 | +#endif 241 | + 242 | +#ifndef _NETINET_USER_CONFIG_H_ 243 | +#define _NETINET_USER_CONFIG_H_ 244 | + 245 | +#define SCTP_THREAD_DEFAULT_NAME "pthread" 246 | +#define SCTP_THREAD_DEFAULT_SIZE 4096 247 | +#define SCTP_THREAD_ADDR_MON_NAME "SCTP addr mon" 248 | +#define SCTP_THREAD_ADDR_MON_SIZE SCTP_THREAD_DEFAULT_SIZE 249 | +#define SCTP_THREAD_IPV4_RCV_NAME "SCTP/IP4" 250 | +#define SCTP_THREAD_IPV4_RCV_SIZE SCTP_THREAD_DEFAULT_SIZE 251 | +#define SCTP_THREAD_UDP_IPV4_RCV_NAME "SCTP/UDP/IP4" 252 | +#define SCTP_THREAD_UDP_IPV4_RCV_SIZE SCTP_THREAD_DEFAULT_SIZE 253 | +#define SCTP_THREAD_IPV6_RCV_NAME "SCTP/IP6" 254 | +#define SCTP_THREAD_IPV6_RCV_SIZE SCTP_THREAD_DEFAULT_SIZE 255 | +#define SCTP_THREAD_IPV6_RCV_NAME "SCTP/IP6" 256 | +#define SCTP_THREAD_IPV6_RCV_SIZE SCTP_THREAD_DEFAULT_SIZE 257 | +#define SCTP_THREAD_UDP_IPV6_RCV_NAME "SCTP/UDP/IP6" 258 | +#define SCTP_THREAD_UDP_IPV6_SIZE SCTP_THREAD_DEFAULT_SIZE 259 | +#define SCTP_THREAD_ITERATOR_NAME "SCTP iterator" 260 | +#define SCTP_THREAD_ITERATOR_SIZE SCTP_THREAD_DEFAULT_SIZE 261 | +#define SCTP_THREAD_TIMER_NAME "SCTP timer" 262 | +#define SCTP_THREAD_TIMER_SIZE 8192//SCTP_THREAD_DEFAULT_SIZE 263 | + 264 | +#endif//!< _NETINET_USER_CONFIG_H_ 265 | diff --git a/usrsctplib/user_recv_thread.c b/usrsctplib/user_recv_thread.c 266 | index 5848e94..cc912cb 100755 267 | --- a/usrsctplib/user_recv_thread.c 268 | +++ b/usrsctplib/user_recv_thread.c 269 | @@ -41,6 +41,7 @@ 270 | #include 271 | #endif 272 | #endif 273 | +#include 274 | #include 275 | #include 276 | #include 277 | @@ -144,7 +145,7 @@ recv_function_route(void *arg) 278 | char rt_buffer[1024]; 279 | struct sockaddr *sa, *rti_info[RTAX_MAX]; 280 | 281 | - sctp_userspace_set_threadname("SCTP addr mon"); 282 | + sctp_userspace_set_threadname(SCTP_THREAD_ADDR_MON_NAME); 283 | 284 | while (1) { 285 | memset(rt_buffer, 0, sizeof(rt_buffer)); 286 | @@ -295,7 +296,7 @@ recv_function_raw(void *arg) 287 | int want_ext = (iovlen > MLEN)? 1 : 0; 288 | int want_header = 0; 289 | 290 | - sctp_userspace_set_threadname("SCTP/IP4 rcv"); 291 | + sctp_userspace_set_threadname(SCTP_THREAD_IPV4_RCV_NAME); 292 | 293 | memset(&src, 0, sizeof(struct sockaddr_in)); 294 | memset(&dst, 0, sizeof(struct sockaddr_in)); 295 | @@ -476,7 +477,7 @@ recv_function_raw6(void *arg) 296 | int want_ext = (iovlen > MLEN)? 1 : 0; 297 | int want_header = 0; 298 | 299 | - sctp_userspace_set_threadname("SCTP/IP6 rcv"); 300 | + sctp_userspace_set_threadname(SCTP_THREAD_IPV6_RCV_NAME); 301 | 302 | recvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 303 | 304 | @@ -665,7 +666,7 @@ recv_function_udp(void *arg) 305 | DWORD ncounter; 306 | #endif 307 | 308 | - sctp_userspace_set_threadname("SCTP/UDP/IP4 rcv"); 309 | + sctp_userspace_set_threadname(SCTP_THREAD_UDP_IPV4_RCV_NAME); 310 | 311 | udprecvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 312 | 313 | @@ -867,7 +868,7 @@ recv_function_udp6(void *arg) 314 | DWORD ncounter; 315 | #endif 316 | 317 | - sctp_userspace_set_threadname("SCTP/UDP/IP6 rcv"); 318 | + sctp_userspace_set_threadname(SCTP_THREAD_UDP_IPV6_RCV_NAME); 319 | 320 | udprecvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 321 | while (1) { 322 | @@ -1391,7 +1392,7 @@ recv_thread_init(void) 323 | if (SCTP_BASE_VAR(userspace_route) != -1) { 324 | int rc; 325 | 326 | - if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadroute), &recv_function_route))) { 327 | + if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadroute), &recv_function_route, SCTP_THREAD_ADDR_MON_NAME, SCTP_THREAD_ADDR_MON_SIZE))) { 328 | SCTPDBG(SCTP_DEBUG_USR, "Can't start routing thread (%d).\n", rc); 329 | close(SCTP_BASE_VAR(userspace_route)); 330 | SCTP_BASE_VAR(userspace_route) = -1; 331 | @@ -1403,7 +1404,7 @@ recv_thread_init(void) 332 | if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { 333 | int rc; 334 | 335 | - if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw), &recv_function_raw))) { 336 | + if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw), &recv_function_raw, SCTP_THREAD_IPV4_RCV_NAME, SCTP_THREAD_IPV4_RCV_SIZE))) { 337 | SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread (%d).\n", rc); 338 | #if defined(_WIN32) 339 | closesocket(SCTP_BASE_VAR(userspace_rawsctp)); 340 | @@ -1416,7 +1417,7 @@ recv_thread_init(void) 341 | if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { 342 | int rc; 343 | 344 | - if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp), &recv_function_udp))) { 345 | + if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp), &recv_function_udp, SCTP_THREAD_UDP_IPV4_RCV_NAME, SCTP_THREAD_UDP_IPV4_RCV_SIZE))) { 346 | SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc); 347 | #if defined(_WIN32) 348 | closesocket(SCTP_BASE_VAR(userspace_udpsctp)); 349 | @@ -1431,7 +1432,7 @@ recv_thread_init(void) 350 | if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 351 | int rc; 352 | 353 | - if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw6), &recv_function_raw6))) { 354 | + if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw6), &recv_function_raw6, SCTP_THREAD_IPV6_RCV_NAME, SCTP_THREAD_IPV6_RCV_SIZE))) { 355 | SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc); 356 | #if defined(_WIN32) 357 | closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 358 | @@ -1444,7 +1445,7 @@ recv_thread_init(void) 359 | if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { 360 | int rc; 361 | 362 | - if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp6), &recv_function_udp6))) { 363 | + if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp6), &recv_function_udp6, SCTP_THREAD_UDP_IPV6_RCV_NAME, SCTP_THREAD_UDP_IPV6_SIZE))) { 364 | SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc); 365 | #if defined(_WIN32) 366 | closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 367 | -- 368 | 2.34.1 369 | 370 | -------------------------------------------------------------------------------- /patch/usrsctp/0006-add-pthread_exit.patch: -------------------------------------------------------------------------------- 1 | From e49e4fb4bcb32ed8ac136592bf6be5eb328ee054 Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Tue, 26 Apr 2022 14:34:29 +0800 4 | Subject: [PATCH 6/7] add pthread_exit. 5 | 6 | --- 7 | usrsctplib/netinet/sctp_bsd_addr.c | 1 + 8 | usrsctplib/netinet/sctp_callout.c | 1 + 9 | usrsctplib/user_recv_thread.c | 5 +++++ 10 | 3 files changed, 7 insertions(+) 11 | 12 | diff --git a/usrsctplib/netinet/sctp_bsd_addr.c b/usrsctplib/netinet/sctp_bsd_addr.c 13 | index 71f82ca..ec900eb 100755 14 | --- a/usrsctplib/netinet/sctp_bsd_addr.c 15 | +++ b/usrsctplib/netinet/sctp_bsd_addr.c 16 | @@ -167,6 +167,7 @@ sctp_iterator_thread(void *v SCTP_UNUSED) 17 | SCTP_IPI_ITERATOR_WQ_UNLOCK(); 18 | #if defined(__Userspace__) 19 | sctp_wakeup_iterator(); 20 | + pthread_exit(NULL); 21 | return (NULL); 22 | #else 23 | wakeup(&sctp_it_ctl.iterator_flags); 24 | diff --git a/usrsctplib/netinet/sctp_callout.c b/usrsctplib/netinet/sctp_callout.c 25 | index 0e780a8..de74d79 100755 26 | --- a/usrsctplib/netinet/sctp_callout.c 27 | +++ b/usrsctplib/netinet/sctp_callout.c 28 | @@ -220,6 +220,7 @@ user_sctp_timer_iterate(void *arg) 29 | } 30 | sctp_handle_tick(sctp_msecs_to_ticks(TIMEOUT_INTERVAL)); 31 | } 32 | + pthread_exit(NULL); 33 | return (NULL); 34 | } 35 | 36 | diff --git a/usrsctplib/user_recv_thread.c b/usrsctplib/user_recv_thread.c 37 | index cc912cb..1a72948 100755 38 | --- a/usrsctplib/user_recv_thread.c 39 | +++ b/usrsctplib/user_recv_thread.c 40 | @@ -176,6 +176,7 @@ recv_function_route(void *arg) 41 | } 42 | } 43 | } 44 | + pthread_exit(NULL); 45 | return (NULL); 46 | } 47 | #endif 48 | @@ -437,6 +438,7 @@ recv_function_raw(void *arg) 49 | /* free the array itself */ 50 | free(recvmbuf); 51 | SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/IP4 rcv\n", __func__); 52 | + pthread_exit(NULL); 53 | return (NULL); 54 | } 55 | #endif 56 | @@ -623,6 +625,7 @@ recv_function_raw6(void *arg) 57 | /* free the array itself */ 58 | free(recvmbuf6); 59 | SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/IP6 rcv\n", __func__); 60 | + pthread_exit(NULL); 61 | return (NULL); 62 | } 63 | #endif 64 | @@ -829,6 +832,7 @@ recv_function_udp(void *arg) 65 | /* free the array itself */ 66 | free(udprecvmbuf); 67 | SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/UDP/IP4 rcv\n", __func__); 68 | + pthread_exit(NULL); 69 | return (NULL); 70 | } 71 | #endif 72 | @@ -1017,6 +1021,7 @@ recv_function_udp6(void *arg) 73 | /* free the array itself */ 74 | free(udprecvmbuf6); 75 | SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/UDP/IP6 rcv\n", __func__); 76 | + pthread_exit(NULL); 77 | return (NULL); 78 | } 79 | #endif 80 | -- 81 | 2.34.1 82 | 83 | -------------------------------------------------------------------------------- /patch/usrsctp/0007-disable-the-compiling-of-shared-lib.patch: -------------------------------------------------------------------------------- 1 | From 4c78c7a980f0db1da586a30167f08fe23fda9b64 Mon Sep 17 00:00:00 2001 2 | From: ycyang 3 | Date: Tue, 25 Apr 2023 13:45:29 +0800 4 | Subject: [PATCH 7/7] disable the compiling of shared lib. 5 | 6 | --- 7 | usrsctplib/CMakeLists.txt | 16 ++++++++-------- 8 | 1 file changed, 8 insertions(+), 8 deletions(-) 9 | 10 | diff --git a/usrsctplib/CMakeLists.txt b/usrsctplib/CMakeLists.txt 11 | index 7f45b47..581cf25 100644 12 | --- a/usrsctplib/CMakeLists.txt 13 | +++ b/usrsctplib/CMakeLists.txt 14 | @@ -180,29 +180,29 @@ list(APPEND usrsctp_sources 15 | user_socket.c 16 | ) 17 | 18 | -add_library(usrsctp SHARED ${usrsctp_sources} ${usrsctp_headers}) 19 | +#add_library(usrsctp STATIC ${usrsctp_sources} ${usrsctp_headers}) 20 | add_library(usrsctp-static STATIC ${usrsctp_sources} ${usrsctp_headers}) 21 | 22 | -target_include_directories(usrsctp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 23 | +#target_include_directories(usrsctp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 24 | target_include_directories(usrsctp-static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 25 | 26 | if(SCTP_USE_MBEDTLS_SHA1) 27 | - target_include_directories(usrsctp PRIVATE ${MBEDTLS_INCLUDE_DIRS}) 28 | + target_include_directories(usrsctp-static PRIVATE ${MBEDTLS_INCLUDE_DIRS}) 29 | endif() 30 | 31 | if (WIN32) 32 | message(STATUS "link library: ws2_32") 33 | - target_link_libraries(usrsctp ws2_32 iphlpapi.lib) 34 | + #target_link_libraries(usrsctp ws2_32 iphlpapi.lib) 35 | target_link_libraries(usrsctp-static ws2_32 iphlpapi.lib) 36 | endif () 37 | 38 | if(SCTP_USE_MBEDTLS_SHA1) 39 | - target_link_libraries(usrsctp PRIVATE ${MBEDTLS_LIBRARIES}) 40 | + target_link_libraries(usrsctp-static PRIVATE ${MBEDTLS_LIBRARIES}) 41 | endif() 42 | 43 | set_target_properties(usrsctp-static PROPERTIES OUTPUT_NAME "usrsctp") 44 | -set_target_properties(usrsctp PROPERTIES IMPORT_SUFFIX "_import.lib") 45 | -set_target_properties(usrsctp PROPERTIES SOVERSION 1 VERSION 1.0.0) 46 | +#set_target_properties(usrsctp PROPERTIES IMPORT_SUFFIX "_import.lib") 47 | +#set_target_properties(usrsctp PROPERTIES SOVERSION 1 VERSION 1.0.0) 48 | 49 | if (NOT DEFINED CMAKE_INSTALL_LIBDIR) 50 | SET(CMAKE_INSTALL_LIBDIR lib) 51 | @@ -213,5 +213,5 @@ endif () 52 | # INSTALL LIBRARY AND HEADER 53 | ################################################# 54 | 55 | -install(TARGETS usrsctp usrsctp-static DESTINATION ${CMAKE_INSTALL_LIBDIR}) 56 | +install(TARGETS usrsctp-static DESTINATION ${CMAKE_INSTALL_LIBDIR}) 57 | install(FILES usrsctp.h DESTINATION include) 58 | -- 59 | 2.34.1 60 | 61 | -------------------------------------------------------------------------------- /patch/wslay/0001-patches-for-freertos.patch: -------------------------------------------------------------------------------- 1 | From f563497a9e38ea9f5e95ffb17311d8df230c6eff Mon Sep 17 00:00:00 2001 2 | From: ycyang1229 3 | Date: Mon, 3 Jan 2022 10:29:02 +0800 4 | Subject: [PATCH] patches for freertos. 5 | 6 | --- 7 | CMakeLists.txt | 4 ++-- 8 | cmake/FindMbedTLS.cmake | 38 ++++++++++++++++++++++++++++++++++++++ 9 | examples/CMakeLists.txt | 7 +++++-- 10 | lib/CMakeLists.txt | 4 ++-- 11 | lib/wslay_net.h | 8 ++++++++ 12 | 5 files changed, 55 insertions(+), 6 deletions(-) 13 | create mode 100644 cmake/FindMbedTLS.cmake 14 | 15 | diff --git a/CMakeLists.txt b/CMakeLists.txt 16 | index 7a41914..9d5320b 100644 17 | --- a/CMakeLists.txt 18 | +++ b/CMakeLists.txt 19 | @@ -14,7 +14,7 @@ project(wslay) 20 | 21 | option(WSLAY_CONFIGURE_INSTALL "Generate install target" ON) 22 | option(WSLAY_STATIC "Build static version of the library" ON) 23 | -option(WSLAY_SHARED "Build shared version of the library" OFF) 24 | +option(WSLAY_SHARED "Build shared version of the library" ON) 25 | option(WSLAY_EXAMPLES "Build examples" OFF) 26 | option(WSLAY_TESTS "Build tests" OFF) 27 | 28 | @@ -30,7 +30,7 @@ endif() 29 | if (WSLAY_CONFIGURE_INSTALL) 30 | include(GNUInstallDirs) 31 | set(INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/wslay) 32 | - install(EXPORT wslay 33 | + install(TARGETS wslay 34 | DESTINATION ${INSTALL_CMAKE_DIR}) 35 | configure_file(wslay-config.cmake.in wslay-config.cmake @ONLY) 36 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/wslay-config.cmake 37 | diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake 38 | new file mode 100644 39 | index 0000000..b3ed046 40 | --- /dev/null 41 | +++ b/cmake/FindMbedTLS.cmake 42 | @@ -0,0 +1,38 @@ 43 | +find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h) 44 | + 45 | +find_library(MBEDTLS_LIBRARY mbedtls) 46 | +find_library(MBEDX509_LIBRARY mbedx509) 47 | +find_library(MBEDCRYPTO_LIBRARY mbedcrypto) 48 | + 49 | +set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}") 50 | + 51 | +include(FindPackageHandleStandardArgs) 52 | +find_package_handle_standard_args(MbedTLS DEFAULT_MSG 53 | + MBEDTLS_LIBRARY MBEDTLS_INCLUDE_DIRS MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) 54 | + 55 | +mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) 56 | + 57 | +if(NOT TARGET MbedTLS) 58 | + message("in mbedtls ${MBEDTLS_LIBRARY}") 59 | + add_library(MbedTLS UNKNOWN IMPORTED) 60 | + set_target_properties(MbedTLS PROPERTIES 61 | + INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIRS}" 62 | + IMPORTED_LINK_INTERFACE_LANGUAGES "C" 63 | + IMPORTED_LOCATION "${MBEDTLS_LIBRARY}") 64 | +endif() 65 | + 66 | +if(NOT TARGET MbedCrypto) 67 | + add_library(MbedCrypto UNKNOWN IMPORTED) 68 | + set_target_properties(MbedCrypto PROPERTIES 69 | + INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIRS}" 70 | + IMPORTED_LINK_INTERFACE_LANGUAGES "C" 71 | + IMPORTED_LOCATION "${MBEDCRYPTO_LIBRARY}") 72 | +endif() 73 | + 74 | +if(NOT TARGET MbedX509) 75 | + add_library(MbedX509 UNKNOWN IMPORTED) 76 | + set_target_properties(MbedX509 PROPERTIES 77 | + INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIRS}" 78 | + IMPORTED_LINK_INTERFACE_LANGUAGES "C" 79 | + IMPORTED_LOCATION "${MBEDX509_LIBRARY}") 80 | +endif() 81 | diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt 82 | index 5d6aabf..3b89672 100644 83 | --- a/examples/CMakeLists.txt 84 | +++ b/examples/CMakeLists.txt 85 | @@ -7,6 +7,9 @@ if(NOT HAVE_EPOLL) 86 | endif() 87 | find_package(Nettle REQUIRED) 88 | 89 | +find_package(MbedTLS REQUIRED) 90 | + 91 | + 92 | if(WSLAY_STATIC) 93 | set(WSLAY_TARGET "wslay") 94 | else() 95 | @@ -22,5 +25,5 @@ target_include_directories(fork-echoserv PRIVATE ${NETTLE_INCLUDE_DIRS}) 96 | target_link_libraries(fork-echoserv ${WSLAY_TARGET} ${NETTLE_LIBRARIES}) 97 | 98 | add_executable(testclient testclient.cc) 99 | -target_include_directories(testclient PRIVATE ${NETTLE_INCLUDE_DIRS}) 100 | -target_link_libraries(testclient ${WSLAY_TARGET} ${NETTLE_LIBRARIES}) 101 | +target_include_directories(testclient PRIVATE ${NETTLE_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIRS}) 102 | +target_link_libraries(testclient ${WSLAY_TARGET} ${NETTLE_LIBRARIES} ${MBEDTLS_LIBRARIES}) 103 | diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt 104 | index 25e637d..ba24310 100644 105 | --- a/lib/CMakeLists.txt 106 | +++ b/lib/CMakeLists.txt 107 | @@ -6,9 +6,9 @@ cmake_minimum_required(VERSION 2.8) 108 | 109 | set(PACKAGE_VERSION "1.0.1-DEV") 110 | set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/includes) 111 | -set(GEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/includes) 112 | +set(GEN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/includes) 113 | 114 | -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -pedantic-errors -Wno-long-long") 115 | +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wno-long-long") 116 | 117 | include(CheckIncludeFile) 118 | include(TestBigEndian) 119 | diff --git a/lib/wslay_net.h b/lib/wslay_net.h 120 | index 2310870..43aa065 100644 121 | --- a/lib/wslay_net.h 122 | +++ b/lib/wslay_net.h 123 | @@ -34,6 +34,14 @@ 124 | #ifdef HAVE_ARPA_INET_H 125 | # include 126 | #endif /* HAVE_ARPA_INET_H */ 127 | + 128 | +#include 129 | +#define htons(x) lwip_htons(x) 130 | +#define ntohs(x) lwip_ntohs(x) 131 | +#define htonl(x) lwip_htonl(x) 132 | +#define ntohl(x) lwip_ntohl(x) 133 | + 134 | + 135 | #ifdef HAVE_NETINET_IN_H 136 | # include 137 | #endif /* HAVE_NETINET_IN_H */ 138 | -- 139 | 2.17.1 140 | 141 | -------------------------------------------------------------------------------- /webrtc_example.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap 3 | nvs, data, nvs, 0x9000, 0x6000, 4 | phy_init, data, phy, 0xf000, 0x1000, 5 | factory, app, factory, 0x10000, 2M, 6 | --------------------------------------------------------------------------------