├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── Readme Files ├── AppIcon.png ├── EASessionConnected.png ├── ServerStarted.png ├── Start.png ├── TCPConnected.png └── USBConnected.png ├── Relay.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── Relay ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ ├── 120-1.png │ ├── 120.png │ ├── 180.png │ ├── 58.png │ ├── 80.png │ ├── 87.png │ └── Contents.json ├── Contents.json ├── Logging_Icon.imageset │ ├── Contents.json │ └── text_20x20@2x.png └── Settings_Icon.imageset │ ├── Contents.json │ └── profile_20x20@2x.png ├── Base.lproj └── LaunchScreen.storyboard ├── EASession+Streams.h ├── EASession+Streams.m ├── Info.plist ├── Main.storyboard ├── NSObject+Notifications.h ├── NSObject+Notifications.m ├── NSStream+Connection.h ├── NSStream+Connection.m ├── SDLLabel.h ├── SDLLabel.m ├── SDLRelayManager.h ├── SDLRelayManager.m ├── SDLStatusViewController.h ├── SDLStatusViewController.m ├── SDLTCPConnection.h ├── SDLTCPConnection.m ├── SDLTCPServer.h ├── SDLTCPServer.m ├── SDLiAPManager.h ├── SDLiAPManager.m └── main.m /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | [Delete any non-applicable sections, but we may ask for more information.] 2 | 3 | ### Bug Report 4 | [Summary] 5 | 6 | ##### Reproduction Steps 7 | 1. [Step 1] 8 | 2. [Step 2] 9 | 3. [Step 3] 10 | 11 | ##### Expected Behavior 12 | [Some expected behavior] 13 | 14 | ##### Observed Behavior 15 | [Some observed behavior] 16 | 17 | ##### OS & Version Information 18 | * iOS Version: [What version of iOS are you using when the bug occurred] 19 | * SDL iOS Version: [What version of the library has this bug been seen on] 20 | * Testing Against: [What you tested with to observe this behavior] 21 | 22 | ##### Test Case, Sample Code, and / or Example App 23 | [Paste a link to a PR, gist, or other code that exemplifies this behavior] 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # OS generated files # 21 | ###################### 22 | .DS_Store 23 | .DS_Store? 24 | ._* 25 | .Spotlight-V100 26 | .Trashes 27 | Icon? 28 | ehthumbs.db 29 | Thumbs.db 30 | 31 | # OS X temporary files # 32 | ######################## 33 | *.swp 34 | *.lock 35 | profile 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0 Release Notes 2 | * Initial Commit 3 | 4 | # 1.0.1 Release Notes 5 | * Fixed issue that caused an application to not be able to reconnect after disconnect. 6 | * Fixed issue where in certain circumstances the relay would crash. 7 | 8 | # 1.0.2 Release Notes 9 | * Fixed issue that caused the relay to go into a "Connecting…" EASession state after SDL disconnected. 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to SDL Projects 2 | 3 | Third party contributions are essential for making SDL great. However, we do have a few guidelines we need contributors to follow. 4 | 5 | ### Issues 6 | If writing a bug report, please make sure it has enough info. Include all relevant information. 7 | 8 | If requesting a feature, understand that we appreciate the input! However, it may not immediately fit our roadmap, and it may take a while for us to get to your request. 9 | 10 | ### Gitflow 11 | We use Gitflow as our branch management system. Please follow gitflow's guidelines while contributing to any SDL project. 12 | 13 | ### Pull Requests 14 | * Please follow the repository's for all code and documentation. 15 | * All feature branches should be based on `develop` and have the format `feature/branch_name`. 16 | * Minor bug fixes, that is bug fixes that do not change, add, or remove any public API, should be based on `master` and have the format `hotfix/branch_name`. 17 | * All pull requests should implement a single feature or fix a single bug. Pull Requests that involve multiple changes (it is our discretion what precisely this means) will be rejected with a reason. 18 | * All commits should separated into logical units, i.e. unrelated changes should be in different commits within a pull request. 19 | * Work in progress pull requests should have "[WIP]" in front of the Pull Request title. When you believe the pull request is ready to merge, remove this tag and @mention the appropriate SDL team to schedule a review. 20 | * All new code *must* include unit tests. Bug fixes should have a test that fails previously and now passes. All new features should be covered. If your code does not have tests, or regresses old tests, it will be rejected. 21 | * A great example of a pull request can be found here. 22 | 23 | ### Contributor's License Agreement (CLA) 24 | In order to accept Pull Requests from contributors, you must first sign [the Contributor's License Agreement](https://docs.google.com/forms/d/1VNR8EUd5b46cQ7uNbCq1fJmnu0askNpUp5dudLKRGpU/viewform). If you need to make a change to information that you entered, [please contact us](mailto:justin@livio.io). 25 | 26 | ### Repository Specific Guidelines 27 | * iOS Style Guide 28 | * Please document all code written using [Objective-C style documentation](http://nshipster.com/documentation/) for methods (we use [VVDocumenter](https://github.com/onevcat/VVDocumenter-Xcode) for methods and use inline code comments where it makes sense, i.e. for non-obvious code chunks. 29 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | [Delete any non-applicable sections, but we may ask for more information.] 2 | 3 | ### Bug Report 4 | [Summary] 5 | 6 | ##### Reproduction Steps 7 | 1. [Step 1] 8 | 1. [Step 2] 9 | 1. [Step 3] 10 | 11 | ##### Expected Behavior 12 | [Some expected behavior] 13 | 14 | ##### Observed Behavior 15 | [Some observed behavior] 16 | 17 | ##### OS & Version Information 18 | * Relay Device's iOS Version: [What version of iOS is the Relay app running on when the bug occurred] 19 | * Relay Version: [What version of Relay App] 20 | * App's SDL Version: [What version of the library has this bug been seen on] 21 | * Testing Against: [What you tested with to observe this behavior] 22 | 23 | ##### Test Case, Sample Code, and / or Example App 24 | [Paste a link to a PR, gist, or other code that exemplifies this behavior] 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 SmartDeviceLink Consortium, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of SmartDeviceLink Consortium, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes #[issue number] 2 | 3 | This PR is **[ready / not ready]** for review. 4 | 5 | ### Risk 6 | This PR makes **[no / minor / major]** API changes. 7 | 8 | ### Testing Plan 9 | [Describe how you plan to unit test the changes in this PR] 10 | 11 | ### Summary 12 | [Summary of PR changes] 13 | 14 | ### Changelog 15 | ##### Breaking Changes 16 | * [Breaking change info] 17 | 18 | ##### Enchancements 19 | * [Enchancement info] 20 | 21 | ##### Bug Fixes 22 | * [Bug Fix Info] 23 | 24 | ### Tasks Remaining: 25 | - [ ] [Task 1] 26 | - [ ] [Task 2] 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![logo](https://github.com/smartdevicelink/relay_app_ios/blob/master/Readme%20Files/AppIcon.png) 2 | # SmartDeviceLink (SDL) iOS Relay 3 | 4 | SDL iOS Relay is a tool built for developers building applications 5 | that utilizes SmartDeviceLink for connecting their apps to technologies using 6 | our [SmartDeviceLink Core](https://github.com/smartdevicelink/sdl_core) connected 7 | via USB. This tool allows those developers to test their applications over a TCP/IP connection, allowing developers to easily see debug logs to make development faster 8 | and easier. 9 | 10 | ### Things To Note 11 | - Make sure that both SDL iOS Relay and your app are connected to the 12 | **same** wifi network. 13 | 14 | 15 | ## Relay Status 16 | 17 | #### Start 18 | 19 | > Initial app startup. This state is visible when the app is not connected to 20 | hardware running SDL Core via USB. 21 | 22 | #### USB Connected 23 | 24 | > When Relay is initially connected via USB, but the connection isn't complete. 25 | 26 | #### EASession Connected 27 | 28 | > When the Relay is fully connected via USB, and ready for server start. 29 | 30 | #### Relay started 31 | 32 | > Server is now started, and awating connection. 33 | 34 | 35 | #### Connected to Relay 36 | 37 | > Application is correctly connected to Relay, and messages can 38 | now be sent and received. 39 | 40 | ## How To Start Testing Using Relay 41 | 42 | > ###### For all documentation purposes, we will be using our [SDL iOS Library](https://github.com/smartdevicelink/sdl_ios) for code snippets. 43 | 44 | To get started, please be sure to use the proxy builder's [TCP/IP initializer](https://github.com/smartdevicelink/sdl_ios/blob/master/SmartDeviceLink-iOS/SmartDeviceLink/SDLProxyFactory.h#L16). 45 | ```objective-c 46 | SDLProxy* proxy = [SDLProxyFactory buildSDLProxyWithListener:sdlProxyListenerDelegate 47 | tcpIPAddress:@"1.2.3.4" 48 | port:@"2776"]; 49 | ``` 50 | > NOTE: Be sure to start the Relay app **before** connecting your application to it. 51 | 52 | ## Need Help? 53 | If you need general assistance, or have other questions, you can [sign up](http://slack.smartdevicelink.org/) for the [SDL Slack](https://smartdevicelink.slack.com/) and chat with other developers and the maintainers of the project. 54 | 55 | ## Found a Bug? 56 | If you see a bug, feel free to [post an issue](https://github.com/smartdevicelink/relay_app_ios/issues/new). Please see the [contribution guidelines](https://github.com/smartdevicelink/relay_app_ios/blob/master/CONTRIBUTING.md) before proceeding. 57 | 58 | ## Want to Help? 59 | If you want to help add more features, please [file a pull request](https://github.com/smartdevicelink/relay_app_ios/compare). Please see the [contribution guidelines](https://github.com/smartdevicelink/relay_app_ios/blob/master/CONTRIBUTING.md) before proceeding. 60 | -------------------------------------------------------------------------------- /Readme Files/AppIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Readme Files/AppIcon.png -------------------------------------------------------------------------------- /Readme Files/EASessionConnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Readme Files/EASessionConnected.png -------------------------------------------------------------------------------- /Readme Files/ServerStarted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Readme Files/ServerStarted.png -------------------------------------------------------------------------------- /Readme Files/Start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Readme Files/Start.png -------------------------------------------------------------------------------- /Readme Files/TCPConnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Readme Files/TCPConnected.png -------------------------------------------------------------------------------- /Readme Files/USBConnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Readme Files/USBConnected.png -------------------------------------------------------------------------------- /Relay.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1A8553C61BE833AC00312347 /* SDLStatusViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8553C41BE833AC00312347 /* SDLStatusViewController.m */; }; 11 | 1A8553CF1BE833C900312347 /* SDLTCPServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8553CE1BE833C900312347 /* SDLTCPServer.m */; }; 12 | 1A8553D21BE833D000312347 /* SDLiAPManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8553D11BE833D000312347 /* SDLiAPManager.m */; }; 13 | 1A8553D51BE833E400312347 /* SDLRelayManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8553D41BE833E400312347 /* SDLRelayManager.m */; }; 14 | 1AEDDD631BE2824800ACCCA6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDDD621BE2824800ACCCA6 /* main.m */; }; 15 | 1AEDDD661BE2824800ACCCA6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDDD651BE2824800ACCCA6 /* AppDelegate.m */; }; 16 | 1AEDDD6E1BE2824800ACCCA6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1AEDDD6D1BE2824800ACCCA6 /* Assets.xcassets */; }; 17 | 1AEDDD711BE2824800ACCCA6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AEDDD6F1BE2824800ACCCA6 /* LaunchScreen.storyboard */; }; 18 | DA9EAE2C1C193C8000697E06 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA9EAE2B1C193C8000697E06 /* Main.storyboard */; }; 19 | DA9EAE331C1959EA00697E06 /* SDLLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9EAE321C1959EA00697E06 /* SDLLabel.m */; }; 20 | DAD0ACF51C8790F90060A411 /* SDLTCPConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD0ACF41C8790F90060A411 /* SDLTCPConnection.m */; }; 21 | DAD0ACFD1C87DE3F0060A411 /* NSStream+Connection.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD0ACFC1C87DE3F0060A411 /* NSStream+Connection.m */; }; 22 | DAD0AD001C87DE470060A411 /* EASession+Streams.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD0ACFF1C87DE470060A411 /* EASession+Streams.m */; }; 23 | DAD0AD041C89060C0060A411 /* NSObject+Notifications.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD0AD031C89060C0060A411 /* NSObject+Notifications.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 1A8553C31BE833AC00312347 /* SDLStatusViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStatusViewController.h; sourceTree = ""; }; 28 | 1A8553C41BE833AC00312347 /* SDLStatusViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStatusViewController.m; sourceTree = ""; }; 29 | 1A8553CD1BE833C900312347 /* SDLTCPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLTCPServer.h; sourceTree = ""; }; 30 | 1A8553CE1BE833C900312347 /* SDLTCPServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLTCPServer.m; sourceTree = ""; }; 31 | 1A8553D01BE833D000312347 /* SDLiAPManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLiAPManager.h; sourceTree = ""; }; 32 | 1A8553D11BE833D000312347 /* SDLiAPManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLiAPManager.m; sourceTree = ""; }; 33 | 1A8553D31BE833E400312347 /* SDLRelayManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLRelayManager.h; sourceTree = ""; }; 34 | 1A8553D41BE833E400312347 /* SDLRelayManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRelayManager.m; sourceTree = ""; }; 35 | 1AEDDD5E1BE2824800ACCCA6 /* Relay.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Relay.app; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 1AEDDD621BE2824800ACCCA6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 37 | 1AEDDD641BE2824800ACCCA6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 38 | 1AEDDD651BE2824800ACCCA6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 39 | 1AEDDD6D1BE2824800ACCCA6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 40 | 1AEDDD701BE2824800ACCCA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 41 | 1AEDDD721BE2824800ACCCA6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | DA9EAE2B1C193C8000697E06 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 43 | DA9EAE311C1959EA00697E06 /* SDLLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLabel.h; sourceTree = ""; }; 44 | DA9EAE321C1959EA00697E06 /* SDLLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLabel.m; sourceTree = ""; }; 45 | DAD0ACF31C8790F90060A411 /* SDLTCPConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLTCPConnection.h; sourceTree = ""; }; 46 | DAD0ACF41C8790F90060A411 /* SDLTCPConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLTCPConnection.m; sourceTree = ""; }; 47 | DAD0ACFB1C87DE3F0060A411 /* NSStream+Connection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSStream+Connection.h"; sourceTree = ""; }; 48 | DAD0ACFC1C87DE3F0060A411 /* NSStream+Connection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSStream+Connection.m"; sourceTree = ""; }; 49 | DAD0ACFE1C87DE470060A411 /* EASession+Streams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EASession+Streams.h"; sourceTree = ""; }; 50 | DAD0ACFF1C87DE470060A411 /* EASession+Streams.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EASession+Streams.m"; sourceTree = ""; }; 51 | DAD0AD021C89060C0060A411 /* NSObject+Notifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Notifications.h"; sourceTree = ""; }; 52 | DAD0AD031C89060C0060A411 /* NSObject+Notifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Notifications.m"; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 1AEDDD5B1BE2824800ACCCA6 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 1ABE50361BE95805006394EF /* ViewControllers */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 1A8553C31BE833AC00312347 /* SDLStatusViewController.h */, 70 | 1A8553C41BE833AC00312347 /* SDLStatusViewController.m */, 71 | ); 72 | name = ViewControllers; 73 | sourceTree = ""; 74 | }; 75 | 1AEDDD551BE2824800ACCCA6 = { 76 | isa = PBXGroup; 77 | children = ( 78 | 1AEDDD601BE2824800ACCCA6 /* Relay */, 79 | 1AEDDD5F1BE2824800ACCCA6 /* Products */, 80 | ); 81 | sourceTree = ""; 82 | }; 83 | 1AEDDD5F1BE2824800ACCCA6 /* Products */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 1AEDDD5E1BE2824800ACCCA6 /* Relay.app */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | 1AEDDD601BE2824800ACCCA6 /* Relay */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | DAD0ACFA1C87DE370060A411 /* Categories */, 95 | 1AEDDD641BE2824800ACCCA6 /* AppDelegate.h */, 96 | 1AEDDD651BE2824800ACCCA6 /* AppDelegate.m */, 97 | DAD0ACF31C8790F90060A411 /* SDLTCPConnection.h */, 98 | DAD0ACF41C8790F90060A411 /* SDLTCPConnection.m */, 99 | 1A8553CD1BE833C900312347 /* SDLTCPServer.h */, 100 | 1A8553CE1BE833C900312347 /* SDLTCPServer.m */, 101 | 1A8553D01BE833D000312347 /* SDLiAPManager.h */, 102 | 1A8553D11BE833D000312347 /* SDLiAPManager.m */, 103 | 1A8553D31BE833E400312347 /* SDLRelayManager.h */, 104 | 1A8553D41BE833E400312347 /* SDLRelayManager.m */, 105 | DA9EAE301C1959DD00697E06 /* Views */, 106 | 1ABE50361BE95805006394EF /* ViewControllers */, 107 | 1AEDDD611BE2824800ACCCA6 /* Supporting Files */, 108 | ); 109 | path = Relay; 110 | sourceTree = ""; 111 | }; 112 | 1AEDDD611BE2824800ACCCA6 /* Supporting Files */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 1AEDDD6D1BE2824800ACCCA6 /* Assets.xcassets */, 116 | 1AEDDD6F1BE2824800ACCCA6 /* LaunchScreen.storyboard */, 117 | DA9EAE2B1C193C8000697E06 /* Main.storyboard */, 118 | 1AEDDD721BE2824800ACCCA6 /* Info.plist */, 119 | 1AEDDD621BE2824800ACCCA6 /* main.m */, 120 | ); 121 | name = "Supporting Files"; 122 | sourceTree = ""; 123 | }; 124 | DA9EAE301C1959DD00697E06 /* Views */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | DA9EAE311C1959EA00697E06 /* SDLLabel.h */, 128 | DA9EAE321C1959EA00697E06 /* SDLLabel.m */, 129 | ); 130 | name = Views; 131 | sourceTree = ""; 132 | }; 133 | DAD0ACFA1C87DE370060A411 /* Categories */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | DAD0ACFE1C87DE470060A411 /* EASession+Streams.h */, 137 | DAD0ACFF1C87DE470060A411 /* EASession+Streams.m */, 138 | DAD0ACFB1C87DE3F0060A411 /* NSStream+Connection.h */, 139 | DAD0ACFC1C87DE3F0060A411 /* NSStream+Connection.m */, 140 | DAD0AD021C89060C0060A411 /* NSObject+Notifications.h */, 141 | DAD0AD031C89060C0060A411 /* NSObject+Notifications.m */, 142 | ); 143 | name = Categories; 144 | sourceTree = ""; 145 | }; 146 | /* End PBXGroup section */ 147 | 148 | /* Begin PBXNativeTarget section */ 149 | 1AEDDD5D1BE2824800ACCCA6 /* Relay */ = { 150 | isa = PBXNativeTarget; 151 | buildConfigurationList = 1AEDDD751BE2824800ACCCA6 /* Build configuration list for PBXNativeTarget "Relay" */; 152 | buildPhases = ( 153 | 1AEDDD5A1BE2824800ACCCA6 /* Sources */, 154 | 1AEDDD5B1BE2824800ACCCA6 /* Frameworks */, 155 | 1AEDDD5C1BE2824800ACCCA6 /* Resources */, 156 | ); 157 | buildRules = ( 158 | ); 159 | dependencies = ( 160 | ); 161 | name = Relay; 162 | productName = Relay; 163 | productReference = 1AEDDD5E1BE2824800ACCCA6 /* Relay.app */; 164 | productType = "com.apple.product-type.application"; 165 | }; 166 | /* End PBXNativeTarget section */ 167 | 168 | /* Begin PBXProject section */ 169 | 1AEDDD561BE2824800ACCCA6 /* Project object */ = { 170 | isa = PBXProject; 171 | attributes = { 172 | LastUpgradeCheck = 0710; 173 | ORGANIZATIONNAME = "Ford Motor Company"; 174 | TargetAttributes = { 175 | 1AEDDD5D1BE2824800ACCCA6 = { 176 | CreatedOnToolsVersion = 7.1; 177 | }; 178 | }; 179 | }; 180 | buildConfigurationList = 1AEDDD591BE2824800ACCCA6 /* Build configuration list for PBXProject "Relay" */; 181 | compatibilityVersion = "Xcode 3.2"; 182 | developmentRegion = English; 183 | hasScannedForEncodings = 0; 184 | knownRegions = ( 185 | en, 186 | Base, 187 | ); 188 | mainGroup = 1AEDDD551BE2824800ACCCA6; 189 | productRefGroup = 1AEDDD5F1BE2824800ACCCA6 /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | 1AEDDD5D1BE2824800ACCCA6 /* Relay */, 194 | ); 195 | }; 196 | /* End PBXProject section */ 197 | 198 | /* Begin PBXResourcesBuildPhase section */ 199 | 1AEDDD5C1BE2824800ACCCA6 /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | DA9EAE2C1C193C8000697E06 /* Main.storyboard in Resources */, 204 | 1AEDDD711BE2824800ACCCA6 /* LaunchScreen.storyboard in Resources */, 205 | 1AEDDD6E1BE2824800ACCCA6 /* Assets.xcassets in Resources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXResourcesBuildPhase section */ 210 | 211 | /* Begin PBXSourcesBuildPhase section */ 212 | 1AEDDD5A1BE2824800ACCCA6 /* Sources */ = { 213 | isa = PBXSourcesBuildPhase; 214 | buildActionMask = 2147483647; 215 | files = ( 216 | DA9EAE331C1959EA00697E06 /* SDLLabel.m in Sources */, 217 | DAD0ACFD1C87DE3F0060A411 /* NSStream+Connection.m in Sources */, 218 | 1A8553C61BE833AC00312347 /* SDLStatusViewController.m in Sources */, 219 | 1A8553D21BE833D000312347 /* SDLiAPManager.m in Sources */, 220 | 1A8553CF1BE833C900312347 /* SDLTCPServer.m in Sources */, 221 | DAD0AD041C89060C0060A411 /* NSObject+Notifications.m in Sources */, 222 | 1AEDDD661BE2824800ACCCA6 /* AppDelegate.m in Sources */, 223 | 1A8553D51BE833E400312347 /* SDLRelayManager.m in Sources */, 224 | 1AEDDD631BE2824800ACCCA6 /* main.m in Sources */, 225 | DAD0AD001C87DE470060A411 /* EASession+Streams.m in Sources */, 226 | DAD0ACF51C8790F90060A411 /* SDLTCPConnection.m in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXSourcesBuildPhase section */ 231 | 232 | /* Begin PBXVariantGroup section */ 233 | 1AEDDD6F1BE2824800ACCCA6 /* LaunchScreen.storyboard */ = { 234 | isa = PBXVariantGroup; 235 | children = ( 236 | 1AEDDD701BE2824800ACCCA6 /* Base */, 237 | ); 238 | name = LaunchScreen.storyboard; 239 | sourceTree = ""; 240 | }; 241 | /* End PBXVariantGroup section */ 242 | 243 | /* Begin XCBuildConfiguration section */ 244 | 1AEDDD731BE2824800ACCCA6 /* Debug */ = { 245 | isa = XCBuildConfiguration; 246 | buildSettings = { 247 | ALWAYS_SEARCH_USER_PATHS = NO; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_ENABLE_MODULES = YES; 251 | CLANG_ENABLE_OBJC_ARC = YES; 252 | CLANG_WARN_BOOL_CONVERSION = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_EMPTY_BODY = YES; 256 | CLANG_WARN_ENUM_CONVERSION = YES; 257 | CLANG_WARN_INT_CONVERSION = YES; 258 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 259 | CLANG_WARN_UNREACHABLE_CODE = YES; 260 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 261 | CODE_SIGN_IDENTITY = "iPhone Developer: James Sokoll (VQ4272R23R)"; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: James Sokoll (VQ4272R23R)"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_STRICT_OBJC_MSGSEND = YES; 266 | ENABLE_TESTABILITY = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_DYNAMIC_NO_PIC = NO; 269 | GCC_NO_COMMON_BLOCKS = YES; 270 | GCC_OPTIMIZATION_LEVEL = 0; 271 | GCC_PREPROCESSOR_DEFINITIONS = ( 272 | "DEBUG=1", 273 | "$(inherited)", 274 | ); 275 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 276 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 277 | GCC_WARN_UNDECLARED_SELECTOR = YES; 278 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 279 | GCC_WARN_UNUSED_FUNCTION = YES; 280 | GCC_WARN_UNUSED_VARIABLE = YES; 281 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 282 | MTL_ENABLE_DEBUG_INFO = YES; 283 | ONLY_ACTIVE_ARCH = YES; 284 | SDKROOT = iphoneos; 285 | STRIP_INSTALLED_PRODUCT = NO; 286 | STRIP_STYLE = debugging; 287 | }; 288 | name = Debug; 289 | }; 290 | 1AEDDD741BE2824800ACCCA6 /* Release */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | ALWAYS_SEARCH_USER_PATHS = NO; 294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 295 | CLANG_CXX_LIBRARY = "libc++"; 296 | CLANG_ENABLE_MODULES = YES; 297 | CLANG_ENABLE_OBJC_ARC = YES; 298 | CLANG_WARN_BOOL_CONVERSION = YES; 299 | CLANG_WARN_CONSTANT_CONVERSION = YES; 300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 301 | CLANG_WARN_EMPTY_BODY = YES; 302 | CLANG_WARN_ENUM_CONVERSION = YES; 303 | CLANG_WARN_INT_CONVERSION = YES; 304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 305 | CLANG_WARN_UNREACHABLE_CODE = YES; 306 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 307 | CODE_SIGN_IDENTITY = "iPhone Developer: James Sokoll (VQ4272R23R)"; 308 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: James Sokoll (VQ4272R23R)"; 309 | COPY_PHASE_STRIP = NO; 310 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 311 | ENABLE_NS_ASSERTIONS = NO; 312 | ENABLE_STRICT_OBJC_MSGSEND = YES; 313 | GCC_C_LANGUAGE_STANDARD = gnu99; 314 | GCC_NO_COMMON_BLOCKS = YES; 315 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 316 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 317 | GCC_WARN_UNDECLARED_SELECTOR = YES; 318 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 319 | GCC_WARN_UNUSED_FUNCTION = YES; 320 | GCC_WARN_UNUSED_VARIABLE = YES; 321 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 322 | MTL_ENABLE_DEBUG_INFO = NO; 323 | SDKROOT = iphoneos; 324 | STRIP_INSTALLED_PRODUCT = NO; 325 | STRIP_STYLE = debugging; 326 | VALIDATE_PRODUCT = YES; 327 | }; 328 | name = Release; 329 | }; 330 | 1AEDDD761BE2824800ACCCA6 /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 334 | CODE_SIGN_IDENTITY = "iPhone Developer"; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | INFOPLIST_FILE = Relay/Info.plist; 338 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 339 | PRODUCT_BUNDLE_IDENTIFIER = com.sdl.relay; 340 | PRODUCT_NAME = "$(TARGET_NAME)"; 341 | PROVISIONING_PROFILE = ""; 342 | STRIP_INSTALLED_PRODUCT = NO; 343 | STRIP_STYLE = debugging; 344 | }; 345 | name = Debug; 346 | }; 347 | 1AEDDD771BE2824800ACCCA6 /* Release */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 351 | CODE_SIGN_IDENTITY = "iPhone Developer"; 352 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 353 | COPY_PHASE_STRIP = NO; 354 | INFOPLIST_FILE = Relay/Info.plist; 355 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 356 | PRODUCT_BUNDLE_IDENTIFIER = com.sdl.relay; 357 | PRODUCT_NAME = "$(TARGET_NAME)"; 358 | PROVISIONING_PROFILE = ""; 359 | STRIP_INSTALLED_PRODUCT = NO; 360 | STRIP_STYLE = debugging; 361 | }; 362 | name = Release; 363 | }; 364 | /* End XCBuildConfiguration section */ 365 | 366 | /* Begin XCConfigurationList section */ 367 | 1AEDDD591BE2824800ACCCA6 /* Build configuration list for PBXProject "Relay" */ = { 368 | isa = XCConfigurationList; 369 | buildConfigurations = ( 370 | 1AEDDD731BE2824800ACCCA6 /* Debug */, 371 | 1AEDDD741BE2824800ACCCA6 /* Release */, 372 | ); 373 | defaultConfigurationIsVisible = 0; 374 | defaultConfigurationName = Release; 375 | }; 376 | 1AEDDD751BE2824800ACCCA6 /* Build configuration list for PBXNativeTarget "Relay" */ = { 377 | isa = XCConfigurationList; 378 | buildConfigurations = ( 379 | 1AEDDD761BE2824800ACCCA6 /* Debug */, 380 | 1AEDDD771BE2824800ACCCA6 /* Release */, 381 | ); 382 | defaultConfigurationIsVisible = 0; 383 | defaultConfigurationName = Release; 384 | }; 385 | /* End XCConfigurationList section */ 386 | }; 387 | rootObject = 1AEDDD561BE2824800ACCCA6 /* Project object */; 388 | } 389 | -------------------------------------------------------------------------------- /Relay.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Relay/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | @interface AppDelegate : UIResponder 9 | 10 | @property (strong, nonatomic) UIWindow *window; 11 | 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /Relay/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Relay 4 | // 5 | 6 | #import "AppDelegate.h" 7 | 8 | @interface AppDelegate () 9 | 10 | @end 11 | 12 | @implementation AppDelegate 13 | 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 16 | [UIApplication sharedApplication].idleTimerDisabled = YES; 17 | 18 | return YES; 19 | } 20 | 21 | - (void)applicationWillResignActive:(UIApplication *)application { 22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 24 | } 25 | 26 | - (void)applicationDidEnterBackground:(UIApplication *)application { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application { 32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 33 | } 34 | 35 | - (void)applicationDidBecomeActive:(UIApplication *)application { 36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 37 | } 38 | 39 | - (void)applicationWillTerminate:(UIApplication *)application { 40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/AppIcon.appiconset/120-1.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "58.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "87.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "80.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "120-1.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "120.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "180.png", 37 | "scale" : "3x" 38 | } 39 | ], 40 | "info" : { 41 | "version" : 1, 42 | "author" : "xcode" 43 | } 44 | } -------------------------------------------------------------------------------- /Relay/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Relay/Assets.xcassets/Logging_Icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "text_20x20@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Relay/Assets.xcassets/Logging_Icon.imageset/text_20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/Logging_Icon.imageset/text_20x20@2x.png -------------------------------------------------------------------------------- /Relay/Assets.xcassets/Settings_Icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "profile_20x20@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Relay/Assets.xcassets/Settings_Icon.imageset/profile_20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartdevicelink/relay_app_ios/263d60a56e87f99d7ffb563cb38888695a61d881/Relay/Assets.xcassets/Settings_Icon.imageset/profile_20x20@2x.png -------------------------------------------------------------------------------- /Relay/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Relay/EASession+Streams.h: -------------------------------------------------------------------------------- 1 | // 2 | // EASession+Streams.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | @interface EASession (Streams) 9 | 10 | /** 11 | * Convenience method that opens both input and output streams, sets their delegates, and 12 | * adds them to the currentRunLoop. 13 | * 14 | * @param delegate Delegate that will respond to NSStream's delegate notifications. 15 | */ 16 | - (void)openStreamsWithDelegate:(id)delegate; 17 | 18 | /** 19 | * Convenience method that closes both input and output streams, sets their delegates to 20 | * nil, and removes them from the currentRunLoop. 21 | */ 22 | - (void)closeStreams; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Relay/EASession+Streams.m: -------------------------------------------------------------------------------- 1 | // 2 | // EASession+Streams.m 3 | // Relay 4 | // 5 | 6 | #import "EASession+Streams.h" 7 | #import "NSStream+Connection.h" 8 | 9 | @implementation EASession (Streams) 10 | 11 | - (void)openStreamsWithDelegate:(id)delegate { 12 | [self.inputStream openStreamWithDelegate:delegate]; 13 | [self.outputStream openStreamWithDelegate:delegate]; 14 | } 15 | 16 | - (void)closeStreams { 17 | [self.inputStream closeStream]; 18 | [self.outputStream closeStream]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Relay/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIBackgroundModes 26 | 27 | external-accessory 28 | 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedExternalAccessoryProtocols 38 | 39 | com.ford.sync.prot0 40 | com.smartdevicelink.prot0 41 | com.smartdevicelink.prot1 42 | com.smartdevicelink.prot2 43 | com.smartdevicelink.prot3 44 | com.smartdevicelink.prot4 45 | com.smartdevicelink.prot5 46 | com.smartdevicelink.prot6 47 | com.smartdevicelink.prot7 48 | com.smartdevicelink.prot8 49 | com.smartdevicelink.prot9 50 | com.smartdevicelink.prot10 51 | com.smartdevicelink.prot11 52 | com.smartdevicelink.prot12 53 | com.smartdevicelink.prot13 54 | com.smartdevicelink.prot14 55 | com.smartdevicelink.prot15 56 | com.smartdevicelink.prot16 57 | com.smartdevicelink.prot17 58 | com.smartdevicelink.prot18 59 | com.smartdevicelink.prot19 60 | com.smartdevicelink.prot20 61 | com.smartdevicelink.prot21 62 | com.smartdevicelink.prot22 63 | com.smartdevicelink.prot23 64 | com.smartdevicelink.prot24 65 | com.smartdevicelink.prot25 66 | com.smartdevicelink.prot26 67 | com.smartdevicelink.prot27 68 | com.smartdevicelink.prot28 69 | com.smartdevicelink.prot29 70 | 71 | UISupportedInterfaceOrientations 72 | 73 | UIInterfaceOrientationPortrait 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Relay/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 38 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 62 | 68 | 74 | 80 | 86 | 92 | 98 | 104 | 110 | 116 | 122 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /Relay/NSObject+Notifications.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Notifications.h 3 | // Relay 4 | // 5 | // Created by Muller, Alexander (A.) on 3/3/16. 6 | // Copyright © 2016 Ford Motor Company. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Notifications) 12 | 13 | - (void)addSelfObserverForNotificationNamed:(NSString *)name selector:(SEL)selector; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Relay/NSObject+Notifications.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Notifications.m 3 | // Relay 4 | // 5 | // Created by Muller, Alexander (A.) on 3/3/16. 6 | // Copyright © 2016 Ford Motor Company. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Notifications.h" 10 | 11 | @implementation NSObject (Notifications) 12 | 13 | - (void)addSelfObserverForNotificationNamed:(NSString *)name selector:(SEL)selector { 14 | [[NSNotificationCenter defaultCenter] addObserver:self 15 | selector:selector 16 | name:name 17 | object:nil]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Relay/NSStream+Connection.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSStream+Connection.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | @interface NSStream (Connection) 9 | 10 | /** 11 | * Convenience method that opens the stream, sets it's delegate, and adds it to the 12 | * currentRunLoop. 13 | * 14 | * @param delegate Delegate that will respond to NSStream's delegate notifications. 15 | */ 16 | - (void)openStreamWithDelegate:(id)delegate; 17 | 18 | /** 19 | * Convenience method that closes the stream, sets it's delegate to nil, and removes it 20 | * from the currentRunLoop. 21 | */ 22 | - (void)closeStream; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Relay/NSStream+Connection.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSStream+Connection.m 3 | // Relay 4 | // 5 | 6 | #import "NSStream+Connection.h" 7 | 8 | @implementation NSStream (Connection) 9 | 10 | - (void)openStreamWithDelegate:(id)delegate { 11 | [self setDelegate:delegate]; 12 | [self scheduleInRunLoop:[NSRunLoop currentRunLoop] 13 | forMode:NSDefaultRunLoopMode]; 14 | [self open]; 15 | 16 | } 17 | 18 | - (void)closeStream { 19 | [self setDelegate:nil]; 20 | [self close]; 21 | [self removeFromRunLoop:[NSRunLoop currentRunLoop] 22 | forMode:NSDefaultRunLoopMode]; 23 | 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Relay/SDLLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDLLabel.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | typedef NS_ENUM(NSUInteger, SDLLabelState) { 9 | SDLLabelStateNone, 10 | SDLLabelStateError, 11 | SDLLabelStateSuccess, 12 | SDLLabelStateWaiting 13 | }; 14 | 15 | @interface SDLLabel : UILabel 16 | 17 | @property (nonatomic, readonly) SDLLabelState currentState; 18 | 19 | - (void)updateToErrorStateWithString:(NSString *)string; 20 | - (void)updateToNoStateWithString:(NSString *)string; 21 | - (void)updateToSuccessStateWithString:(NSString *)string; 22 | - (void)updateToWaitingStateWithString:(NSString *)string; 23 | - (void)updateToState:(SDLLabelState)newState withString:(NSString *)string; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Relay/SDLLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDLLabel.m 3 | // Relay 4 | // 5 | 6 | #import "SDLLabel.h" 7 | 8 | #define FLAT_COLOR_BLACK [UIColor colorWithRed:(34 / 255.0) green:(49 / 255.0) blue:(63 / 255.0) alpha:1.0f] 9 | #define FLAT_COLOR_GREEN [UIColor colorWithRed:(38 / 255.0) green:(166 / 255.0) blue:(91 / 255.0) alpha:1.0f] 10 | #define FLAT_COLOR_ORANGE [UIColor colorWithRed:(249 / 255.0) green:(105 / 255.0) blue:(14 / 255.0) alpha:1.0f] 11 | #define FLAT_COLOR_RED [UIColor colorWithRed:(217 / 255.0) green:(30 / 255.0) blue:(24 / 255.0) alpha:1.0f] 12 | 13 | 14 | @implementation SDLLabel { 15 | BOOL _hasUpdatedOnce; 16 | } 17 | 18 | - (void)setText:(NSString *)text { 19 | if (_currentState == SDLLabelStateNone && !_hasUpdatedOnce) { 20 | self.textColor = FLAT_COLOR_BLACK; 21 | } 22 | if (!_hasUpdatedOnce) { 23 | _hasUpdatedOnce = YES; 24 | } 25 | [super setText:text]; 26 | } 27 | 28 | - (void)updateToErrorStateWithString:(NSString *)string { 29 | [self updateToState:SDLLabelStateError 30 | withString:string]; 31 | } 32 | 33 | - (void)updateToSuccessStateWithString:(NSString *)string { 34 | [self updateToState:SDLLabelStateSuccess 35 | withString:string]; 36 | } 37 | 38 | - (void)updateToNoStateWithString:(NSString *)string { 39 | [self updateToState:SDLLabelStateNone 40 | withString:string]; 41 | } 42 | 43 | - (void)updateToWaitingStateWithString:(NSString *)string { 44 | [self updateToState:SDLLabelStateWaiting 45 | withString:string]; 46 | } 47 | 48 | 49 | - (void)updateToState:(SDLLabelState)newState withString:(NSString *)string { 50 | self.text = string; 51 | if (_currentState == newState) { 52 | return; 53 | } 54 | 55 | _currentState = newState; 56 | UIColor *newColor = nil; 57 | switch (newState) { 58 | case SDLLabelStateNone: 59 | newColor = FLAT_COLOR_BLACK; 60 | break; 61 | case SDLLabelStateError: 62 | newColor = FLAT_COLOR_RED; 63 | break; 64 | case SDLLabelStateSuccess: 65 | newColor = FLAT_COLOR_GREEN; 66 | break; 67 | case SDLLabelStateWaiting: 68 | newColor = FLAT_COLOR_ORANGE; 69 | break; 70 | default: 71 | break; 72 | } 73 | self.textColor = newColor; 74 | } 75 | 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /Relay/SDLRelayManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDLRelayManager.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | // Notification User Info Key 9 | /** 10 | * User Info key for Notifications. 11 | */ 12 | extern NSString* const SDLNotificationInfoKey; 13 | 14 | /** 15 | * Notification when USB is connected. 16 | */ 17 | extern NSString* const SDLRelayManagerUSBConnectedNotification; 18 | 19 | /** 20 | * Notification when USB is disonnected. 21 | */ 22 | extern NSString* const SDLRelayManagerUSBDisconnectedNotification; 23 | 24 | /** 25 | * Notification when Control Session is established. 26 | */ 27 | extern NSString* const SDLRelayManagerControlSessionEstablishedNotification; 28 | 29 | /** 30 | * Notification when Data Session is established. 31 | */ 32 | extern NSString* const SDLRelayManagerDataSessionEstablishedNotification; 33 | 34 | /** 35 | * Notification when TCP Server has been started. 36 | */ 37 | extern NSString* const SDLRelayManagerTCPServerStartedNotification; 38 | 39 | /** 40 | * Notification when TCP Server is connected. 41 | */ 42 | extern NSString* const SDLRelayManagerTCPServerConnectedNotification; 43 | 44 | /** 45 | * Notification when TCP Server is disconnected. 46 | */ 47 | extern NSString* const SDLRelayManagerTCPServerDisconnectedNotification; 48 | 49 | /** 50 | * Relay manager routes data and updates status' 51 | */ 52 | @interface SDLRelayManager : NSObject 53 | 54 | /** 55 | * Create the RelayManager object 56 | * 57 | * @return Instance of RelayManager 58 | */ 59 | + (instancetype)sharedManager; 60 | 61 | /** 62 | * Start TCP Server. 63 | */ 64 | - (void)startTCPServer; 65 | 66 | /** 67 | * Stop TCP Server. 68 | */ 69 | - (void)stopTCPServer; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Relay/SDLRelayManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDLRelayManager.m 3 | // Relay 4 | // 5 | 6 | #import "SDLRelayManager.h" 7 | #import "SDLiAPManager.h" 8 | #import "SDLTCPServer.h" 9 | 10 | NSString* const SDLNotificationInfoKey = @"SDLNotificationInfoKey"; 11 | 12 | NSString* const SDLRelayManagerUSBConnectedNotification = @"com.smartdevicelink.sdlrelaymanager.usbconnected"; 13 | NSString* const SDLRelayManagerUSBDisconnectedNotification = @"com.smartdevicelink.sdlrelaymanager.usbdisconnected"; 14 | NSString* const SDLRelayManagerControlSessionEstablishedNotification = @"com.smartdevicelink.sdlrelaymanager.controlsessionestablished"; 15 | NSString* const SDLRelayManagerDataSessionEstablishedNotification = @"com.smartdevicelink.sdlrelaymanager.datasessionestablished"; 16 | 17 | NSString* const SDLRelayManagerTCPServerStartedNotification = @"com.smartdevicelink.sdlrelaymanager.tcpserverstarted"; 18 | NSString* const SDLRelayManagerTCPServerConnectedNotification = @"com.smartdevicelink.sdlrelaymanager.tcpserverconnected"; 19 | NSString* const SDLRelayManagerTCPServerDisconnectedNotification = @"com.smartdevicelink.sdlrelaymanager.tcpserverdisconnected"; 20 | 21 | @interface SDLRelayManager () 22 | 23 | @end 24 | 25 | @implementation SDLRelayManager 26 | 27 | + (instancetype)sharedManager { 28 | static SDLRelayManager *sharedManager = nil; 29 | static dispatch_once_t onceToken; 30 | dispatch_once(&onceToken, ^{ 31 | sharedManager = [[SDLRelayManager alloc] init]; 32 | }); 33 | 34 | return sharedManager; 35 | } 36 | 37 | - (instancetype)init { 38 | if (self = [super init]) { 39 | [SDLTCPServer sharedService].delegate = self; 40 | [SDLiAPManager sharedService].delegate = self; 41 | } 42 | 43 | return self; 44 | } 45 | 46 | #pragma mark - Private 47 | - (void)sdl_postNotification:(NSString *)name info:(id)info { 48 | NSDictionary *userInfo = nil; 49 | if (info != nil) { 50 | userInfo = @{ 51 | SDLNotificationInfoKey : info 52 | }; 53 | } 54 | [[NSNotificationCenter defaultCenter] postNotificationName:name 55 | object:self 56 | userInfo:userInfo]; 57 | } 58 | 59 | #pragma mark - Public Functions 60 | - (void)startTCPServer { 61 | [[SDLTCPServer sharedService] startServer]; 62 | } 63 | 64 | - (void)stopTCPServer { 65 | [[SDLTCPServer sharedService] stopServer]; 66 | [[SDLiAPManager sharedService] restartEASession]; 67 | } 68 | 69 | #pragma mark - Delegates 70 | #pragma mark SDLTCPServer 71 | - (void)TCPServer:(SDLTCPServer *)server hasAvailableConnection:(SDLTCPConnection *)connection { 72 | [self sdl_postNotification:SDLRelayManagerTCPServerStartedNotification 73 | info:connection]; 74 | } 75 | 76 | - (void)TCPServerDidConnect:(SDLTCPServer *)server { 77 | [self sdl_postNotification:SDLRelayManagerTCPServerConnectedNotification 78 | info:nil]; 79 | } 80 | 81 | - (void)TCPServerDidDisconnect:(SDLTCPServer *)server { 82 | [[SDLiAPManager sharedService] restartEASession]; 83 | [self sdl_postNotification:SDLRelayManagerTCPServerDisconnectedNotification 84 | info:nil]; 85 | } 86 | 87 | - (void)TCPServer:(SDLTCPServer *)server didReceiveData:(NSData *)data { 88 | [[SDLiAPManager sharedService] sendData:data]; 89 | } 90 | 91 | #pragma mark SDLiAPManager 92 | - (void)iAPManager:(SDLiAPManager *)iAPManager didReceiveData:(NSData *)data { 93 | [[SDLTCPServer sharedService] sendData:data]; 94 | } 95 | 96 | - (void)iAPManagerUSBConnected:(SDLiAPManager *)iAPManager { 97 | [self sdl_postNotification:SDLRelayManagerUSBConnectedNotification 98 | info:nil]; 99 | } 100 | 101 | - (void)iAPManagerUSBDisconnected:(SDLiAPManager *)iAPManager { 102 | [self sdl_postNotification:SDLRelayManagerUSBDisconnectedNotification 103 | info:nil]; 104 | } 105 | 106 | - (void)iAPManagerControlSessionEstablished:(SDLiAPManager *)iAPManager { 107 | [self sdl_postNotification:SDLRelayManagerControlSessionEstablishedNotification 108 | info:nil]; 109 | } 110 | 111 | - (void)iAPManagerDataSessionEstablished:(SDLiAPManager *)iAPManager { 112 | [self sdl_postNotification:SDLRelayManagerDataSessionEstablishedNotification 113 | info:nil]; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Relay/SDLStatusViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDLStatusViewController.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | @interface SDLStatusViewController : UIViewController 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Relay/SDLStatusViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDLStatusViewController.m 3 | // Relay 4 | // 5 | 6 | #import "SDLStatusViewController.h" 7 | #import "SDLRelayManager.h" 8 | #import "SDLTCPConnection.h" 9 | #import "SDLLabel.h" 10 | 11 | #import "NSObject+Notifications.h" 12 | 13 | static NSString* const SDLStatusAvailable = @"Available"; 14 | static NSString* const SDLStatusClosed = @"Closed"; 15 | static NSString* const SDLStatusConnected = @"Connected"; 16 | static NSString* const SDLStatusConnecting = @"Connecting…"; 17 | static NSString* const SDLStatusDisconnected = @"Disconnected"; 18 | static NSString* const SDLStatusError = @"Error"; 19 | static NSString* const SDLStatusNotStarted = @"Not Started"; 20 | 21 | @interface SDLStatusViewController () 22 | 23 | @property (nonatomic, readonly) SDLRelayManager *sharedManager; 24 | 25 | @property (weak) IBOutlet UIScrollView* scrollView; 26 | @property (nonatomic, weak) IBOutlet SDLLabel *usbStatusLabel; 27 | @property (nonatomic, weak) IBOutlet SDLLabel *eaStatusLabel; 28 | @property (nonatomic, weak) IBOutlet SDLLabel *serverStatusLabel; 29 | @property (nonatomic, weak) IBOutlet SDLLabel *serverAddressLabel; 30 | @property (nonatomic, weak) IBOutlet SDLLabel *serverPortLabel; 31 | @property (nonatomic, weak) IBOutlet SDLLabel *sdlStatusLabel; 32 | @property (nonatomic, weak) IBOutlet UISwitch *serverSwitch; 33 | 34 | @end 35 | 36 | @implementation SDLStatusViewController 37 | 38 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 39 | if (self = [super initWithCoder:aDecoder]) { 40 | self.title = @"Status"; 41 | 42 | [self sdl_registerForNotifications]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)viewDidLoad { 48 | [super viewDidLoad]; 49 | 50 | [self usbDisconnected:nil]; 51 | [self tcpServerDisconnected:nil]; 52 | [self serverToggleAction:nil]; 53 | } 54 | 55 | - (void)sdl_registerForNotifications { 56 | [self addSelfObserverForNotificationNamed:SDLRelayManagerUSBConnectedNotification 57 | selector:@selector(usbConnected:)]; 58 | [self addSelfObserverForNotificationNamed:SDLRelayManagerUSBDisconnectedNotification 59 | selector:@selector(usbDisconnected:)]; 60 | [self addSelfObserverForNotificationNamed:SDLRelayManagerDataSessionEstablishedNotification 61 | selector:@selector(dataSessionEstablished:)]; 62 | [self addSelfObserverForNotificationNamed:SDLRelayManagerControlSessionEstablishedNotification 63 | selector:@selector(controlSessionEstablished:)]; 64 | [self addSelfObserverForNotificationNamed:SDLRelayManagerTCPServerStartedNotification 65 | selector:@selector(tcpServerStarted:)]; 66 | [self addSelfObserverForNotificationNamed:SDLRelayManagerTCPServerConnectedNotification 67 | selector:@selector(tcpServerConnected:)]; 68 | [self addSelfObserverForNotificationNamed:SDLRelayManagerTCPServerDisconnectedNotification 69 | selector:@selector(tcpServerDisconnected:)]; 70 | } 71 | 72 | #pragma mark - Actions 73 | - (IBAction)serverToggleAction:(id)selector { 74 | if ([_serverSwitch isOn]) { 75 | [self.relayManager startTCPServer]; 76 | } else { 77 | [self.relayManager stopTCPServer]; 78 | [_serverStatusLabel updateToErrorStateWithString:SDLStatusNotStarted]; 79 | _serverAddressLabel.text = @""; 80 | _serverPortLabel.text = @""; 81 | } 82 | } 83 | 84 | #pragma mark - Notifications 85 | - (void)usbConnected:(NSNotification*)notification { 86 | [_usbStatusLabel updateToSuccessStateWithString:SDLStatusConnected]; 87 | } 88 | 89 | - (void)usbDisconnected:(NSNotification*)notification { 90 | [_usbStatusLabel updateToErrorStateWithString:SDLStatusDisconnected]; 91 | [_eaStatusLabel updateToErrorStateWithString:SDLStatusClosed]; 92 | } 93 | 94 | - (void)controlSessionEstablished:(NSNotification*)notification { 95 | [_eaStatusLabel updateToWaitingStateWithString:SDLStatusConnecting]; 96 | } 97 | 98 | - (void)dataSessionEstablished:(NSNotification*)notification { 99 | [_eaStatusLabel updateToSuccessStateWithString:SDLStatusConnected]; 100 | } 101 | 102 | - (void)tcpServerStarted:(NSNotification *)notification { 103 | NSString* ip = SDLStatusError; 104 | NSString* port = SDLStatusError; 105 | 106 | id notificationObject = notification.userInfo[SDLNotificationInfoKey]; 107 | if ([notificationObject isKindOfClass:[SDLTCPConnection class]]) { 108 | SDLTCPConnection* connection = (SDLTCPConnection*)notificationObject; 109 | ip = connection.ipAddress; 110 | port = [NSString stringWithFormat:@"%lu", (unsigned long)connection.port]; 111 | } 112 | 113 | [_serverStatusLabel updateToSuccessStateWithString:SDLStatusAvailable]; 114 | _serverAddressLabel.text = ip; 115 | _serverPortLabel.text = port; 116 | } 117 | 118 | - (void)tcpServerConnected:(NSNotification *)notification { 119 | [_sdlStatusLabel updateToSuccessStateWithString:SDLStatusConnected]; 120 | } 121 | 122 | - (void)tcpServerDisconnected:(NSNotification *)notification { 123 | [_sdlStatusLabel updateToErrorStateWithString:SDLStatusDisconnected]; 124 | } 125 | 126 | #pragma mark - Private 127 | #pragma mark Getters 128 | - (SDLRelayManager*)relayManager { 129 | return [SDLRelayManager sharedManager]; 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /Relay/SDLTCPConnection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDLTCPConnection.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | /** 9 | * Object to store current connection properties. 10 | */ 11 | @interface SDLTCPConnection : NSObject 12 | 13 | /** 14 | * Convenience initializer for creating a SDLTCPConnection object. This class will retrieve 15 | * the IP Address from the current connected network. 16 | * * 17 | * @return instance of SDLTCPConnection 18 | */ 19 | + (instancetype)connection; 20 | 21 | /** 22 | * The IP Address the connection is using. 23 | */ 24 | @property (nonatomic, readonly) NSString* ipAddress; 25 | 26 | /** 27 | * The port the connection is using. 28 | */ 29 | @property (nonatomic, readonly) NSUInteger port; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Relay/SDLTCPConnection.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDLTCPConnection.m 3 | // Relay 4 | // 5 | 6 | #import "SDLTCPConnection.h" 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | @implementation SDLTCPConnection 13 | 14 | + (instancetype)connection { 15 | return [[SDLTCPConnection alloc] init]; 16 | } 17 | 18 | #pragma mark - Getters 19 | - (NSString*)ipAddress { 20 | NSString *address = @"error"; 21 | struct ifaddrs *interfaces = NULL; 22 | struct ifaddrs *temp_addr = NULL; 23 | int success = 0; 24 | // retrieve the current interfaces - returns 0 on success 25 | success = getifaddrs(&interfaces); 26 | if (success == 0) { 27 | // Loop through linked list of interfaces 28 | temp_addr = interfaces; 29 | while (temp_addr != NULL) { 30 | if (temp_addr->ifa_addr->sa_family == AF_INET) { 31 | // Check if interface is en0 which is the wifi connection on the iPhone 32 | if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { 33 | // Get NSString from C String 34 | address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; 35 | } 36 | } 37 | 38 | temp_addr = temp_addr->ifa_next; 39 | } 40 | } 41 | // Free memory 42 | freeifaddrs(interfaces); 43 | return address; 44 | } 45 | 46 | - (NSUInteger)port { 47 | return 2776; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Relay/SDLTCPServer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDLTCPServer.h 3 | // Relay 4 | // 5 | 6 | #import 7 | #import "SDLTCPConnection.h" 8 | 9 | @class SDLTCPServer; 10 | 11 | /** 12 | * Describes the protocol of a TCPServer delegate. 13 | */ 14 | @protocol SDLTCPServerDelegate 15 | 16 | /** 17 | * Called when TCPServer has data from the client. 18 | * 19 | * @param server Shared SDLTCPServer 20 | * @param data The data to be sent. 21 | */ 22 | - (void)TCPServer:(SDLTCPServer*)server didReceiveData:(NSData*)data; 23 | 24 | /** 25 | * Called when TCPServer has established an available server. 26 | * 27 | * @param server Shared SDLTCPServer 28 | * @param connection Object storing connection information. 29 | */ 30 | - (void)TCPServer:(SDLTCPServer*)server hasAvailableConnection:(SDLTCPConnection*)connection; 31 | 32 | /** 33 | * Called when TCPServer has accepted an incoming connection. 34 | * 35 | * @param server Shared SDLTCPServer 36 | */ 37 | - (void)TCPServerDidConnect:(SDLTCPServer *)server; 38 | 39 | /** 40 | * Called when TCPServer has closed the current connection. 41 | * 42 | * @param server Shared SDLTCPServer 43 | */ 44 | - (void)TCPServerDidDisconnect:(SDLTCPServer *)server; 45 | 46 | @end 47 | 48 | /** 49 | * TCP Server. 50 | */ 51 | @interface SDLTCPServer : NSObject 52 | 53 | /** 54 | * The delegate for TCPServer callbacks. 55 | */ 56 | @property (weak) id delegate; 57 | 58 | /** 59 | * Create the TCPServer object. 60 | * 61 | * @return Singleton instance of SDLTCPServer. 62 | */ 63 | + (instancetype)sharedService; 64 | 65 | /** 66 | * Establish a new server session. 67 | */ 68 | - (void)startServer; 69 | 70 | /** 71 | * Close the current server session. 72 | */ 73 | - (void)stopServer; 74 | 75 | /** 76 | * Sends data to client. 77 | * 78 | * @param data The data to be sent. 79 | */ 80 | - (void)sendData:(NSData*)data; 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /Relay/SDLTCPServer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDLTCPServer.m 3 | // Relay 4 | // 5 | 6 | #import "SDLTCPServer.h" 7 | 8 | #import "NSStream+Connection.h" 9 | 10 | #import 11 | 12 | @interface SDLTCPServer () 13 | 14 | @property (strong, nonatomic) NSInputStream *inputStream; 15 | @property (strong, nonatomic) NSOutputStream *outputStream; 16 | @property CFSocketRef socket; 17 | @property dispatch_queue_t tcpLinkQueue; 18 | 19 | @end 20 | 21 | @implementation SDLTCPServer 22 | 23 | + (instancetype)sharedService { 24 | static SDLTCPServer *sharedService = nil; 25 | static dispatch_once_t onceToken; 26 | dispatch_once(&onceToken, ^{ 27 | sharedService = [[SDLTCPServer alloc] init]; 28 | }); 29 | 30 | return sharedService; 31 | } 32 | 33 | - (instancetype)init { 34 | if (self = [super init]) { 35 | self.tcpLinkQueue = dispatch_queue_create("com.queue.tcpLinkQueue", NULL); 36 | } 37 | 38 | return self; 39 | } 40 | 41 | 42 | #pragma mark Server lifecycle methods 43 | - (void)startServer { 44 | CFSocketContext context = {0, (__bridge void *)self, NULL, NULL, NULL}; 45 | 46 | self.socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, &openConnection, &context); 47 | 48 | SDLTCPConnection* connection = [SDLTCPConnection connection]; 49 | 50 | struct sockaddr_in sin; 51 | 52 | memset(&sin, 0, sizeof(sin)); 53 | sin.sin_len = sizeof(sin); 54 | sin.sin_family = AF_INET; /* address family */ 55 | sin.sin_port = htons(connection.port); 56 | sin.sin_addr.s_addr = INADDR_ANY; 57 | 58 | // allow address/port to be reused after server is closed and restarted 59 | setsockopt(CFSocketGetNative(self.socket), SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); 60 | setsockopt(CFSocketGetNative(self.socket), SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int)); 61 | 62 | CFDataRef sincfd = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&sin, sizeof(sin)); 63 | 64 | CFSocketSetAddress(self.socket, sincfd); 65 | CFRelease(sincfd); 66 | 67 | CFRunLoopSourceRef socketSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.socket, 0); 68 | CFRunLoopAddSource(CFRunLoopGetCurrent(), socketSource, kCFRunLoopDefaultMode); 69 | 70 | [self.delegate TCPServer:self hasAvailableConnection:connection]; 71 | 72 | CFRelease(socketSource); 73 | } 74 | 75 | static void openConnection(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { 76 | CFReadStreamRef readStream; 77 | CFWriteStreamRef writeStream; 78 | 79 | CFSocketNativeHandle *socketNumber = (int *)data; 80 | 81 | CFStreamCreatePairWithSocket(kCFAllocatorDefault, *socketNumber, &readStream, &writeStream); 82 | 83 | SDLTCPServer *weakServer = (__bridge SDLTCPServer *)info; 84 | weakServer.inputStream = (__bridge_transfer NSInputStream *)readStream; 85 | weakServer.outputStream = (__bridge_transfer NSOutputStream *)writeStream; 86 | 87 | [weakServer.inputStream openStreamWithDelegate:weakServer]; 88 | [weakServer.outputStream openStreamWithDelegate:weakServer]; 89 | 90 | [weakServer.delegate TCPServerDidConnect:weakServer]; 91 | } 92 | 93 | - (void)stopServer { 94 | [self.inputStream closeStream]; 95 | [self.outputStream closeStream]; 96 | 97 | if (self.socket) { 98 | CFSocketInvalidate(self.socket); 99 | CFRelease(self.socket); 100 | self.socket = nil; 101 | } 102 | } 103 | 104 | 105 | #pragma mark Handle stream events 106 | 107 | - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { 108 | switch (eventCode) { 109 | case NSStreamEventNone: 110 | case NSStreamEventOpenCompleted: 111 | case NSStreamEventHasSpaceAvailable: 112 | case NSStreamEventErrorOccurred: 113 | // no-op 114 | break; 115 | case NSStreamEventHasBytesAvailable: 116 | [self sdl_processIncomingBytesForStream:aStream]; 117 | break; 118 | case NSStreamEventEndEncountered: 119 | [aStream close]; 120 | [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] 121 | forMode:NSDefaultRunLoopMode]; 122 | [self.delegate TCPServerDidDisconnect:self]; 123 | break; 124 | default: { 125 | break; 126 | } 127 | } 128 | } 129 | 130 | - (void)sdl_processIncomingBytesForStream:(NSStream *)theStream { 131 | uint8_t buf[1024]; 132 | NSInteger len = 0; 133 | len = [(NSInputStream *)theStream read:buf maxLength:1024]; 134 | if (len > 0) { 135 | NSData* data = [NSData dataWithBytes:buf length:len]; 136 | 137 | [self.delegate TCPServer:self didReceiveData:data]; 138 | } 139 | } 140 | 141 | - (void)sendData:(NSData *)data { 142 | dispatch_async(self.tcpLinkQueue, ^{ 143 | NSData *localData = [[NSData alloc] initWithData:data]; 144 | 145 | while (localData != nil) { 146 | if (self.outputStream.hasSpaceAvailable) { 147 | [self.outputStream write:[localData bytes] maxLength:[localData length]]; 148 | localData = nil; 149 | } 150 | } 151 | }); 152 | } 153 | 154 | @end 155 | -------------------------------------------------------------------------------- /Relay/SDLiAPManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDLiAPManager.h 3 | // Relay 4 | // 5 | 6 | #import 7 | 8 | @class SDLiAPManager; 9 | 10 | /** 11 | * Describes the protocol of an SDLiAPManager delegate. 12 | */ 13 | @protocol SDLiAPManagerDelegate 14 | 15 | /** 16 | * Called when SDLiAPManager has connected to an external accessory via USB. 17 | * 18 | * @param iAPManager Shared SDLiAPManager 19 | */ 20 | - (void)iAPManagerUSBConnected:(SDLiAPManager*)manager; 21 | 22 | /** 23 | * Called when SDLiAPManager has disconnected from an external accessory. 24 | * 25 | * @param iAPManager Shared SDLiAPManager 26 | */ 27 | - (void)iAPManagerUSBDisconnected:(SDLiAPManager *)manager; 28 | 29 | /** 30 | * Called when SDLiAPManager has established a control session with a TDK. 31 | * 32 | * @param iAPManager Shared SDLiAPManager 33 | */ 34 | - (void)iAPManagerControlSessionEstablished:(SDLiAPManager*)manager; 35 | 36 | /** 37 | * Called when SDLiAPManager has established a data session with a TDK. 38 | * 39 | * @param iAPManager Shared SDLiAPManager 40 | */ 41 | - (void)iAPManagerDataSessionEstablished:(SDLiAPManager*)manager; 42 | 43 | /** 44 | * Called when SDLiAPManager has data to send to send to the SDL app. 45 | * 46 | * @param iAPManager Shared SDLiAPManager 47 | * @param data The data to be sent. 48 | */ 49 | - (void)iAPManager:(SDLiAPManager*)manager didReceiveData:(NSData*)data; 50 | 51 | @end 52 | 53 | /** 54 | * External Accessory session. 55 | */ 56 | @interface SDLiAPManager : NSObject 57 | 58 | /** 59 | * The delegate for SDLiAPManager callbacks. 60 | */ 61 | @property (weak) id delegate; 62 | 63 | /** 64 | * Create the SDLiAPManager object. 65 | * 66 | * @return Instance of SDLiAPManager. 67 | */ 68 | + (instancetype)sharedService; 69 | 70 | /** 71 | * Called when SDLiAPManager has data to send to a TDK. 72 | * 73 | * @param data The data to be sent. 74 | */ 75 | - (void)sendData:(NSData*)data; 76 | 77 | /** 78 | * Close the current external accessory session, attempt to create a new session. 79 | */ 80 | - (void)restartEASession; 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /Relay/SDLiAPManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDLiAPManager.m 3 | // Relay 4 | // 5 | 6 | #import "SDLiAPManager.h" 7 | 8 | #import "EASession+Streams.h" 9 | #import "NSObject+Notifications.h" 10 | 11 | #import 12 | #import 13 | 14 | static NSString* const ControlProtocolString = @"com.smartdevicelink.prot0"; 15 | static NSString* const IndexedProtocolString = @"com.smartdevicelink.prot%i"; 16 | static NSString* const LegacyProtocolString = @"com.ford.sync.prot0"; 17 | 18 | @interface SDLiAPManager () 19 | 20 | @property BOOL protocolRerouted; 21 | @property (nonatomic, strong) EASession* session; 22 | 23 | @property dispatch_queue_t iAPManagerQueue; 24 | 25 | @end 26 | 27 | @implementation SDLiAPManager 28 | + (instancetype)sharedService { 29 | static SDLiAPManager *sharedService = nil; 30 | static dispatch_once_t onceToken; 31 | dispatch_once(&onceToken, ^{ 32 | sharedService = [[SDLiAPManager alloc] init]; 33 | }); 34 | 35 | return sharedService; 36 | } 37 | 38 | - (instancetype)init { 39 | self = [super init]; 40 | 41 | if (self) { 42 | _protocolRerouted = NO; 43 | 44 | // register for EAAccessory notifications 45 | [self addSelfObserverForNotificationNamed:EAAccessoryDidConnectNotification 46 | selector:@selector(accessoryDidConnect:)]; 47 | [self addSelfObserverForNotificationNamed:EAAccessoryDidDisconnectNotification 48 | selector:@selector(accessoryDidDisconnect:)]; 49 | [[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications]; 50 | 51 | // monitor battery state 52 | [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; 53 | [self addSelfObserverForNotificationNamed:UIDeviceBatteryStateDidChangeNotification 54 | selector:@selector(batteryStateChanged:)]; 55 | 56 | // attempt to connect on app start 57 | [self performSelector:@selector(sdl_connectToEAOnAppStart) withObject:nil afterDelay:2.0]; 58 | 59 | self.iAPManagerQueue = dispatch_queue_create("com.queue.iapManager", NULL); 60 | } 61 | 62 | return self; 63 | } 64 | 65 | #pragma mark - Notifications 66 | - (void)accessoryDidConnect:(NSNotification *)notification { 67 | if (!self.session) { 68 | [self.delegate iAPManagerUSBConnected:self]; 69 | self.session = [self sdl_openSessionForProtocol:ControlProtocolString]; 70 | } 71 | } 72 | 73 | - (void)accessoryDidDisconnect:(NSNotification *)notification { 74 | [self.delegate iAPManagerUSBDisconnected:self]; 75 | [self sdl_closeSession]; 76 | } 77 | 78 | - (void)batteryStateChanged:(NSNotification*)notification { 79 | if ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateUnplugged) { 80 | [self accessoryDidDisconnect:nil]; 81 | self.protocolRerouted = NO; 82 | } else if ([[UIDevice currentDevice] batteryState] != UIDeviceBatteryStateUnplugged 83 | && !self.session) { 84 | [self accessoryDidConnect:nil]; 85 | } 86 | } 87 | 88 | #pragma mark - Public Functions 89 | - (void)sendData:(NSData *)data { 90 | dispatch_async(self.iAPManagerQueue, ^{ 91 | NSData *localData = [[NSData alloc] initWithData:data]; 92 | 93 | while (localData != nil) { 94 | if (self.session.outputStream.hasSpaceAvailable) { 95 | [self.session.outputStream write:[localData bytes] maxLength:[localData length]]; 96 | localData = nil; 97 | } 98 | } 99 | }); 100 | } 101 | 102 | - (void)restartEASession { 103 | if (self.session) { 104 | [self sdl_closeSession]; 105 | } 106 | 107 | 108 | if ([[UIDevice currentDevice] batteryState] != UIDeviceBatteryStateUnplugged && self.session == nil) { 109 | [self accessoryDidConnect:nil]; 110 | } 111 | } 112 | 113 | #pragma mark - Delegates 114 | #pragma mark NSStream 115 | - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { 116 | switch (eventCode) { 117 | case NSStreamEventHasBytesAvailable: 118 | [self sdl_processIncomingBytesForStream:aStream]; 119 | break; 120 | case NSStreamEventEndEncountered: 121 | [aStream close]; 122 | [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 123 | break; 124 | case NSStreamEventNone: 125 | case NSStreamEventOpenCompleted: 126 | case NSStreamEventHasSpaceAvailable: 127 | break; 128 | default: 129 | break; 130 | } 131 | } 132 | 133 | 134 | #pragma mark - Private 135 | #pragma mark Helpers 136 | - (void)sdl_connectToEAOnAppStart { 137 | if ([[UIDevice currentDevice] batteryState] != UIDeviceBatteryStateUnplugged) { 138 | [self accessoryDidConnect:nil]; 139 | } 140 | } 141 | 142 | - (void)sdl_processIncomingBytesForStream:(NSStream *)aStream { 143 | while ([self.session.inputStream hasBytesAvailable]) { 144 | uint8_t buf[1024]; 145 | NSInteger len = 0; 146 | len = [(NSInputStream *)aStream read:buf maxLength:1024]; 147 | 148 | if (len > 0) { 149 | if (self.protocolRerouted) { 150 | NSData* incomingData = [NSData dataWithBytes:buf length:len]; 151 | [self.delegate iAPManager:self didReceiveData:incomingData]; 152 | } else { 153 | NSData *recBytes = [[NSData alloc] initWithBytes:buf length:len]; 154 | int protocol = CFSwapInt32LittleToHost(*(int *)([recBytes bytes])); 155 | NSString *newProtocol = [NSString stringWithFormat:IndexedProtocolString, protocol]; 156 | [self sdl_closeSession]; 157 | self.session = [self sdl_openSessionForProtocol:newProtocol]; 158 | self.protocolRerouted = YES; 159 | } 160 | } 161 | } 162 | } 163 | 164 | - (EASession *)sdl_openSessionForProtocol:(NSString *)protocolString { 165 | NSArray *accessories = [[EAAccessoryManager sharedAccessoryManager] connectedAccessories]; 166 | EAAccessory *accessory = nil; 167 | EASession *session = nil; 168 | 169 | for (EAAccessory *obj in accessories) { 170 | if ([[obj protocolStrings] containsObject:protocolString]) { 171 | accessory = obj; 172 | break; 173 | } else { 174 | if ([[obj protocolStrings] containsObject:LegacyProtocolString] && ![[obj protocolStrings] containsObject:ControlProtocolString]) { 175 | protocolString = LegacyProtocolString; 176 | self.protocolRerouted = YES; 177 | accessory = obj; 178 | break; 179 | } 180 | } 181 | } 182 | 183 | if (accessory) { 184 | session = [[EASession alloc] initWithAccessory:accessory 185 | forProtocol:protocolString]; 186 | 187 | if (session) { 188 | [session openStreamsWithDelegate:self]; 189 | if ([protocolString isEqualToString:ControlProtocolString]) { 190 | [self.delegate iAPManagerControlSessionEstablished:self]; 191 | } else { 192 | [self.delegate iAPManagerDataSessionEstablished:self]; 193 | } 194 | } 195 | } 196 | 197 | accessory = nil; 198 | 199 | return session; 200 | } 201 | 202 | - (void)sdl_closeSession { 203 | [self.session closeStreams]; 204 | 205 | _protocolRerouted = NO; 206 | self.session = nil; 207 | } 208 | 209 | @end 210 | -------------------------------------------------------------------------------- /Relay/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Relay 4 | // 5 | // Created by James Sokoll on 10/29/15. 6 | // Copyright © 2016 Ford Motor Company. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------