summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2017-08-15 17:25:15 -0400
committerJoel Fischer <joeljfischer@gmail.com>2017-08-15 17:25:15 -0400
commit4687b311f77c532065a603a66e9e56f091070613 (patch)
tree79f896004b38b266387783c4dee22017f827fd08
parent9e30d1878c2b292bed2261a353d8c7b4a3952f8d (diff)
parent7aea81eaa08665dc656effa519f064ce72976270 (diff)
downloadsdl_ios-4687b311f77c532065a603a66e9e56f091070613.tar.gz
Merge branch 'release/5.0.0' into feature/SDL_0075_OEM_specific_HID_support_5.0
# Conflicts: # SmartDeviceLink-iOS.xcodeproj/project.pbxproj
-rw-r--r--.gitmodules3
-rw-r--r--Cartfile.resolved4
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj276
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.xcworkspace/xcshareddata/SmartDeviceLink-iOS.xcscmblueprint30
-rw-r--r--SmartDeviceLink/SDLAbstractProtocol.h14
-rw-r--r--SmartDeviceLink/SDLAbstractProtocol.m10
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.h24
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.m81
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadConstants.h21
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadConstants.m21
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadEndService.h24
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadEndService.m81
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadNak.h25
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadNak.m100
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadRPCStartService.h24
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadRPCStartService.m83
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.h30
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.m103
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadType.h20
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadVideoStartService.h36
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadVideoStartService.m114
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h40
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m119
-rw-r--r--SmartDeviceLink/SDLError.h1
-rw-r--r--SmartDeviceLink/SDLError.m11
-rw-r--r--SmartDeviceLink/SDLErrorConstants.h4
-rw-r--r--SmartDeviceLink/SDLFile.h9
-rw-r--r--SmartDeviceLink/SDLFile.m39
-rw-r--r--SmartDeviceLink/SDLGlobals.h17
-rw-r--r--SmartDeviceLink/SDLGlobals.m67
-rw-r--r--SmartDeviceLink/SDLIAPTransport.m4
-rw-r--r--SmartDeviceLink/SDLProtocol.h8
-rw-r--r--SmartDeviceLink/SDLProtocol.m162
-rw-r--r--SmartDeviceLink/SDLProtocolHeader.h1
-rw-r--r--SmartDeviceLink/SDLProtocolHeader.m16
-rw-r--r--SmartDeviceLink/SDLProtocolListener.h17
-rw-r--r--SmartDeviceLink/SDLProtocolMessage.h4
-rw-r--r--SmartDeviceLink/SDLProtocolMessage.m43
-rw-r--r--SmartDeviceLink/SDLProtocolReceivedMessageRouter.m27
-rw-r--r--SmartDeviceLink/SDLProxy.m4
-rw-r--r--SmartDeviceLink/SDLUploadFileOperation.h3
-rw-r--r--SmartDeviceLink/SDLUploadFileOperation.m235
-rw-r--r--SmartDeviceLink/SDLV2ProtocolHeader.m2
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m12
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFileSpec.m49
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m357
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadNakSpec.m57
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadVideoStartServiceSpec.m80
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFrameVideoStartServiceAckSpec.m86
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m12
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolMessageSpec.m12
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m14
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadAudioStartServiceAckSpec.m60
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadEndServiceSpec.m58
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceAckSpec.m71
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceSpec.m60
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolMessageDisassemblerSpec.m4
-rw-r--r--SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m2
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m14
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m3
-rw-r--r--SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h11
-rw-r--r--SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m8
-rw-r--r--SmartDeviceLinkTests/UtilitiesSpecs/SDLGlobalsSpec.m107
-rw-r--r--SmartDeviceLink_Example/Base.lproj/LaunchScreen.xib12
m---------bson_c_lib0
65 files changed, 2667 insertions, 379 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..684da2889
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "bson_c_lib"]
+ path = bson_c_lib
+ url = https://github.com/smartdevicelink/bson_c_lib.git
diff --git a/Cartfile.resolved b/Cartfile.resolved
index 2de645370..d4d301910 100644
--- a/Cartfile.resolved
+++ b/Cartfile.resolved
@@ -1,5 +1,5 @@
-github "Quick/Nimble" "v6.1.0"
github "AliSoftware/OHHTTPStubs" "5.2.3-swift3"
+github "Quick/Nimble" "v6.1.0"
github "Quick/Quick" "v1.1.0"
-github "facebook/ios-snapshot-test-case" "2.1.4"
github "erikdoe/ocmock" "v3.4"
+github "facebook/ios-snapshot-test-case" "2.1.4"
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 9fdabcba2..0bcbdfa58 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -285,6 +285,13 @@
5D43466F1E6F55BD00B639C6 /* SDLLogManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D43466E1E6F55BD00B639C6 /* SDLLogManagerSpec.m */; };
5D4346731E6F617D00B639C6 /* TestLogTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4346721E6F617D00B639C6 /* TestLogTarget.m */; };
5D4346861E771B5700B639C6 /* SDLLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D4346851E771B5700B639C6 /* SDLLog.swift */; };
+ 5D4631041F2120A30092EFDC /* SDLControlFramePayloadType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4631031F2120A30092EFDC /* SDLControlFramePayloadType.h */; };
+ 5D4631081F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4631061F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.h */; };
+ 5D4631091F21261B0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4631071F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.m */; };
+ 5D4631101F2135850092EFDC /* SDLControlFramePayloadConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D46310E1F2135850092EFDC /* SDLControlFramePayloadConstants.h */; };
+ 5D4631111F2135850092EFDC /* SDLControlFramePayloadConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D46310F1F2135850092EFDC /* SDLControlFramePayloadConstants.m */; };
+ 5D4631141F2136B60092EFDC /* SDLControlFramePayloadNak.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4631121F2136B60092EFDC /* SDLControlFramePayloadNak.h */; };
+ 5D4631151F2136B60092EFDC /* SDLControlFramePayloadNak.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4631131F2136B60092EFDC /* SDLControlFramePayloadNak.m */; };
5D48329D1A8EA33D00252386 /* Preferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D48329C1A8EA33D00252386 /* Preferences.m */; };
5D4832A11A92868E00252386 /* ProxyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4832A01A92868E00252386 /* ProxyManager.m */; };
5D4832A51A94F90D00252386 /* ConnectionTransitionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4832A41A94F90D00252386 /* ConnectionTransitionContext.m */; };
@@ -828,6 +835,15 @@
5D9F50811BE7E6E300FEF399 /* SDLPermissionsManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9F50801BE7E6E300FEF399 /* SDLPermissionsManagerSpec.m */; };
5D9F50831BEA5C6100FEF399 /* SDLFileManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9F50821BEA5C6100FEF399 /* SDLFileManagerSpec.m */; };
5D9F50871BED412E00FEF399 /* TestConnectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9F50861BED412E00FEF399 /* TestConnectionManager.m */; };
+ 5D9FDA8F1F2A7D3400A495C8 /* bson_array.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA891F2A7D3400A495C8 /* bson_array.c */; };
+ 5D9FDA901F2A7D3400A495C8 /* bson_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA8A1F2A7D3400A495C8 /* bson_array.h */; };
+ 5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA8B1F2A7D3400A495C8 /* bson_object.c */; };
+ 5D9FDA921F2A7D3400A495C8 /* bson_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA8C1F2A7D3400A495C8 /* bson_object.h */; };
+ 5D9FDA931F2A7D3400A495C8 /* bson_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA8D1F2A7D3400A495C8 /* bson_util.c */; };
+ 5D9FDA941F2A7D3400A495C8 /* bson_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */; };
+ 5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA951F2A7D3F00A495C8 /* emhashmap.c */; };
+ 5D9FDA991F2A7D3F00A495C8 /* emhashmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA961F2A7D3F00A495C8 /* emhashmap.h */; };
+ 5D9FDA9A1F2A7D3F00A495C8 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 5D9FDA971F2A7D3F00A495C8 /* LICENSE */; };
5DA026901AD44EE700019F86 /* SDLDialNumberResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA0268F1AD44EE700019F86 /* SDLDialNumberResponseSpec.m */; };
5DA102A41D4122C700C15826 /* NSMutableDictionary+SafeRemove.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA102A21D4122C700C15826 /* NSMutableDictionary+SafeRemove.h */; };
5DA102A51D4122C700C15826 /* NSMutableDictionary+SafeRemove.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA102A31D4122C700C15826 /* NSMutableDictionary+SafeRemove.m */; };
@@ -840,6 +856,10 @@
5DA22CBD1D075DE800245F5F /* OHHTTPStubs.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5DA22CB51D075CF200245F5F /* OHHTTPStubs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5DA22CBE1D075DE800245F5F /* Quick.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5DA22CB61D075CF200245F5F /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5DA22CBF1D075DEC00245F5F /* SmartDeviceLink.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5D61FA1C1A84237100846EE7 /* SmartDeviceLink.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 5DA23FF01F2FA0FF009C0313 /* SDLControlFramePayloadEndServiceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FEF1F2FA0FF009C0313 /* SDLControlFramePayloadEndServiceSpec.m */; };
+ 5DA23FF31F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FF21F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m */; };
+ 5DA23FF61F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FF51F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m */; };
+ 5DA23FF81F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FF71F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m */; };
5DA3F3541BC448060026F2D0 /* NSMapTable+Subscripting.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA3F3521BC448060026F2D0 /* NSMapTable+Subscripting.h */; };
5DA3F3551BC448060026F2D0 /* NSMapTable+Subscripting.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA3F3531BC448060026F2D0 /* NSMapTable+Subscripting.m */; };
5DA3F35A1BC448480026F2D0 /* SDLError.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA3F3581BC448480026F2D0 /* SDLError.h */; };
@@ -848,6 +868,8 @@
5DA3F3601BC448590026F2D0 /* SDLNotificationConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA3F35E1BC448590026F2D0 /* SDLNotificationConstants.m */; };
5DA3F3701BC4489A0026F2D0 /* SDLManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA3F36E1BC4489A0026F2D0 /* SDLManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
5DA3F3711BC4489A0026F2D0 /* SDLManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA3F36F1BC4489A0026F2D0 /* SDLManager.m */; };
+ 5DA49CE51F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA49CE31F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h */; };
+ 5DA49CE61F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA49CE41F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m */; };
5DAE06731BDEC6C000F9B498 /* SDLFileSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAE06721BDEC6C000F9B498 /* SDLFileSpec.m */; };
5DAE06751BDEC6D600F9B498 /* SDLArtworkSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAE06741BDEC6D600F9B498 /* SDLArtworkSpec.m */; };
5DB1BCD31D243A8E002FFC37 /* SDLDeleteFileOperationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB1BCD01D243A8E002FFC37 /* SDLDeleteFileOperationSpec.m */; };
@@ -864,6 +886,14 @@
5DB92D2F1AC59F0000C15BB0 /* SDLObjectWithPrioritySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB92D2E1AC59F0000C15BB0 /* SDLObjectWithPrioritySpec.m */; };
5DB92D321AC9C8BA00C15BB0 /* SDLRPCStruct.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB92D301AC9C8BA00C15BB0 /* SDLRPCStruct.h */; settings = {ATTRIBUTES = (Public, ); }; };
5DB92D331AC9C8BA00C15BB0 /* SDLRPCStruct.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB92D311AC9C8BA00C15BB0 /* SDLRPCStruct.m */; };
+ 5DB9964E1F26886C002D8795 /* SDLControlFramePayloadEndService.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB9964C1F26886C002D8795 /* SDLControlFramePayloadEndService.h */; };
+ 5DB9964F1F26886C002D8795 /* SDLControlFramePayloadEndService.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB9964D1F26886C002D8795 /* SDLControlFramePayloadEndService.m */; };
+ 5DB996571F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB996551F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.h */; };
+ 5DB996581F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB996561F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m */; };
+ 5DB9965C1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB9965A1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.h */; };
+ 5DB9965D1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB9965B1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m */; };
+ 5DB996601F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB9965E1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h */; };
+ 5DB996611F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */; };
5DBAE0AB1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */; };
5DBAE0AD1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */; };
5DBF06231E64A83F00A5CF03 /* SDLLogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06211E64A83F00A5CF03 /* SDLLogManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -878,6 +908,9 @@
5DBF06351E64A9FE00A5CF03 /* SDLLogConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06331E64A9FE00A5CF03 /* SDLLogConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
5DBF06391E64ABBE00A5CF03 /* SDLLogConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06371E64ABBE00A5CF03 /* SDLLogConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
5DBF063A1E64ABBE00A5CF03 /* SDLLogConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF06381E64ABBE00A5CF03 /* SDLLogConfiguration.m */; };
+ 5DBF0D5E1F3A68C0008AF2C9 /* SDLControlFramePayloadVideoStartServiceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF0D5D1F3A68C0008AF2C9 /* SDLControlFramePayloadVideoStartServiceSpec.m */; };
+ 5DBF0D601F3B3DB4008AF2C9 /* SDLControlFrameVideoStartServiceAckSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF0D5F1F3B3DB4008AF2C9 /* SDLControlFrameVideoStartServiceAckSpec.m */; };
+ 5DC09EDA1F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DC09ED91F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m */; };
5DC978261B7A38640012C2F1 /* SDLGlobalsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DC978251B7A38640012C2F1 /* SDLGlobalsSpec.m */; };
5DCF76F51ACDBAD300BB647B /* SDLSendLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DCF76F31ACDBAD300BB647B /* SDLSendLocation.h */; settings = {ATTRIBUTES = (Public, ); }; };
5DCF76F61ACDBAD300BB647B /* SDLSendLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF76F41ACDBAD300BB647B /* SDLSendLocation.m */; };
@@ -1352,6 +1385,13 @@
5D4346711E6F617D00B639C6 /* TestLogTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestLogTarget.h; path = LoggingSpecs/TestLogTarget.h; sourceTree = "<group>"; };
5D4346721E6F617D00B639C6 /* TestLogTarget.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestLogTarget.m; path = LoggingSpecs/TestLogTarget.m; sourceTree = "<group>"; };
5D4346851E771B5700B639C6 /* SDLLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDLLog.swift; sourceTree = "<group>"; };
+ 5D4631031F2120A30092EFDC /* SDLControlFramePayloadType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadType.h; sourceTree = "<group>"; };
+ 5D4631061F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadRPCStartServiceAck.h; sourceTree = "<group>"; };
+ 5D4631071F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartServiceAck.m; sourceTree = "<group>"; };
+ 5D46310E1F2135850092EFDC /* SDLControlFramePayloadConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadConstants.h; sourceTree = "<group>"; };
+ 5D46310F1F2135850092EFDC /* SDLControlFramePayloadConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadConstants.m; sourceTree = "<group>"; };
+ 5D4631121F2136B60092EFDC /* SDLControlFramePayloadNak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadNak.h; sourceTree = "<group>"; };
+ 5D4631131F2136B60092EFDC /* SDLControlFramePayloadNak.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadNak.m; sourceTree = "<group>"; };
5D48329B1A8EA33D00252386 /* Preferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Preferences.h; path = SmartDeviceLink_Example/Classes/Preferences.h; sourceTree = SOURCE_ROOT; };
5D48329C1A8EA33D00252386 /* Preferences.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Preferences.m; path = SmartDeviceLink_Example/Classes/Preferences.m; sourceTree = SOURCE_ROOT; };
5D48329F1A92868E00252386 /* ProxyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProxyManager.h; path = SmartDeviceLink_Example/Classes/ProxyManager.h; sourceTree = SOURCE_ROOT; };
@@ -1909,6 +1949,15 @@
5D9F50821BEA5C6100FEF399 /* SDLFileManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFileManagerSpec.m; path = DevAPISpecs/SDLFileManagerSpec.m; sourceTree = "<group>"; };
5D9F50851BED412E00FEF399 /* TestConnectionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestConnectionManager.h; path = TestUtilities/TestConnectionManager.h; sourceTree = "<group>"; };
5D9F50861BED412E00FEF399 /* TestConnectionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestConnectionManager.m; path = TestUtilities/TestConnectionManager.m; sourceTree = "<group>"; };
+ 5D9FDA891F2A7D3400A495C8 /* bson_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_array.c; path = bson_c_lib/src/bson_array.c; sourceTree = SOURCE_ROOT; };
+ 5D9FDA8A1F2A7D3400A495C8 /* bson_array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_array.h; path = bson_c_lib/src/bson_array.h; sourceTree = SOURCE_ROOT; };
+ 5D9FDA8B1F2A7D3400A495C8 /* bson_object.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_object.c; path = bson_c_lib/src/bson_object.c; sourceTree = SOURCE_ROOT; };
+ 5D9FDA8C1F2A7D3400A495C8 /* bson_object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_object.h; path = bson_c_lib/src/bson_object.h; sourceTree = SOURCE_ROOT; };
+ 5D9FDA8D1F2A7D3400A495C8 /* bson_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_util.c; path = bson_c_lib/src/bson_util.c; sourceTree = SOURCE_ROOT; };
+ 5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_util.h; path = bson_c_lib/src/bson_util.h; sourceTree = SOURCE_ROOT; };
+ 5D9FDA951F2A7D3F00A495C8 /* emhashmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = emhashmap.c; path = bson_c_lib/src/emhashmap/emhashmap.c; sourceTree = SOURCE_ROOT; };
+ 5D9FDA961F2A7D3F00A495C8 /* emhashmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = emhashmap.h; path = bson_c_lib/src/emhashmap/emhashmap.h; sourceTree = SOURCE_ROOT; };
+ 5D9FDA971F2A7D3F00A495C8 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = bson_c_lib/src/emhashmap/LICENSE; sourceTree = SOURCE_ROOT; };
5DA0268F1AD44EE700019F86 /* SDLDialNumberResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDialNumberResponseSpec.m; sourceTree = "<group>"; };
5DA102A21D4122C700C15826 /* NSMutableDictionary+SafeRemove.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+SafeRemove.h"; sourceTree = "<group>"; };
5DA102A31D4122C700C15826 /* NSMutableDictionary+SafeRemove.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+SafeRemove.m"; sourceTree = "<group>"; };
@@ -1916,6 +1965,10 @@
5DA22CB41D075CF200245F5F /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = sdl_ios/Carthage/Build/iOS/OCMock.framework; sourceTree = "<group>"; };
5DA22CB51D075CF200245F5F /* OHHTTPStubs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OHHTTPStubs.framework; path = sdl_ios/Carthage/Build/iOS/OHHTTPStubs.framework; sourceTree = "<group>"; };
5DA22CB61D075CF200245F5F /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = sdl_ios/Carthage/Build/iOS/Quick.framework; sourceTree = "<group>"; };
+ 5DA23FEF1F2FA0FF009C0313 /* SDLControlFramePayloadEndServiceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadEndServiceSpec.m; sourceTree = "<group>"; };
+ 5DA23FF21F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadAudioStartServiceAckSpec.m; sourceTree = "<group>"; };
+ 5DA23FF51F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartServiceSpec.m; sourceTree = "<group>"; };
+ 5DA23FF71F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartServiceAckSpec.m; sourceTree = "<group>"; };
5DA3F3521BC448060026F2D0 /* NSMapTable+Subscripting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMapTable+Subscripting.h"; sourceTree = "<group>"; };
5DA3F3531BC448060026F2D0 /* NSMapTable+Subscripting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMapTable+Subscripting.m"; sourceTree = "<group>"; };
5DA3F3581BC448480026F2D0 /* SDLError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLError.h; sourceTree = "<group>"; };
@@ -1924,6 +1977,8 @@
5DA3F35E1BC448590026F2D0 /* SDLNotificationConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLNotificationConstants.m; sourceTree = "<group>"; };
5DA3F36E1BC4489A0026F2D0 /* SDLManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLManager.h; sourceTree = "<group>"; };
5DA3F36F1BC4489A0026F2D0 /* SDLManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLManager.m; sourceTree = "<group>"; };
+ 5DA49CE31F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadRPCStartService.h; sourceTree = "<group>"; };
+ 5DA49CE41F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartService.m; sourceTree = "<group>"; };
5DAE06721BDEC6C000F9B498 /* SDLFileSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFileSpec.m; path = DevAPISpecs/SDLFileSpec.m; sourceTree = "<group>"; };
5DAE06741BDEC6D600F9B498 /* SDLArtworkSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLArtworkSpec.m; path = DevAPISpecs/SDLArtworkSpec.m; sourceTree = "<group>"; };
5DB1BCD01D243A8E002FFC37 /* SDLDeleteFileOperationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLDeleteFileOperationSpec.m; path = DevAPISpecs/SDLDeleteFileOperationSpec.m; sourceTree = "<group>"; };
@@ -1941,6 +1996,14 @@
5DB92D2E1AC59F0000C15BB0 /* SDLObjectWithPrioritySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLObjectWithPrioritySpec.m; path = "UtilitiesSpecs/Prioritized Objects/SDLObjectWithPrioritySpec.m"; sourceTree = "<group>"; };
5DB92D301AC9C8BA00C15BB0 /* SDLRPCStruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLRPCStruct.h; sourceTree = "<group>"; };
5DB92D311AC9C8BA00C15BB0 /* SDLRPCStruct.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRPCStruct.m; sourceTree = "<group>"; };
+ 5DB9964C1F26886C002D8795 /* SDLControlFramePayloadEndService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadEndService.h; sourceTree = "<group>"; };
+ 5DB9964D1F26886C002D8795 /* SDLControlFramePayloadEndService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadEndService.m; sourceTree = "<group>"; };
+ 5DB996551F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadAudioStartServiceAck.h; sourceTree = "<group>"; };
+ 5DB996561F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadAudioStartServiceAck.m; sourceTree = "<group>"; };
+ 5DB9965A1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadVideoStartService.h; sourceTree = "<group>"; };
+ 5DB9965B1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartService.m; sourceTree = "<group>"; };
+ 5DB9965E1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadVideoStartServiceAck.h; sourceTree = "<group>"; };
+ 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartServiceAck.m; sourceTree = "<group>"; };
5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLNotificationDispatcherSpec.m; path = DevAPISpecs/SDLNotificationDispatcherSpec.m; sourceTree = "<group>"; };
5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLResponseDispatcherSpec.m; path = DevAPISpecs/SDLResponseDispatcherSpec.m; sourceTree = "<group>"; };
5DBF06211E64A83F00A5CF03 /* SDLLogManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLogManager.h; sourceTree = "<group>"; };
@@ -1955,6 +2018,9 @@
5DBF06331E64A9FE00A5CF03 /* SDLLogConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLogConstants.h; sourceTree = "<group>"; };
5DBF06371E64ABBE00A5CF03 /* SDLLogConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLogConfiguration.h; sourceTree = "<group>"; };
5DBF06381E64ABBE00A5CF03 /* SDLLogConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLogConfiguration.m; sourceTree = "<group>"; };
+ 5DBF0D5D1F3A68C0008AF2C9 /* SDLControlFramePayloadVideoStartServiceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLControlFramePayloadVideoStartServiceSpec.m; path = ControlFramePayloadSpecs/SDLControlFramePayloadVideoStartServiceSpec.m; sourceTree = "<group>"; };
+ 5DBF0D5F1F3B3DB4008AF2C9 /* SDLControlFrameVideoStartServiceAckSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLControlFrameVideoStartServiceAckSpec.m; path = ControlFramePayloadSpecs/SDLControlFrameVideoStartServiceAckSpec.m; sourceTree = "<group>"; };
+ 5DC09ED91F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLControlFramePayloadNakSpec.m; path = ControlFramePayloadSpecs/SDLControlFramePayloadNakSpec.m; sourceTree = "<group>"; };
5DC978251B7A38640012C2F1 /* SDLGlobalsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLGlobalsSpec.m; path = UtilitiesSpecs/SDLGlobalsSpec.m; sourceTree = "<group>"; };
5DCA93821EE0844D0015768E /* SmartDeviceLink.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = SmartDeviceLink.podspec; sourceTree = SOURCE_ROOT; };
5DCF76F31ACDBAD300BB647B /* SDLSendLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLSendLocation.h; sourceTree = "<group>"; };
@@ -2436,6 +2502,7 @@
1680B1041A9CD7AD00DBD79E /* ProtocolSpecs */ = {
isa = PBXGroup;
children = (
+ 5DC09ED71F2F7F1A00F4AB1D /* Control Frame Payloads */,
1680B1051A9CD7AD00DBD79E /* HeaderSpecs */,
1680B1091A9CD7AD00DBD79E /* MessageSpecs */,
1680B10E1A9CD7AD00DBD79E /* SDLAbstractProtocolSpec.m */,
@@ -2627,6 +2694,36 @@
name = Mocks;
sourceTree = "<group>";
};
+ 5D4631051F2125F70092EFDC /* @protocols */ = {
+ isa = PBXGroup;
+ children = (
+ 5D4631031F2120A30092EFDC /* SDLControlFramePayloadType.h */,
+ );
+ name = "@protocols";
+ sourceTree = "<group>";
+ };
+ 5D46310D1F2133940092EFDC /* RPC Service */ = {
+ isa = PBXGroup;
+ children = (
+ 5DA49CE31F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h */,
+ 5DA49CE41F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m */,
+ 5D4631061F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.h */,
+ 5D4631071F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.m */,
+ );
+ name = "RPC Service";
+ sourceTree = "<group>";
+ };
+ 5D4631161F223DEE0092EFDC /* General */ = {
+ isa = PBXGroup;
+ children = (
+ 5D4631121F2136B60092EFDC /* SDLControlFramePayloadNak.h */,
+ 5D4631131F2136B60092EFDC /* SDLControlFramePayloadNak.m */,
+ 5DB9964C1F26886C002D8795 /* SDLControlFramePayloadEndService.h */,
+ 5DB9964D1F26886C002D8795 /* SDLControlFramePayloadEndService.m */,
+ );
+ name = General;
+ sourceTree = "<group>";
+ };
5D4832991A8EA27200252386 /* Storyboards */ = {
isa = PBXGroup;
children = (
@@ -2687,6 +2784,7 @@
5D5934EE1A85160900687FB9 /* Protocol */ = {
isa = PBXGroup;
children = (
+ 5DA49C8C1F1E549000E65FC5 /* BSON */,
5D5934FA1A851AC900687FB9 /* @protocols */,
5D5935011A851D7E00687FB9 /* Header */,
5D5935021A851D8700687FB9 /* Message */,
@@ -3359,6 +3457,7 @@
5D5935021A851D8700687FB9 /* Message */ = {
isa = PBXGroup;
children = (
+ 5DA49CE21F1EA77900E65FC5 /* Control Frame Payloads */,
5D61FB5B1A84238B00846EE7 /* SDLProtocolMessage.h */,
5D61FB5C1A84238B00846EE7 /* SDLProtocolMessage.m */,
5D61FC0A1A84238C00846EE7 /* SDLV1ProtocolMessage.h */,
@@ -3634,6 +3733,32 @@
name = Permissions;
sourceTree = "<group>";
};
+ 5DA23FF11F2FA32A009C0313 /* Audio Service */ = {
+ isa = PBXGroup;
+ children = (
+ 5DA23FF21F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m */,
+ );
+ name = "Audio Service";
+ sourceTree = "<group>";
+ };
+ 5DA23FF41F2FAA06009C0313 /* RPC Service */ = {
+ isa = PBXGroup;
+ children = (
+ 5DA23FF51F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m */,
+ 5DA23FF71F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m */,
+ );
+ name = "RPC Service";
+ sourceTree = "<group>";
+ };
+ 5DA23FF91F2FB485009C0313 /* Video Service */ = {
+ isa = PBXGroup;
+ children = (
+ 5DBF0D5D1F3A68C0008AF2C9 /* SDLControlFramePayloadVideoStartServiceSpec.m */,
+ 5DBF0D5F1F3B3DB4008AF2C9 /* SDLControlFrameVideoStartServiceAckSpec.m */,
+ );
+ name = "Video Service";
+ sourceTree = "<group>";
+ };
5DA3F3511BC4477B0026F2D0 /* Developer API */ = {
isa = PBXGroup;
children = (
@@ -3681,6 +3806,52 @@
name = Notifications;
sourceTree = "<group>";
};
+ 5DA3F3611BC448690026F2D0 /* Handler Additions */ = {
+ isa = PBXGroup;
+ children = (
+ 5D6F7A2A1BC45BF70070BF37 /* SDLRequestHandler.h */,
+ );
+ name = "Handler Additions";
+ sourceTree = "<group>";
+ };
+ 5DA49C8C1F1E549000E65FC5 /* BSON */ = {
+ isa = PBXGroup;
+ children = (
+ 5D9FDA891F2A7D3400A495C8 /* bson_array.c */,
+ 5D9FDA8A1F2A7D3400A495C8 /* bson_array.h */,
+ 5D9FDA8B1F2A7D3400A495C8 /* bson_object.c */,
+ 5D9FDA8C1F2A7D3400A495C8 /* bson_object.h */,
+ 5D9FDA8D1F2A7D3400A495C8 /* bson_util.c */,
+ 5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */,
+ 5DA49CB51F1E64BB00E65FC5 /* emhashmap */,
+ );
+ name = BSON;
+ sourceTree = "<group>";
+ };
+ 5DA49CB51F1E64BB00E65FC5 /* emhashmap */ = {
+ isa = PBXGroup;
+ children = (
+ 5D9FDA951F2A7D3F00A495C8 /* emhashmap.c */,
+ 5D9FDA961F2A7D3F00A495C8 /* emhashmap.h */,
+ 5D9FDA971F2A7D3F00A495C8 /* LICENSE */,
+ );
+ name = emhashmap;
+ sourceTree = "<group>";
+ };
+ 5DA49CE21F1EA77900E65FC5 /* Control Frame Payloads */ = {
+ isa = PBXGroup;
+ children = (
+ 5D46310E1F2135850092EFDC /* SDLControlFramePayloadConstants.h */,
+ 5D46310F1F2135850092EFDC /* SDLControlFramePayloadConstants.m */,
+ 5DB996541F268E9D002D8795 /* Audio Service */,
+ 5D4631161F223DEE0092EFDC /* General */,
+ 5D46310D1F2133940092EFDC /* RPC Service */,
+ 5DB996591F268F78002D8795 /* Video Service */,
+ 5D4631051F2125F70092EFDC /* @protocols */,
+ );
+ name = "Control Frame Payloads";
+ sourceTree = "<group>";
+ };
5DAE06711BDEC68700F9B498 /* Developer API Tests */ = {
isa = PBXGroup;
children = (
@@ -3760,6 +3931,26 @@
name = "Prioritized Objects";
sourceTree = "<group>";
};
+ 5DB996541F268E9D002D8795 /* Audio Service */ = {
+ isa = PBXGroup;
+ children = (
+ 5DB996551F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.h */,
+ 5DB996561F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m */,
+ );
+ name = "Audio Service";
+ sourceTree = "<group>";
+ };
+ 5DB996591F268F78002D8795 /* Video Service */ = {
+ isa = PBXGroup;
+ children = (
+ 5DB9965A1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.h */,
+ 5DB9965B1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m */,
+ 5DB9965E1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h */,
+ 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */,
+ );
+ name = "Video Service";
+ sourceTree = "<group>";
+ };
5DBAE0A51D355EE700CE00BF /* Lock Screen */ = {
isa = PBXGroup;
children = (
@@ -3863,6 +4054,45 @@
name = Modules;
sourceTree = "<group>";
};
+ 5DC09ED71F2F7F1A00F4AB1D /* Control Frame Payloads */ = {
+ isa = PBXGroup;
+ children = (
+ 5DA23FF11F2FA32A009C0313 /* Audio Service */,
+ 5DC09ED81F2F7FC000F4AB1D /* General */,
+ 5DA23FF41F2FAA06009C0313 /* RPC Service */,
+ 5DA23FF91F2FB485009C0313 /* Video Service */,
+ );
+ name = "Control Frame Payloads";
+ sourceTree = "<group>";
+ };
+ 5DC09ED81F2F7FC000F4AB1D /* General */ = {
+ isa = PBXGroup;
+ children = (
+ 5DC09ED91F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m */,
+ 5DA23FEF1F2FA0FF009C0313 /* SDLControlFramePayloadEndServiceSpec.m */,
+ );
+ name = General;
+ sourceTree = "<group>";
+ };
+ 5DCC199D1B8221D2004FFAD9 /* HTTP Connection */ = {
+ isa = PBXGroup;
+ children = (
+ 5DCC199E1B8221F3004FFAD9 /* SDLURLSession.h */,
+ 5DCC199F1B8221F3004FFAD9 /* SDLURLSession.m */,
+ 5DCC19A21B822804004FFAD9 /* SDLURLRequestTask.h */,
+ 5DCC19A31B822804004FFAD9 /* SDLURLRequestTask.m */,
+ );
+ name = "HTTP Connection";
+ sourceTree = "<group>";
+ };
+ 5DE372A71ACC35C100849FAA /* @protocols */ = {
+ isa = PBXGroup;
+ children = (
+ 5DE372A51ACC35B400849FAA /* SDLDebugToolConsole.h */,
+ );
+ name = "@protocols";
+ sourceTree = "<group>";
+ };
5DEE55BE1B8509A5004F0D0F /* HTTP Connection */ = {
isa = PBXGroup;
children = (
@@ -3969,6 +4199,7 @@
5D61FD131A84238C00846EE7 /* SDLOnLanguageChange.h in Headers */,
5D61FDE71A84238C00846EE7 /* SDLUnsubscribeButton.h in Headers */,
5D61FCAB1A84238C00846EE7 /* SDLFuelCutoffStatus.h in Headers */,
+ 5DB9965C1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.h in Headers */,
5D1665C81CF8CA3D00CC4CA1 /* SDLPermissionFilter.h in Headers */,
E9C32B911AB20BA200F283AF /* SDLIAPSession.h in Headers */,
5D61FCD71A84238C00846EE7 /* SDLInteractionMode.h in Headers */,
@@ -3983,8 +4214,11 @@
5D61FE111A84238C00846EE7 /* SDLWarningLightStatus.h in Headers */,
5D61FC7A1A84238C00846EE7 /* SDLDeleteInteractionChoiceSet.h in Headers */,
5D61FC3B1A84238C00846EE7 /* SDLAlertManeuverResponse.h in Headers */,
+ 5DB9964E1F26886C002D8795 /* SDLControlFramePayloadEndService.h in Headers */,
+ 5D9FDA991F2A7D3F00A495C8 /* emhashmap.h in Headers */,
5D61FDB71A84238C00846EE7 /* SDLSyncPData.h in Headers */,
5D61FD011A84238C00846EE7 /* SDLOnAudioPassThru.h in Headers */,
+ 5D9FDA901F2A7D3400A495C8 /* bson_array.h in Headers */,
5D61FDCB1A84238C00846EE7 /* SDLTextFieldName.h in Headers */,
5D61FD8B1A84238C00846EE7 /* SDLSetMediaClockTimer.h in Headers */,
5D61FD031A84238C00846EE7 /* SDLOnButtonEvent.h in Headers */,
@@ -4058,6 +4292,7 @@
5D61FD871A84238C00846EE7 /* SDLSetGlobalProperties.h in Headers */,
5D61FC741A84238C00846EE7 /* SDLDeleteCommandResponse.h in Headers */,
5D61FDF11A84238C00846EE7 /* SDLUpdateTurnList.h in Headers */,
+ 5DB996571F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.h in Headers */,
5D61FD671A84238C00846EE7 /* SDLResult.h in Headers */,
5D61FD351A84238C00846EE7 /* SDLPowerModeStatus.h in Headers */,
5D61FD971A84238C00846EE7 /* SDLSingleTireStatus.h in Headers */,
@@ -4074,6 +4309,7 @@
5D61FD191A84238C00846EE7 /* SDLOnSyncPData.h in Headers */,
5D61FE091A84238C00846EE7 /* SDLVehicleDataType.h in Headers */,
5D61FDB11A84238C00846EE7 /* SDLSubscribeVehicleData.h in Headers */,
+ 5DB996601F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h in Headers */,
5DCF76F51ACDBAD300BB647B /* SDLSendLocation.h in Headers */,
5D61FC9E1A84238C00846EE7 /* SDLEncodedSyncPData.h in Headers */,
5D61FC291A84238C00846EE7 /* SDLAbstractProtocol.h in Headers */,
@@ -4092,6 +4328,7 @@
5D61FCFA1A84238C00846EE7 /* SDLMyKey.h in Headers */,
8B7B31A61F2F875200BDC38D /* SDLVideoStreamingCapability.h in Headers */,
5D61FC981A84238C00846EE7 /* SDLECallInfo.h in Headers */,
+ 5D9FDA921F2A7D3400A495C8 /* bson_object.h in Headers */,
5D61FD7B1A84238C00846EE7 /* SDLScrollableMessage.h in Headers */,
DA9F7E931DCC04E400ACAE48 /* SDLUnsubscribeWaypoints.h in Headers */,
5D61FD3D1A84238C00846EE7 /* SDLPrimaryAudioSource.h in Headers */,
@@ -4132,6 +4369,7 @@
5D61FCF21A84238C00846EE7 /* SDLLockScreenStatus.h in Headers */,
5D00AC771F15283E004000D9 /* SDLNavigationCapability.h in Headers */,
88EED83E1F33C5A400E6C42E /* SDLSendHapticData.h in Headers */,
+ 8BD729AE1F2A5AA10029AC93 /* SDLVideoStreamingFormat.h in Headers */,
5D61FCD31A84238C00846EE7 /* SDLImageResolution.h in Headers */,
8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */,
5D61FD541A84238C00846EE7 /* SDLProxyListener.h in Headers */,
@@ -4168,6 +4406,7 @@
DAC572631D10C5020004288B /* SDLPinchGesture.h in Headers */,
5D61FC311A84238C00846EE7 /* SDLAddSubMenu.h in Headers */,
5D61FD171A84238C00846EE7 /* SDLOnPermissionsChange.h in Headers */,
+ 5D4631081F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.h in Headers */,
5D61FDD51A84238C00846EE7 /* SDLTouchEventCapabilities.h in Headers */,
5D61FD0B1A84238C00846EE7 /* SDLOnEncodedSyncPData.h in Headers */,
5D61FC631A84238C00846EE7 /* SDLClusterModeStatus.h in Headers */,
@@ -4180,6 +4419,7 @@
DA9F7E7F1DCC028B00ACAE48 /* SDLOnWaypointChange.h in Headers */,
5D61FCE41A84238C00846EE7 /* SDLKeyboardProperties.h in Headers */,
5D61FDED1A84238C00846EE7 /* SDLUnsubscribeVehicleDataResponse.h in Headers */,
+ 5D4631041F2120A30092EFDC /* SDLControlFramePayloadType.h in Headers */,
5D61FCCF1A84238C00846EE7 /* SDLImageField.h in Headers */,
5D535DC51B72473800CF7760 /* SDLGlobals.h in Headers */,
5D79A03B1CE36F030035797B /* SDLUploadFileOperation.h in Headers */,
@@ -4192,10 +4432,12 @@
5D61FDB51A84238C00846EE7 /* SDLSyncMsgVersion.h in Headers */,
5DA102A41D4122C700C15826 /* NSMutableDictionary+SafeRemove.h in Headers */,
5DBF062A1E64A92C00A5CF03 /* SDLLogTarget.h in Headers */,
+ 5DA49CE51F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h in Headers */,
5D61FE031A84238C00846EE7 /* SDLVehicleDataResult.h in Headers */,
5D61FD911A84238C00846EE7 /* SDLShowConstantTBT.h in Headers */,
5D61FC331A84238C00846EE7 /* SDLAddSubMenuResponse.h in Headers */,
5D61FD5D1A84238C00846EE7 /* SDLRegisterAppInterface.h in Headers */,
+ 8BD729A61F2A2CF30029AC93 /* SDLVideoStreamingCodec.h in Headers */,
5D61FC9A1A84238C00846EE7 /* SDLEmergencyEvent.h in Headers */,
5D61FC651A84238C00846EE7 /* SDLCompassDirection.h in Headers */,
5D61FC8E1A84238C00846EE7 /* SDLDimension.h in Headers */,
@@ -4214,6 +4456,7 @@
5D61FCA31A84238C00846EE7 /* SDLEndAudioPassThru.h in Headers */,
5D61FCB11A84238C00846EE7 /* SDLGetDTCs.h in Headers */,
5D61FDFF1A84238C00846EE7 /* SDLVehicleDataEventStatus.h in Headers */,
+ 8BD729AA1F2A41F40029AC93 /* SDLVideoStreamingProtocol.h in Headers */,
5D61FC5B1A84238C00846EE7 /* SDLChangeRegistration.h in Headers */,
5D61FD5B1A84238C00846EE7 /* SDLReadDIDResponse.h in Headers */,
5D61FDEF1A84238C00846EE7 /* SDLUpdateMode.h in Headers */,
@@ -4229,6 +4472,7 @@
332A91501CED9CF10043824C /* SDLAppInfo.h in Headers */,
5D61FDA71A84238C00846EE7 /* SDLSpeakResponse.h in Headers */,
5D1665CB1CF8CA6700CC4CA1 /* NSNumber+NumberType.h in Headers */,
+ 5D9FDA941F2A7D3400A495C8 /* bson_util.h in Headers */,
5D61FD771A84238C00846EE7 /* SDLSamplingRate.h in Headers */,
5D61FCBB1A84238C00846EE7 /* SDLGPSData.h in Headers */,
5D61FDA31A84238C00846EE7 /* SDLSoftButtonType.h in Headers */,
@@ -4239,6 +4483,7 @@
5D61FD691A84238C00846EE7 /* SDLRPCMessage.h in Headers */,
5D61FCA71A84238C00846EE7 /* SDLEnum.h in Headers */,
5D8B174F1AC9D266006A6E1C /* SDLDialNumber.h in Headers */,
+ 5D4631101F2135850092EFDC /* SDLControlFramePayloadConstants.h in Headers */,
5D7F87EF1CE3C294002DD7C4 /* SDLFileManagerConstants.h in Headers */,
5D61FCAD1A84238C00846EE7 /* SDLFunctionID.h in Headers */,
DA9F7E831DCC047200ACAE48 /* SDLWaypointType.h in Headers */,
@@ -4250,6 +4495,7 @@
5D82041E1BCD8E6100D0A41B /* SDLConfiguration.h in Headers */,
5D61FD4A1A84238C00846EE7 /* SDLProtocolMessageAssembler.h in Headers */,
5D61FD4C1A84238C00846EE7 /* SDLProtocolMessageDisassembler.h in Headers */,
+ 5D4631141F2136B60092EFDC /* SDLControlFramePayloadNak.h in Headers */,
5D61FD4E1A84238C00846EE7 /* SDLProtocolReceivedMessageRouter.h in Headers */,
97E26DEC1E807AD70074A3C7 /* SDLMutableDataQueue.h in Headers */,
5D61FDF71A84238C00846EE7 /* SDLV1ProtocolMessage.h in Headers */,
@@ -4267,6 +4513,7 @@
5D61FD6F1A84238C00846EE7 /* SDLRPCPayload.h in Headers */,
5D61FCF01A84238C00846EE7 /* SDLLockScreenStatusManager.h in Headers */,
5D61FD311A84238C00846EE7 /* SDLPolicyDataParser.h in Headers */,
+ 8BD729B21F2A61DF0029AC93 /* SDLVideoStreamingCapability.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4431,6 +4678,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5D9FDA9A1F2A7D3F00A495C8 /* LICENSE in Resources */,
5D6F7A3E1BC811FC0070BF37 /* SDLAssets.xcassets in Resources */,
5D616B451D552F7A00553F6B /* SDLLockScreen.storyboard in Resources */,
);
@@ -4483,6 +4731,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 8BD729AB1F2A41F40029AC93 /* SDLVideoStreamingProtocol.m in Sources */,
332A914F1CED9CC60043824C /* SDLAppInfo.m in Sources */,
DA9F7E841DCC047200ACAE48 /* SDLWaypointType.m in Sources */,
5D61FC561A84238C00846EE7 /* SDLButtonName.m in Sources */,
@@ -4536,9 +4785,11 @@
5D61FCC81A84238C00846EE7 /* SDLIAPTransport.m in Sources */,
5D61FE101A84238C00846EE7 /* SDLVrHelpItem.m in Sources */,
5D61FCC01A84238C00846EE7 /* SDLHexUtility.m in Sources */,
+ 5DB9964F1F26886C002D8795 /* SDLControlFramePayloadEndService.m in Sources */,
5D61FD821A84238C00846EE7 /* SDLSetAppIconResponse.m in Sources */,
5D61FDF81A84238C00846EE7 /* SDLV1ProtocolMessage.m in Sources */,
5D61FDC81A84238C00846EE7 /* SDLTextAlignment.m in Sources */,
+ 5D4631091F21261B0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.m in Sources */,
5D82042E1BCEC32F00D0A41B /* SDLFile.m in Sources */,
5DA3F3601BC448590026F2D0 /* SDLNotificationConstants.m in Sources */,
5D61FD5A1A84238C00846EE7 /* SDLReadDID.m in Sources */,
@@ -4569,6 +4820,7 @@
5D61FDB21A84238C00846EE7 /* SDLSubscribeVehicleData.m in Sources */,
5D61FC991A84238C00846EE7 /* SDLECallInfo.m in Sources */,
5D61FD601A84238C00846EE7 /* SDLRegisterAppInterfaceResponse.m in Sources */,
+ 5DB996581F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m in Sources */,
DAC572621D10C5020004288B /* SDLPinchGesture.m in Sources */,
5D61FCF51A84238C00846EE7 /* SDLMaintenanceModeStatus.m in Sources */,
5D61FCD81A84238C00846EE7 /* SDLInteractionMode.m in Sources */,
@@ -4597,11 +4849,13 @@
5D3E48801D6F88A30000BFEF /* SDLRPCNotificationNotification.m in Sources */,
DAC572581D1067270004288B /* SDLTouchManager.m in Sources */,
5D61FC641A84238C00846EE7 /* SDLClusterModeStatus.m in Sources */,
+ 5DB9965D1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m in Sources */,
5D61FCF91A84238C00846EE7 /* SDLMenuParams.m in Sources */,
5D61FD7C1A84238C00846EE7 /* SDLScrollableMessage.m in Sources */,
5D4D67B11D2FE2F900468B4A /* SDLResponseDispatcher.m in Sources */,
5D61FD801A84238C00846EE7 /* SDLSetAppIcon.m in Sources */,
5D61FD3C1A84238C00846EE7 /* SDLPresetBankCapabilities.m in Sources */,
+ 5D4631151F2136B60092EFDC /* SDLControlFramePayloadNak.m in Sources */,
5D61FDB81A84238C00846EE7 /* SDLSyncPData.m in Sources */,
5D61FD221A84238C00846EE7 /* SDLOnVehicleData.m in Sources */,
5D61FCD41A84238C00846EE7 /* SDLImageResolution.m in Sources */,
@@ -4624,13 +4878,16 @@
5D61FD701A84238C00846EE7 /* SDLRPCPayload.m in Sources */,
5D61FD9C1A84238C00846EE7 /* SDLSlider.m in Sources */,
5DCF76FA1ACDD7CD00BB647B /* SDLSendLocationResponse.m in Sources */,
+ 5D9FDA8F1F2A7D3400A495C8 /* bson_array.c in Sources */,
5D61FD661A84238C00846EE7 /* SDLResetGlobalPropertiesResponse.m in Sources */,
5D61FCFE1A84238C00846EE7 /* SDLObjectWithPriority.m in Sources */,
5DBF06241E64A83F00A5CF03 /* SDLLogManager.m in Sources */,
5D61FC401A84238C00846EE7 /* SDLAmbientLightStatus.m in Sources */,
5D61FC951A84238C00846EE7 /* SDLDriverDistractionState.m in Sources */,
+ 5DB996611F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m in Sources */,
5D61FD961A84238C00846EE7 /* SDLShowResponse.m in Sources */,
5D61FD981A84238C00846EE7 /* SDLSingleTireStatus.m in Sources */,
+ 5D9FDA931F2A7D3400A495C8 /* bson_util.c in Sources */,
5D61FD511A84238C00846EE7 /* SDLProxy.m in Sources */,
5D61FD461A84238C00846EE7 /* SDLProtocolHeader.m in Sources */,
5D61FDBC1A84238C00846EE7 /* SDLSystemAction.m in Sources */,
@@ -4651,6 +4908,7 @@
5D61FCC61A84238C00846EE7 /* SDLHMIZoneCapabilities.m in Sources */,
5D61FD161A84238C00846EE7 /* SDLOnLockScreenStatus.m in Sources */,
5D61FDAE1A84238C00846EE7 /* SDLSubscribeButton.m in Sources */,
+ 8BD729AF1F2A5AA10029AC93 /* SDLVideoStreamingFormat.m in Sources */,
DA9F7E6C1DCBFB0700ACAE48 /* SDLDeliveryMode.m in Sources */,
5D61FC581A84238C00846EE7 /* SDLButtonPressMode.m in Sources */,
5D00AC781F15283E004000D9 /* SDLNavigationCapability.m in Sources */,
@@ -4669,6 +4927,7 @@
5D61FDD01A84238C00846EE7 /* SDLTireStatus.m in Sources */,
5D61FC321A84238C00846EE7 /* SDLAddSubMenu.m in Sources */,
5D61FDF61A84238C00846EE7 /* SDLV1ProtocolHeader.m in Sources */,
+ 8BD729B31F2A61DF0029AC93 /* SDLVideoStreamingCapability.m in Sources */,
5D61FDAA1A84238C00846EE7 /* SDLSpeechCapabilities.m in Sources */,
5D61FDB41A84238C00846EE7 /* SDLSubscribeVehicleDataResponse.m in Sources */,
5D61FD121A84238C00846EE7 /* SDLOnKeyboardInput.m in Sources */,
@@ -4683,6 +4942,7 @@
5D61FC7F1A84238C00846EE7 /* SDLDeleteSubMenu.m in Sources */,
5D61FCE91A84238C00846EE7 /* SDLLanguage.m in Sources */,
5D61FC3E1A84238C00846EE7 /* SDLAlertResponse.m in Sources */,
+ 8BD729A71F2A2CF30029AC93 /* SDLVideoStreamingCodec.m in Sources */,
5D61FD8C1A84238C00846EE7 /* SDLSetMediaClockTimer.m in Sources */,
5D61FE121A84238C00846EE7 /* SDLWarningLightStatus.m in Sources */,
5D61FCB81A84238C00846EE7 /* SDLGetVehicleDataResponse.m in Sources */,
@@ -4693,6 +4953,7 @@
5D61FE001A84238C00846EE7 /* SDLVehicleDataEventStatus.m in Sources */,
5D61FDC41A84238C00846EE7 /* SDLTBTState.m in Sources */,
5D61FDA61A84238C00846EE7 /* SDLSpeak.m in Sources */,
+ 5D4631111F2135850092EFDC /* SDLControlFramePayloadConstants.m in Sources */,
DA9F7E881DCC049900ACAE48 /* SDLSubscribeWaypoints.m in Sources */,
5D61FDDE1A84238C00846EE7 /* SDLTTSChunk.m in Sources */,
5D61FD9E1A84238C00846EE7 /* SDLSliderResponse.m in Sources */,
@@ -4709,6 +4970,7 @@
5D61FCA41A84238C00846EE7 /* SDLEndAudioPassThru.m in Sources */,
5D8B17541AC9E11B006A6E1C /* SDLDialNumberResponse.m in Sources */,
5D61FC851A84238C00846EE7 /* SDLDeviceLevelStatus.m in Sources */,
+ 5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */,
5D61FD1E1A84238C00846EE7 /* SDLOnTBTClientState.m in Sources */,
5DD67CBD1E661C84009CD394 /* SDLLogTargetOSLog.m in Sources */,
DA9F7E641DCBFAC800ACAE48 /* SDLDateTime.m in Sources */,
@@ -4730,6 +4992,7 @@
5D61FDD81A84238C00846EE7 /* SDLTouchType.m in Sources */,
DA4F47961E771AA100FC809E /* SDLEnum.m in Sources */,
5D61FDD61A84238C00846EE7 /* SDLTouchEventCapabilities.m in Sources */,
+ 5DA49CE61F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m in Sources */,
5DA102A51D4122C700C15826 /* NSMutableDictionary+SafeRemove.m in Sources */,
5D61FCF11A84238C00846EE7 /* SDLLockScreenStatusManager.m in Sources */,
5D61FDAC1A84238C00846EE7 /* SDLStartTime.m in Sources */,
@@ -4775,6 +5038,7 @@
5D61FDC61A84238C00846EE7 /* SDLTCPTransport.m in Sources */,
5D61FE0E1A84238C00846EE7 /* SDLVrCapabilities.m in Sources */,
5D61FDC21A84238C00846EE7 /* SDLSystemRequestResponse.m in Sources */,
+ 5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */,
5D61FD001A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.m in Sources */,
DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */,
5D61FC6C1A84238C00846EE7 /* SDLCreateInteractionChoiceSet.m in Sources */,
@@ -4818,6 +5082,7 @@
5DA026901AD44EE700019F86 /* SDLDialNumberResponseSpec.m in Sources */,
162E83901A9BDE8B00906325 /* SDLTireStatusSpec.m in Sources */,
162E82E01A9BDE8B00906325 /* SDLHMILevelSpec.m in Sources */,
+ 5DC09EDA1F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m in Sources */,
162E83041A9BDE8B00906325 /* SDLUpdateModeSpec.m in Sources */,
162E83801A9BDE8B00906325 /* SDLHMIPermissionsSpec.m in Sources */,
5D1654561D3E754F00554D93 /* SDLLifecycleManagerSpec.m in Sources */,
@@ -4849,6 +5114,7 @@
162E82ED1A9BDE8B00906325 /* SDLMaintenanceModeStatusSpec.m in Sources */,
5DB92D2D1AC4A34F00C15BB0 /* SDLPrioritizedObjectCollectionSpec.m in Sources */,
5D43466D1E6F522000B639C6 /* SDLLogModelSpec.m in Sources */,
+ 5DA23FF31F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m in Sources */,
1680B11C1A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m in Sources */,
162E83181A9BDE8B00906325 /* SDLOnKeyboardInputSpec.m in Sources */,
162E83701A9BDE8B00906325 /* SDLUpdateTurnListResponseSpec.m in Sources */,
@@ -4884,6 +5150,7 @@
162E82F31A9BDE8B00906325 /* SDLPrerecordedSpeechSpec.m in Sources */,
162E83691A9BDE8B00906325 /* SDLSubscribeButtonResponseSpec.m in Sources */,
5DAE06751BDEC6D600F9B498 /* SDLArtworkSpec.m in Sources */,
+ 5DA23FF01F2FA0FF009C0313 /* SDLControlFramePayloadEndServiceSpec.m in Sources */,
162E83591A9BDE8B00906325 /* SDLListFilesResponseSpec.m in Sources */,
162E832A1A9BDE8B00906325 /* SDLDeleteInteractionChoiceSetSpec.m in Sources */,
162E839D1A9BDE8B00906325 /* SDLRPCResponseSpec.m in Sources */,
@@ -4945,11 +5212,13 @@
162E83361A9BDE8B00906325 /* SDLRegisterAppInterfaceSpec.m in Sources */,
8B7B31AB1F2FB93500BDC38D /* SDLVideoStreamingCodecSpec.m in Sources */,
162E82DD1A9BDE8B00906325 /* SDLFileTypeSpec.m in Sources */,
+ 5DBF0D5E1F3A68C0008AF2C9 /* SDLControlFramePayloadVideoStartServiceSpec.m in Sources */,
162E836A1A9BDE8B00906325 /* SDLSubscribeVehicleDataResponseSpec.m in Sources */,
5D43465B1E6F154400B639C6 /* SDLLogConfigurationSpec.m in Sources */,
162E83761A9BDE8B00906325 /* SDLChoiceSpec.m in Sources */,
162E83571A9BDE8B00906325 /* SDLGetDTCsResponseSpec.m in Sources */,
5D4346471E6F0BDA00B639C6 /* SDLLogFileModuleSpec.m in Sources */,
+ 5DA23FF61F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m in Sources */,
162E83201A9BDE8B00906325 /* SDLOnVehicleDataSpec.m in Sources */,
162E83141A9BDE8B00906325 /* SDLOnDriverDistractionSpec.m in Sources */,
162E83371A9BDE8B00906325 /* SDLResetGlobalPropertiesSpec.m in Sources */,
@@ -5003,6 +5272,7 @@
162E83031A9BDE8B00906325 /* SDLTriggerSource.m in Sources */,
162E82D61A9BDE8A00906325 /* SDLComponentVolumeStatusSpec.m in Sources */,
162E835C1A9BDE8B00906325 /* SDLPutFileResponseSpec.m in Sources */,
+ 8BD729B51F2A711D0029AC93 /* SDLVideoStreamingCodecSpec.m in Sources */,
DA9F7EAA1DCC061A00ACAE48 /* SDLSubscribeWaypointsResponseSpec.m in Sources */,
162E835F1A9BDE8B00906325 /* SDLResetGlobalPropertiesResponseSpec.m in Sources */,
162E835E1A9BDE8B00906325 /* SDLRegisterAppInterfaceResponseSpec.m in Sources */,
@@ -5019,15 +5289,18 @@
162E83301A9BDE8B00906325 /* SDLGetVehicleDataSpec.m in Sources */,
162E833F1A9BDE8B00906325 /* SDLSliderSpec.m in Sources */,
162E838C1A9BDE8B00906325 /* SDLSoftButtonSpec.m in Sources */,
+ 5DA23FF81F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m in Sources */,
162E83191A9BDE8B00906325 /* SDLOnLanguageChangeSpec.m in Sources */,
5DB1BCDD1D243DC3002FFC37 /* SDLLifecycleConfigurationSpec.m in Sources */,
162E83611A9BDE8B00906325 /* SDLSetAppIconResponseSpec.m in Sources */,
162E83471A9BDE8B00906325 /* SDLUnsubscribeVehicleDataSpec.m in Sources */,
162E839A1A9BDE8B00906325 /* SDLRPCMessageSpec.m in Sources */,
5D0A9F911F15550400CC80DD /* SDLSystemCapabilityTypeSpec.m in Sources */,
+ 5DBF0D601F3B3DB4008AF2C9 /* SDLControlFrameVideoStartServiceAckSpec.m in Sources */,
162E83311A9BDE8B00906325 /* SDLListFilesSpec.m in Sources */,
DA9F7EB01DCC063400ACAE48 /* SDLLocationDetailsSpec.m in Sources */,
5DC978261B7A38640012C2F1 /* SDLGlobalsSpec.m in Sources */,
+ 8BF9DE071F2BAEEE004FFCBB /* SDLVideoStreamingFormatSpec.m in Sources */,
162E82FF1A9BDE8B00906325 /* SDLTextAlignmentSpec.m in Sources */,
162E831F1A9BDE8B00906325 /* SDLOnTouchEventSpec.m in Sources */,
162E83921A9BDE8B00906325 /* SDLTouchEventCapabilitiesSpec.m in Sources */,
@@ -5043,6 +5316,7 @@
162E831D1A9BDE8B00906325 /* SDLOnSystemRequestSpec.m in Sources */,
162E835D1A9BDE8B00906325 /* SDLReadDIDResponseSpec.m in Sources */,
162E82D41A9BDE8A00906325 /* SDLCharacterSetSpec.m in Sources */,
+ 8BF9DE091F2BAF0C004FFCBB /* SDLVideoStreamingCapabilitySpec.m in Sources */,
162E830F1A9BDE8B00906325 /* SDLOnAppInterfaceUnregisteredSpec.m in Sources */,
162E83971A9BDE8B00906325 /* SDLVehicleTypeSpec.m in Sources */,
1680B1131A9CD7AD00DBD79E /* SDLProtocolHeaderSpec.m in Sources */,
@@ -5433,6 +5707,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
@@ -5468,6 +5743,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.xcworkspace/xcshareddata/SmartDeviceLink-iOS.xcscmblueprint b/SmartDeviceLink-iOS.xcodeproj/project.xcworkspace/xcshareddata/SmartDeviceLink-iOS.xcscmblueprint
new file mode 100644
index 000000000..3d36d3962
--- /dev/null
+++ b/SmartDeviceLink-iOS.xcodeproj/project.xcworkspace/xcshareddata/SmartDeviceLink-iOS.xcscmblueprint
@@ -0,0 +1,30 @@
+{
+ "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "66020812E25F835F7E461E1F36EFF9E212E74787",
+ "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
+
+ },
+ "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
+ "66020812E25F835F7E461E1F36EFF9E212E74787" : 9223372036854775807,
+ "56518C5F548896A9F8039D14FD50ECBB0A40BE1B" : 9223372036854775807
+ },
+ "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "E7549925-63B0-46D9-8801-13778848A065",
+ "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
+ "66020812E25F835F7E461E1F36EFF9E212E74787" : "sdl_ios\/",
+ "56518C5F548896A9F8039D14FD50ECBB0A40BE1B" : "sdl_ios\/bson_c_lib\/"
+ },
+ "DVTSourceControlWorkspaceBlueprintNameKey" : "SmartDeviceLink-iOS",
+ "DVTSourceControlWorkspaceBlueprintVersion" : 204,
+ "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "SmartDeviceLink-iOS.xcodeproj",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
+ {
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/smartdevicelink\/bson_c_lib.git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "56518C5F548896A9F8039D14FD50ECBB0A40BE1B"
+ },
+ {
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/smartdevicelink\/sdl_ios.git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "66020812E25F835F7E461E1F36EFF9E212E74787"
+ }
+ ]
+} \ No newline at end of file
diff --git a/SmartDeviceLink/SDLAbstractProtocol.h b/SmartDeviceLink/SDLAbstractProtocol.h
index 45e00b434..df804269e 100644
--- a/SmartDeviceLink/SDLAbstractProtocol.h
+++ b/SmartDeviceLink/SDLAbstractProtocol.h
@@ -20,14 +20,20 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy) NSString *appId;
// Sending
-- (void)sendStartSessionWithType:(SDLServiceType)serviceType __deprecated_msg(("Use startServiceWithType: instead"));
-- (void)startServiceWithType:(SDLServiceType)serviceType;
-- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;
+- (void)sendStartSessionWithType:(SDLServiceType)serviceType __deprecated_msg(("Use startServiceWithType:payload: instead"));
+- (void)startServiceWithType:(SDLServiceType)serviceType __deprecated_msg(("Use startServiceWithType:payload: instead"));
+- (void)startServiceWithType:(SDLServiceType)serviceType payload:(NSData *)payload;
+
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL success, NSError *error))completionHandler __deprecated_msg(("Use startSecureServiceWithType:payload:completionHandler instead"));;
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType payload:(NSData *)payload completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;
+
- (void)sendEndSessionWithType:(SDLServiceType)serviceType __deprecated_msg(("Use endServiceWithType: instead"));
- (void)endServiceWithType:(SDLServiceType)serviceType;
+
+- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest __deprecated_msg(("Use sendRPC: instead"));
- (void)sendRPC:(SDLRPCMessage *)message;
- (BOOL)sendRPC:(SDLRPCMessage *)message encrypted:(BOOL)encryption error:(NSError **)error;
-- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest __deprecated_msg(("Use sendRPC: instead"));
+
- (void)sendRawData:(NSData *)data withServiceType:(SDLServiceType)serviceType;
- (void)sendEncryptedRawData:(NSData *)data onService:(SDLServiceType)serviceType;
diff --git a/SmartDeviceLink/SDLAbstractProtocol.m b/SmartDeviceLink/SDLAbstractProtocol.m
index 09b882b66..26443ac2f 100644
--- a/SmartDeviceLink/SDLAbstractProtocol.m
+++ b/SmartDeviceLink/SDLAbstractProtocol.m
@@ -25,7 +25,15 @@ NS_ASSUME_NONNULL_BEGIN
[self doesNotRecognizeSelector:_cmd];
}
-- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL success, NSError *error))completionHandler {
+- (void)startServiceWithType:(SDLServiceType)serviceType payload:(NSData *)payload {
+ [self doesNotRecognizeSelector:_cmd];
+}
+
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL, NSError *))completionHandler {
+ [self doesNotRecognizeSelector:_cmd];
+}
+
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType payload:(NSData *)payload completionHandler:(void (^)(BOOL, NSError *))completionHandler {
[self doesNotRecognizeSelector:_cmd];
}
diff --git a/SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.h b/SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.h
new file mode 100644
index 000000000..9a9dc95f4
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.h
@@ -0,0 +1,24 @@
+//
+// SDLControlFramePayloadAudioStartServiceAck.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/24/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadAudioStartServiceAck : NSObject <SDLControlFramePayloadType>
+
+/// Max transport unit to be used for this service. If not included the client should use the one set via the RPC service or protocol version default.
+@property (assign, nonatomic, readonly) int64_t mtu;
+
+- (instancetype)initWithMTU:(int64_t)mtu;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.m b/SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.m
new file mode 100644
index 000000000..ac969d07b
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadAudioStartServiceAck.m
@@ -0,0 +1,81 @@
+//
+// SDLControlFramePayloadAudioStartServiceAck.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/24/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadAudioStartServiceAck.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadAudioStartServiceAck ()
+
+@property (assign, nonatomic, readwrite) int64_t mtu;
+
+@end
+
+@implementation SDLControlFramePayloadAudioStartServiceAck
+
+- (instancetype)initWithMTU:(int64_t)mtu {
+ self = [super init];
+ if (!self) return nil;
+
+ _mtu = mtu;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ _mtu = SDLControlFrameInt64NotFound;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.mtu == SDLControlFrameInt64NotFound) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.mtu != SDLControlFrameInt64NotFound) {
+ bson_object_put_int64(&payloadObject, SDLControlFrameMTUKey, self.mtu);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+
+ self.mtu = bson_object_get_int64(&payloadObject, SDLControlFrameMTUKey);
+
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: MTU: %lld", NSStringFromClass(self.class), self.mtu];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadConstants.h b/SmartDeviceLink/SDLControlFramePayloadConstants.h
new file mode 100644
index 000000000..f95b90ef8
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadConstants.h
@@ -0,0 +1,21 @@
+//
+// SDLControlFramePayloadConstants.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+extern int32_t const SDLControlFrameInt32NotFound;
+extern int64_t const SDLControlFrameInt64NotFound;
+
+extern char *const SDLControlFrameProtocolVersionKey;
+extern char *const SDLControlFrameHashIdKey;
+extern char *const SDLControlFrameMTUKey;
+extern char *const SDLControlFrameRejectedParams;
+extern char *const SDLControlFrameVideoProtocolKey;
+extern char *const SDLControlFrameVideoCodecKey;
+extern char *const SDLControlFrameHeightKey;
+extern char *const SDLControlFrameWidthKey;
diff --git a/SmartDeviceLink/SDLControlFramePayloadConstants.m b/SmartDeviceLink/SDLControlFramePayloadConstants.m
new file mode 100644
index 000000000..8d9965f37
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadConstants.m
@@ -0,0 +1,21 @@
+//
+// SDLControlFramePayloadConstants.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadConstants.h"
+
+int32_t const SDLControlFrameInt32NotFound = -1;
+int64_t const SDLControlFrameInt64NotFound = -1;
+
+char *const SDLControlFrameProtocolVersionKey = "protocolVersion";
+char *const SDLControlFrameHashIdKey = "hashId";
+char *const SDLControlFrameMTUKey = "mtu";
+char *const SDLControlFrameRejectedParams = "rejectedParams";
+char *const SDLControlFrameVideoProtocolKey = "videoProtocol";
+char *const SDLControlFrameVideoCodecKey = "videoCodec";
+char *const SDLControlFrameHeightKey = "height";
+char *const SDLControlFrameWidthKey = "width";
diff --git a/SmartDeviceLink/SDLControlFramePayloadEndService.h b/SmartDeviceLink/SDLControlFramePayloadEndService.h
new file mode 100644
index 000000000..17790ab9e
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadEndService.h
@@ -0,0 +1,24 @@
+//
+// SDLControlFramePayloadEndService.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/24/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadEndService : NSObject <SDLControlFramePayloadType>
+
+/// Hash ID supplied in the StartServiceACK for this service type
+@property (assign, nonatomic, readonly) int32_t hashId;
+
+- (instancetype)initWithHashId:(int32_t)hashId;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadEndService.m b/SmartDeviceLink/SDLControlFramePayloadEndService.m
new file mode 100644
index 000000000..8399da517
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadEndService.m
@@ -0,0 +1,81 @@
+//
+// SDLControlFramePayloadEndService.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/24/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadEndService.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadEndService ()
+
+@property (assign, nonatomic, readwrite) int32_t hashId;
+
+@end
+
+@implementation SDLControlFramePayloadEndService
+
+- (instancetype)initWithHashId:(int32_t)hashId {
+ self = [super init];
+ if (!self) return nil;
+
+ _hashId = hashId;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ _hashId = SDLControlFrameInt32NotFound;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.hashId == SDLControlFrameInt32NotFound) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.hashId != SDLControlFrameInt32NotFound) {
+ bson_object_put_int32(&payloadObject, SDLControlFrameHashIdKey, self.hashId);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+
+ self.hashId = bson_object_get_int32(&payloadObject, SDLControlFrameHashIdKey);
+
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: hash id: %d", NSStringFromClass(self.class), self.hashId];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadNak.h b/SmartDeviceLink/SDLControlFramePayloadNak.h
new file mode 100644
index 000000000..41781cb2e
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadNak.h
@@ -0,0 +1,25 @@
+//
+// SDLControlFramePayloadNak.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadNak : NSObject <SDLControlFramePayloadType>
+
+/// An array of rejected parameters such as: [`hashId`]
+@property (copy, nonatomic, readonly, nullable) NSArray<NSString *> *rejectedParams;
+
+- (instancetype)initWithRejectedParams:(nullable NSArray<NSString *> *)rejectedParams;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadNak.m b/SmartDeviceLink/SDLControlFramePayloadNak.m
new file mode 100644
index 000000000..4402dea47
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadNak.m
@@ -0,0 +1,100 @@
+//
+// SDLControlFramePayloadNak.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadNak.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadNak ()
+
+@property (copy, nonatomic, readwrite, nullable) NSArray<NSString *> *rejectedParams;
+
+@end
+
+@implementation SDLControlFramePayloadNak
+
+- (instancetype)initWithRejectedParams:(nullable NSArray<NSString *> *)rejectedParams {
+ self = [super init];
+ if (!self) return nil;
+
+ _rejectedParams = rejectedParams;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.rejectedParams == nil) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.rejectedParams != nil) {
+ BsonArray arrayObject;
+ bson_array_initialize(&arrayObject, 512);
+
+ for (NSString *param in self.rejectedParams) {
+ bson_array_add_string(&arrayObject, (char *)param.UTF8String);
+ }
+
+ bson_object_put_array(&payloadObject, SDLControlFrameRejectedParams, &arrayObject);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+ BsonArray *arrayObject = bson_object_get_array(&payloadObject, SDLControlFrameRejectedParams);
+ if (arrayObject == NULL) {
+ return;
+ }
+
+ NSMutableArray<NSString *> *rejectedParams = [NSMutableArray array];
+ char *paramString;
+ size_t index = 0;
+
+ paramString = bson_array_get_string(arrayObject, index);
+ while (paramString != NULL) {
+ [rejectedParams addObject:[NSString stringWithUTF8String:paramString]];
+ index++;
+ paramString = bson_array_get_string(arrayObject, index);
+ }
+
+ self.rejectedParams = [rejectedParams copy];
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: Rejected params: %@", NSStringFromClass(self.class), self.rejectedParams];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h
new file mode 100644
index 000000000..af3d97a12
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h
@@ -0,0 +1,24 @@
+//
+// SDLControlFrameStartService.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/18/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadRPCStartService : NSObject <SDLControlFramePayloadType>
+
+/// The max version of protocol version supported by client requesting service to start. Must be in the format "Major.Minor.Patch"
+@property (copy, nonatomic, readonly, nullable) NSString *protocolVersion;
+
+- (instancetype)initWithVersion:(NSString *)stringVersion;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m
new file mode 100644
index 000000000..222370d24
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m
@@ -0,0 +1,83 @@
+//
+// SDLControlFrameStartService.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/18/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadRPCStartService.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadRPCStartService ()
+
+@property (copy, nonatomic, readwrite, nullable) NSString *protocolVersion;
+
+@end
+
+
+@implementation SDLControlFramePayloadRPCStartService
+
+- (instancetype)initWithVersion:(NSString *)stringVersion {
+ self = [super init];
+ if (!self) return nil;
+
+ _protocolVersion = stringVersion;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.protocolVersion == nil) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.protocolVersion != nil) {
+ bson_object_put_string(&payloadObject, SDLControlFrameProtocolVersionKey, (char *)self.protocolVersion.UTF8String);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+
+ char *utf8String = bson_object_get_string(&payloadObject, SDLControlFrameProtocolVersionKey);
+ if (utf8String != NULL) {
+ self.protocolVersion = [NSString stringWithUTF8String:utf8String];
+ }
+
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: Protocol Version: %@", NSStringFromClass(self.class), self.protocolVersion];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.h b/SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.h
new file mode 100644
index 000000000..078405e1e
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.h
@@ -0,0 +1,30 @@
+//
+// SDLControlFramePayloadStartServiceAck.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadRPCStartServiceAck : NSObject <SDLControlFramePayloadType>
+
+/// Hash ID to identify this service and used when sending an EndService control frame
+@property (assign, nonatomic, readonly) int32_t hashId;
+
+/// Max transport unit to be used for this service
+@property (assign, nonatomic, readonly) int64_t mtu;
+
+/// The negotiated version of the protocol. Must be in the format "Major.Minor.Patch"
+@property (copy, nonatomic, readonly, nullable) NSString *protocolVersion;
+
+- (instancetype)initWithHashId:(int32_t)hashId mtu:(int64_t)mtu protocolVersion:(nullable NSString *)protocolVersion;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.m b/SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.m
new file mode 100644
index 000000000..e4b8347fa
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadRPCStartServiceAck.m
@@ -0,0 +1,103 @@
+//
+// SDLControlFramePayloadStartServiceAck.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadRPCStartServiceAck.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadRPCStartServiceAck ()
+
+@property (assign, nonatomic, readwrite) int32_t hashId;
+@property (assign, nonatomic, readwrite) int64_t mtu;
+@property (copy, nonatomic, readwrite, nullable) NSString *protocolVersion;
+
+@end
+
+
+@implementation SDLControlFramePayloadRPCStartServiceAck
+
+- (instancetype)initWithHashId:(int32_t)hashId mtu:(int64_t)mtu protocolVersion:(nullable NSString *)protocolVersion {
+ self = [super init];
+ if (!self) return nil;
+
+ _hashId = hashId;
+ _mtu = mtu;
+ _protocolVersion = protocolVersion;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ _hashId = SDLControlFrameInt32NotFound;
+ _mtu = SDLControlFrameInt64NotFound;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.hashId == SDLControlFrameInt32NotFound
+ && self.mtu == SDLControlFrameInt64NotFound
+ && self.protocolVersion == nil) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.hashId != SDLControlFrameInt32NotFound) {
+ bson_object_put_int32(&payloadObject, SDLControlFrameHashIdKey, self.hashId);
+ }
+
+ if (self.mtu != SDLControlFrameInt64NotFound) {
+ bson_object_put_int64(&payloadObject, SDLControlFrameMTUKey, self.mtu);
+ }
+
+ if (self.protocolVersion != nil) {
+ bson_object_put_string(&payloadObject, SDLControlFrameProtocolVersionKey, (char *)self.protocolVersion.UTF8String);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+
+ self.hashId = bson_object_get_int32(&payloadObject, SDLControlFrameHashIdKey);
+ self.mtu = bson_object_get_int64(&payloadObject, SDLControlFrameMTUKey);
+
+ char *utf8String = bson_object_get_string(&payloadObject, SDLControlFrameProtocolVersionKey);
+ if (utf8String != NULL) {
+ self.protocolVersion = [NSString stringWithUTF8String:utf8String];
+ }
+
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: Protocol Version: %@, hash id: %d, MTU: %lld", NSStringFromClass(self.class), self.protocolVersion, self.hashId, self.mtu];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadType.h b/SmartDeviceLink/SDLControlFramePayloadType.h
new file mode 100644
index 000000000..2c9673ccc
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadType.h
@@ -0,0 +1,20 @@
+//
+// SDLControlFramePayload.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/20/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol SDLControlFramePayloadType <NSObject>
+
+- (nullable NSData *)data;
+- (instancetype)initWithData:(nullable NSData *)data;;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadVideoStartService.h b/SmartDeviceLink/SDLControlFramePayloadVideoStartService.h
new file mode 100644
index 000000000..63274f3ef
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadVideoStartService.h
@@ -0,0 +1,36 @@
+//
+// SDLControlFramePayloadVideoStartService.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/24/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingProtocol.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadVideoStartService : NSObject <SDLControlFramePayloadType>
+
+/// Desired height in pixels from the client requesting the video service to start
+@property (assign, nonatomic, readonly) int32_t height;
+
+/// Desired width in pixels from the client requesting the video service to start
+@property (assign, nonatomic, readonly) int32_t width;
+
+/// Desired video protocol to be used. See VideoStreamingProtocol RPC
+@property (copy, nonatomic, readonly, nullable) SDLVideoStreamingCodec videoCodec;
+
+/// Desired video codec to be used. See VideoStreamingCodec RPC
+@property (copy, nonatomic, readonly, nullable) SDLVideoStreamingProtocol videoProtocol;
+
+- (instancetype)initWithVideoHeight:(int32_t)height width:(int32_t)width protocol:(nullable SDLVideoStreamingProtocol)protocol codec:(nullable SDLVideoStreamingCodec)codec;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadVideoStartService.m b/SmartDeviceLink/SDLControlFramePayloadVideoStartService.m
new file mode 100644
index 000000000..800c3ace8
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadVideoStartService.m
@@ -0,0 +1,114 @@
+//
+// SDLControlFramePayloadVideoStartService.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/24/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadVideoStartService.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadVideoStartService ()
+
+@property (assign, nonatomic, readwrite) int32_t height;
+@property (assign, nonatomic, readwrite) int32_t width;
+@property (copy, nonatomic, readwrite, nullable) SDLVideoStreamingCodec videoCodec;
+@property (copy, nonatomic, readwrite, nullable) SDLVideoStreamingProtocol videoProtocol;
+
+@end
+
+@implementation SDLControlFramePayloadVideoStartService
+
+- (instancetype)initWithVideoHeight:(int32_t)height width:(int32_t)width protocol:(nullable SDLVideoStreamingProtocol)protocol codec:(nullable SDLVideoStreamingCodec)codec {
+ self = [super init];
+ if (!self) return nil;
+
+ _height = height;
+ _width = width;
+ _videoProtocol = protocol;
+ _videoCodec = codec;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ _height = SDLControlFrameInt32NotFound;
+ _width = SDLControlFrameInt32NotFound;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.height == SDLControlFrameInt32NotFound
+ && self.width == SDLControlFrameInt32NotFound
+ && self.videoProtocol == nil
+ && self.videoCodec == nil) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.height != SDLControlFrameInt32NotFound) {
+ bson_object_put_int32(&payloadObject, SDLControlFrameHeightKey, self.height);
+ }
+
+ if (self.width != SDLControlFrameInt32NotFound) {
+ bson_object_put_int32(&payloadObject, SDLControlFrameWidthKey, self.width);
+ }
+
+ if (self.videoProtocol != nil) {
+ bson_object_put_string(&payloadObject, SDLControlFrameVideoProtocolKey, (char *)self.videoProtocol.UTF8String);
+ }
+
+ if (self.videoCodec != nil) {
+ bson_object_put_string(&payloadObject, SDLControlFrameVideoCodecKey, (char *)self.videoCodec.UTF8String);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+
+ self.height = bson_object_get_int32(&payloadObject, SDLControlFrameHeightKey);
+ self.width = bson_object_get_int32(&payloadObject, SDLControlFrameWidthKey);
+
+ char *utf8String = bson_object_get_string(&payloadObject, SDLControlFrameVideoProtocolKey);
+ if (utf8String != NULL) {
+ self.videoProtocol = [NSString stringWithUTF8String:utf8String];
+ }
+
+ utf8String = bson_object_get_string(&payloadObject, SDLControlFrameVideoCodecKey);
+ if (utf8String != NULL) {
+ self.videoCodec = [NSString stringWithUTF8String:utf8String];
+ }
+
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: Width: %d, Height: %d, Protocol: %@, Codec: %@", NSStringFromClass(self.class), self.width, self.height, self.videoProtocol, self.videoCodec];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h
new file mode 100644
index 000000000..36ad5cfd6
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h
@@ -0,0 +1,40 @@
+//
+// SDLControlFramePayloadVideoStartServiceAck.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/26/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLControlFramePayloadType.h"
+
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingProtocol.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLControlFramePayloadVideoStartServiceAck : NSObject <SDLControlFramePayloadType>
+
+/// Max transport unit to be used for this service
+@property (assign, nonatomic, readonly) int64_t mtu;
+
+/// Accepted height in pixels from the client requesting the video service to start
+@property (assign, nonatomic, readonly) int32_t height;
+
+/// Accepted width in pixels from the client requesting the video service to start
+@property (assign, nonatomic, readonly) int32_t width;
+
+/// Accepted video protocol to be used. See VideoStreamingProtocol RPC
+@property (copy, nonatomic, readonly, nullable) SDLVideoStreamingProtocol videoProtocol;
+
+/// Accepted video codec to be used. See VideoStreamingCodec RPC
+@property (copy, nonatomic, readonly, nullable) SDLVideoStreamingCodec videoCodec;
+
+- (instancetype)initWithMTU:(int64_t)mtu height:(int32_t)height width:(int32_t)width protocol:(SDLVideoStreamingProtocol)protocol codec:(SDLVideoStreamingCodec)codec;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m
new file mode 100644
index 000000000..d74d1c68c
--- /dev/null
+++ b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m
@@ -0,0 +1,119 @@
+//
+// SDLControlFramePayloadVideoStartServiceAck.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 7/26/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLControlFramePayloadVideoStartServiceAck.h"
+
+#import "bson_object.h"
+#import "SDLControlFramePayloadConstants.h"
+
+
+@interface SDLControlFramePayloadVideoStartServiceAck ()
+
+@property (assign, nonatomic, readwrite) int64_t mtu;
+@property (assign, nonatomic, readwrite) int32_t height;
+@property (assign, nonatomic, readwrite) int32_t width;
+@property (copy, nonatomic, readwrite) SDLVideoStreamingProtocol videoProtocol;
+@property (copy, nonatomic, readwrite) SDLVideoStreamingCodec videoCodec;
+
+@end
+
+@implementation SDLControlFramePayloadVideoStartServiceAck
+
+- (instancetype)initWithMTU:(int64_t)mtu height:(int32_t)height width:(int32_t)width protocol:(SDLVideoStreamingProtocol)protocol codec:(SDLVideoStreamingCodec)codec {
+ self = [super init];
+ if (!self) return nil;
+
+ _mtu = mtu;
+ _height = height;
+ _width = width;
+ _videoProtocol = protocol;
+ _videoCodec = codec;
+
+ return self;
+}
+
+- (instancetype)initWithData:(nullable NSData *)data {
+ self = [super init];
+ if (!self) return nil;
+
+ _mtu = SDLControlFrameInt64NotFound;
+ _height = SDLControlFrameInt32NotFound;
+ _width = SDLControlFrameInt32NotFound;
+
+ if (data != nil) {
+ [self sdl_parse:data];
+ }
+
+ return self;
+}
+
+- (nullable NSData *)data {
+ if (self.mtu == SDLControlFrameInt64NotFound
+ && self.height == SDLControlFrameInt32NotFound
+ && self.width == SDLControlFrameInt32NotFound
+ && self.videoProtocol == nil
+ && self.videoCodec == nil) {
+ return nil;
+ }
+
+ BsonObject payloadObject;
+ bson_object_initialize_default(&payloadObject);
+
+ if (self.mtu != SDLControlFrameInt64NotFound) {
+ bson_object_put_int64(&payloadObject, SDLControlFrameMTUKey, self.mtu);
+ }
+
+ if (self.height != SDLControlFrameInt32NotFound) {
+ bson_object_put_int32(&payloadObject, SDLControlFrameHeightKey, self.height);
+ }
+
+ if (self.width != SDLControlFrameInt32NotFound) {
+ bson_object_put_int32(&payloadObject, SDLControlFrameWidthKey, self.width);
+ }
+
+ if (self.videoProtocol != nil) {
+ bson_object_put_string(&payloadObject, SDLControlFrameVideoProtocolKey, (char *)self.videoProtocol.UTF8String);
+ }
+
+ if (self.videoCodec != nil) {
+ bson_object_put_string(&payloadObject, SDLControlFrameVideoCodecKey, (char *)self.videoCodec.UTF8String);
+ }
+
+ BytePtr bsonData = bson_object_to_bytes(&payloadObject);
+ NSUInteger length = bson_object_size(&payloadObject);
+
+ bson_object_deinitialize(&payloadObject);
+
+ return [[NSData alloc] initWithBytes:bsonData length:length];
+}
+
+- (void)sdl_parse:(NSData *)data {
+ BsonObject payloadObject = bson_object_from_bytes((BytePtr)data.bytes);
+
+ self.mtu = bson_object_get_int64(&payloadObject, SDLControlFrameMTUKey);
+ self.height = bson_object_get_int32(&payloadObject, SDLControlFrameHeightKey);
+ self.width = bson_object_get_int32(&payloadObject, SDLControlFrameWidthKey);
+
+ char *utf8String = bson_object_get_string(&payloadObject, SDLControlFrameVideoProtocolKey);
+ if (utf8String != NULL) {
+ self.videoProtocol = [NSString stringWithUTF8String:utf8String];
+ }
+
+ utf8String = bson_object_get_string(&payloadObject, SDLControlFrameVideoCodecKey);
+ if (utf8String != NULL) {
+ self.videoCodec = [NSString stringWithUTF8String:utf8String];
+ }
+
+ bson_object_deinitialize(&payloadObject);
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@>: MTU: %lld, Width: %d, Height: %d, Protocol: %@, Codec: %@", NSStringFromClass(self.class), self.mtu, self.width, self.height, self.videoProtocol, self.videoCodec];
+}
+
+@end
diff --git a/SmartDeviceLink/SDLError.h b/SmartDeviceLink/SDLError.h
index 09ec20ee8..717fb7ac5 100644
--- a/SmartDeviceLink/SDLError.h
+++ b/SmartDeviceLink/SDLError.h
@@ -39,6 +39,7 @@ extern SDLErrorDomain *const SDLErrorDomainFileManager;
+ (NSError *)sdl_fileManager_noKnownFileError;
+ (NSError *)sdl_fileManager_unableToStartError;
+ (NSError *)sdl_fileManager_unableToUploadError;
++ (NSError *)sdl_fileManager_fileDoesNotExistError;
@end
diff --git a/SmartDeviceLink/SDLError.m b/SmartDeviceLink/SDLError.m
index 511f91deb..69ec729d5 100644
--- a/SmartDeviceLink/SDLError.m
+++ b/SmartDeviceLink/SDLError.m
@@ -140,6 +140,17 @@ SDLErrorDomain *const SDLErrorDomainFileManager = @"com.sdl.filemanager.error";
return [NSError errorWithDomain:SDLErrorDomainFileManager code:SDLFileManagerErrorUnableToUpload userInfo:userInfo];
}
+#pragma mark SDLUploadFileOperation
+
++ (NSError *)sdl_fileManager_fileDoesNotExistError {
+ NSDictionary<NSString *, NSString *> *userInfo = @{
+ NSLocalizedDescriptionKey: NSLocalizedString(@"The file manager was unable to send the file", nil),
+ NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"This could be because the file does not exist at the specified file path or that passed data is invalid", nil),
+ NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Make sure that the the correct file path is being set and that the passed data is valid", nil)
+ };
+return [NSError errorWithDomain:SDLErrorDomainFileManager code:SDLFileManagerErrorFileDoesNotExist userInfo:userInfo];
+}
+
@end
diff --git a/SmartDeviceLink/SDLErrorConstants.h b/SmartDeviceLink/SDLErrorConstants.h
index c439d3fd6..9f532a6fe 100644
--- a/SmartDeviceLink/SDLErrorConstants.h
+++ b/SmartDeviceLink/SDLErrorConstants.h
@@ -62,4 +62,8 @@ typedef NS_ENUM(NSInteger, SDLFileManagerError) {
* The file manager was unable to send this file.
*/
SDLFileManagerErrorUnableToUpload = -4,
+ /**
+ * The file manager could not find the local file
+ */
+ SDLFileManagerErrorFileDoesNotExist = -5,
};
diff --git a/SmartDeviceLink/SDLFile.h b/SmartDeviceLink/SDLFile.h
index 67a430705..eb21f3f3d 100644
--- a/SmartDeviceLink/SDLFile.h
+++ b/SmartDeviceLink/SDLFile.h
@@ -41,10 +41,19 @@ NS_ASSUME_NONNULL_BEGIN
@property (copy, nonatomic, readonly) NSData *data;
/**
+ * The size of the binary data of the SDLFile.
+ */
+@property (nonatomic, readonly) unsigned long long fileSize;
+
+/**
* The system will attempt to determine the type of file that you have passed in. It will default to BINARY if it does not recognize the file type or the file type is not supported by SDL.
*/
@property (strong, nonatomic, readonly) SDLFileType fileType;
+/**
+ * A stream to pull binary data from a SDLFile. The stream only pulls required data from the file on disk or in memory. This reduces memory usage while uploading a large file to the remote system as each chunk of data can be released immediately after it is uploaded.
+ */
+@property (nonatomic, readonly) NSInputStream *inputStream;
- (instancetype)init NS_UNAVAILABLE;
diff --git a/SmartDeviceLink/SDLFile.m b/SmartDeviceLink/SDLFile.m
index e7bed7f74..9fc4d5423 100644
--- a/SmartDeviceLink/SDLFile.m
+++ b/SmartDeviceLink/SDLFile.m
@@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic, readwrite) BOOL persistent;
@property (copy, nonatomic, readwrite) NSString *name;
+@property (nonatomic, readwrite) NSInputStream *inputStream;
@end
@@ -86,17 +87,50 @@ NS_ASSUME_NONNULL_BEGIN
return [[self alloc] initWithData:data name:name fileExtension:extension persistent:NO];
}
-
#pragma mark - Getters
- (NSData *)data {
if (_data.length == 0 && _fileURL != nil) {
- _data = [NSData dataWithContentsOfURL:_fileURL];
+ return [NSData dataWithContentsOfURL:_fileURL];
}
return _data;
}
+/**
+ Initalizes a socket from which to read data.
+
+ @return A socket
+ */
+- (NSInputStream *)inputStream {
+ if (!_inputStream) {
+ if (_fileURL) {
+ // Data in file
+ _inputStream = [[NSInputStream alloc] initWithURL:_fileURL];
+ } else if (_data.length != 0) {
+ // Data in memory
+ _inputStream = [[NSInputStream alloc] initWithData:_data];
+ }
+ }
+ return _inputStream;
+}
+
+/**
+ Gets the size of the data. The data may be stored on disk or it may already be in the application's memory.
+
+ @return The size of the data.
+ */
+- (unsigned long long)fileSize {
+ if (_fileURL) {
+ // Data in file
+ NSString *path = [_fileURL path];
+ return [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize;
+ } else if (_data) {
+ // Data in memory
+ return _data.length;
+ }
+ return 0;
+}
#pragma mark - File Type
@@ -121,7 +155,6 @@ NS_ASSUME_NONNULL_BEGIN
}
}
-
#pragma mark - NSCopying
- (id)copyWithZone:(nullable NSZone *)zone {
diff --git a/SmartDeviceLink/SDLGlobals.h b/SmartDeviceLink/SDLGlobals.h
index 15e08182f..5b9220398 100644
--- a/SmartDeviceLink/SDLGlobals.h
+++ b/SmartDeviceLink/SDLGlobals.h
@@ -8,20 +8,31 @@
#import <Foundation/Foundation.h>
+#import "SDLProtocolHeader.h"
+
NS_ASSUME_NONNULL_BEGIN
#define SDL_SYSTEM_VERSION_LESS_THAN(version) ([[[UIDevice currentDevice] systemVersion] compare:version options:NSNumericSearch] == NSOrderedAscending)
#define SDL_SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(version) ([[[UIDevice currentDevice] systemVersion] compare:version options:NSNumericSearch] != NSOrderedAscending)
#define BLOCK_RETURN return
+extern NSString *const SDLMaxProxyProtocolVersion;
+
+extern NSUInteger const SDLDefaultMTUSize;
+extern NSUInteger const SDLV1MTUSize;
+extern NSUInteger const SDLV3MTUSize;
+
@interface SDLGlobals : NSObject
-@property (assign, nonatomic, readonly) NSUInteger protocolVersion;
-@property (assign, nonatomic, readonly) NSUInteger maxMTUSize;
-@property (assign, nonatomic) NSUInteger maxHeadUnitVersion;
+@property (strong, nonatomic, readonly) NSString *protocolVersion;
+@property (assign, nonatomic, readonly) NSInteger majorProtocolVersion;
+@property (strong, nonatomic) NSString *maxHeadUnitVersion;
+ (instancetype)sharedGlobals;
+- (void)setDynamicMTUSize:(NSUInteger)maxMTUSize forServiceType:(SDLServiceType)serviceType;
+- (NSUInteger)mtuSizeForServiceType:(SDLServiceType)serviceType;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLGlobals.m b/SmartDeviceLink/SDLGlobals.m
index 46036d1d4..68f9c0378 100644
--- a/SmartDeviceLink/SDLGlobals.m
+++ b/SmartDeviceLink/SDLGlobals.m
@@ -10,11 +10,22 @@
NS_ASSUME_NONNULL_BEGIN
-static const NSUInteger maxProxyVersion = 4;
+// VERSION DEPENDENT CODE
+NSString *const SDLMaxProxyProtocolVersion = @"5.0.0";
+
+NSUInteger const SDLDefaultMTUSize = UINT32_MAX;
+NSUInteger const SDLV1MTUSize = 1024;
+NSUInteger const SDLV3MTUSize = 131024;
+
+
+typedef NSNumber* ServiceTypeBox;
+typedef NSNumber* MTUBox;
+
@interface SDLGlobals ()
-@property (assign, nonatomic) NSUInteger protocolVersion;
+@property (strong, nonatomic) NSMutableDictionary<ServiceTypeBox, MTUBox> *dynamicMTUDict;
+@property (strong, nonatomic, readwrite) NSString *protocolVersion;
@end
@@ -37,8 +48,9 @@ static const NSUInteger maxProxyVersion = 4;
return nil;
}
- _protocolVersion = 1;
- _maxHeadUnitVersion = 0;
+ _protocolVersion = @"1.0.0";
+ _maxHeadUnitVersion = @"0.0.0";
+ _dynamicMTUDict = [NSMutableDictionary dictionary];
return self;
}
@@ -46,30 +58,57 @@ static const NSUInteger maxProxyVersion = 4;
#pragma mark - Custom Getters / Setters
-- (void)setMaxHeadUnitVersion:(NSUInteger)maxHeadUnitVersion {
- self.protocolVersion = MIN(maxHeadUnitVersion, maxProxyVersion);
+- (void)setMaxHeadUnitVersion:(NSString *)maxHeadUnitVersion {
+ self.protocolVersion = [self sdl_isVersion:maxHeadUnitVersion greaterThanVersion:SDLMaxProxyProtocolVersion] ? SDLMaxProxyProtocolVersion : maxHeadUnitVersion;
_maxHeadUnitVersion = maxHeadUnitVersion;
}
-- (NSUInteger)maxMTUSize {
- switch (self.protocolVersion) {
+- (NSInteger)majorProtocolVersion {
+ return [self.protocolVersion substringWithRange:NSMakeRange(0, 1)].integerValue;
+}
+
+- (void)setDynamicMTUSize:(NSUInteger)maxMTUSize forServiceType:(SDLServiceType)serviceType {
+ self.dynamicMTUDict[@(serviceType)] = @(maxMTUSize);
+}
+
+- (NSUInteger)mtuSizeForServiceType:(SDLServiceType)serviceType {
+ if (self.dynamicMTUDict[@(serviceType)] != nil) {
+ return self.dynamicMTUDict[@(serviceType)].unsignedIntegerValue;
+ } else if (self.dynamicMTUDict[@(SDLServiceTypeRPC)]) {
+ return self.dynamicMTUDict[@(SDLServiceTypeRPC)].unsignedIntegerValue;
+ } else {
+ return [self sdl_defaultMaxMTUSize];
+ }
+}
+
+
+#pragma mark - Helpers
+
+- (BOOL)sdl_isVersion:(NSString *)version1 greaterThanVersion:(NSString *)version2 {
+ return ([version1 compare:version2 options:NSNumericSearch] == NSOrderedDescending);
+}
+
+- (NSUInteger)sdl_defaultMaxMTUSize {
+ // VERSION DEPENDENT CODE
+ switch (self.majorProtocolVersion) {
case 1: // fallthrough
case 2: {
// HAX: This was set to 1024 at some point, for an unknown reason. We can't change it because of backward compatibility & validation concerns. The actual MTU for v1/2 is 1500 bytes.
- return 1024;
+ return SDLV1MTUSize;
} break;
case 3: // fallthrough
- case 4: {
+ case 4: // fallthrough
+ case 5: {
// If the head unit isn't running v3/4, but that's the connection scheme we're using, then we have to know that they could be running an MTU that's not 128k, so we default back to the v1/2 MTU for safety.
- if (self.maxHeadUnitVersion > maxProxyVersion) {
- return 1024;
+ if ([self sdl_isVersion:self.maxHeadUnitVersion greaterThanVersion:SDLMaxProxyProtocolVersion]) {
+ return SDLV1MTUSize;
} else {
- return 131084;
+ return SDLV3MTUSize;
}
} break;
default: {
- NSAssert(NO, @"Unknown version number: %@", @(self.protocolVersion));
+ NSAssert(NO, @"Unknown version number for MTU Size: %@", @(self.majorProtocolVersion));
return 0;
}
}
diff --git a/SmartDeviceLink/SDLIAPTransport.m b/SmartDeviceLink/SDLIAPTransport.m
index cb272e9a2..bc5b06fc0 100644
--- a/SmartDeviceLink/SDLIAPTransport.m
+++ b/SmartDeviceLink/SDLIAPTransport.m
@@ -470,11 +470,11 @@ int const streamOpenTimeoutSeconds = 2;
return ^(NSInputStream *istream) {
__strong typeof(weakSelf) strongSelf = weakSelf;
- uint8_t buf[[SDLGlobals sharedGlobals].maxMTUSize];
+ uint8_t buf[[[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC]];
while (istream.streamStatus == NSStreamStatusOpen && istream.hasBytesAvailable) {
// It is necessary to check the stream status and whether there are bytes available because the dataStreamHasBytesHandler is executed on the IO thread and the accessory disconnect notification arrives on the main thread, causing data to be passed to the delegate while the main thread is tearing down the transport.
- NSInteger bytesRead = [istream read:buf maxLength:[SDLGlobals sharedGlobals].maxMTUSize];
+ NSInteger bytesRead = [istream read:buf maxLength:[[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC]];
NSData *dataIn = [NSData dataWithBytes:buf length:bytesRead];
SDLLogBytes(dataIn, SDLLogBytesDirectionReceive);
diff --git a/SmartDeviceLink/SDLProtocol.h b/SmartDeviceLink/SDLProtocol.h
index a646cef45..ea6df9667 100644
--- a/SmartDeviceLink/SDLProtocol.h
+++ b/SmartDeviceLink/SDLProtocol.h
@@ -18,8 +18,12 @@ extern NSString *const SDLProtocolSecurityErrorDomain;
// Sending
- (void)sendStartSessionWithType:(SDLServiceType)serviceType __deprecated_msg(("Use startServiceWithType: instead"));
-- (void)startServiceWithType:(SDLServiceType)serviceType;
-- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;
+- (void)startServiceWithType:(SDLServiceType)serviceType __deprecated_msg(("Use startServiceWithType:payload: instead"));
+- (void)startServiceWithType:(SDLServiceType)serviceType payload:(nullable NSData *)payload;
+
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL success, NSError *error))completionHandler __deprecated_msg(("Use startSecureServiceWithType:payload:completionHandler instead"));
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType payload:(nullable NSData *)payload completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;
+
- (void)sendEndSessionWithType:(SDLServiceType)serviceType __deprecated_msg(("Use endServiceWithType: instead"));
- (void)endServiceWithType:(SDLServiceType)serviceType;
- (void)sendRPC:(SDLRPCMessage *)message;
diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m
index b318694d0..9d22fa602 100644
--- a/SmartDeviceLink/SDLProtocol.m
+++ b/SmartDeviceLink/SDLProtocol.m
@@ -5,6 +5,10 @@
#import "SDLFunctionID.h"
#import "SDLAbstractTransport.h"
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadNak.h"
+#import "SDLControlFramePayloadRPCStartService.h"
+#import "SDLControlFramePayloadRPCStartServiceAck.h"
#import "SDLLogMacros.h"
#import "SDLGlobals.h"
#import "SDLPrioritizedObjectCollection.h"
@@ -75,19 +79,27 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)sendStartSessionWithType:(SDLServiceType)serviceType {
- [self startServiceWithType:serviceType];
+ [self startServiceWithType:serviceType payload:nil];
}
#pragma mark - Start Service
- (void)startServiceWithType:(SDLServiceType)serviceType {
+ [self startServiceWithType:serviceType payload:nil];
+}
+
+- (void)startServiceWithType:(SDLServiceType)serviceType payload:(nullable NSData *)payload {
// No encryption, just build and send the message synchronously
- SDLProtocolMessage *message = [self sdl_createStartServiceMessageWithType:serviceType encrypted:NO];
+ SDLProtocolMessage *message = [self sdl_createStartServiceMessageWithType:serviceType encrypted:NO payload:payload];
[self sdl_sendDataToTransport:message.data onService:serviceType];
}
- (void)startSecureServiceWithType:(SDLServiceType)serviceType completionHandler:(void (^)(BOOL success, NSError *error))completionHandler {
+ [self startSecureServiceWithType:serviceType payload:nil completionHandler:completionHandler];
+}
+
+- (void)startSecureServiceWithType:(SDLServiceType)serviceType payload:(nullable NSData *)payload completionHandler:(void (^)(BOOL success, NSError *error))completionHandler {
[self sdl_initializeTLSEncryptionWithCompletionHandler:^(BOOL success, NSError *error) {
if (!success) {
// We can't start the service because we don't have encryption, return the error
@@ -96,13 +108,15 @@ NS_ASSUME_NONNULL_BEGIN
}
// TLS initialization succeeded. Build and send the message.
- SDLProtocolMessage *message = [self sdl_createStartServiceMessageWithType:serviceType encrypted:YES];
+ SDLProtocolMessage *message = [self sdl_createStartServiceMessageWithType:serviceType encrypted:YES payload:nil];
[self sdl_sendDataToTransport:message.data onService:serviceType];
}];
}
-- (SDLProtocolMessage *)sdl_createStartServiceMessageWithType:(SDLServiceType)serviceType encrypted:(BOOL)encryption {
- SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].protocolVersion];
+- (SDLProtocolMessage *)sdl_createStartServiceMessageWithType:(SDLServiceType)serviceType encrypted:(BOOL)encryption payload:(nullable NSData *)payload {
+ SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].majorProtocolVersion];
+ NSData *servicePayload = payload;
+
switch (serviceType) {
case SDLServiceTypeRPC: {
// Need a different header for starting the RPC service, we get the session Id from the HU, or its the same as the RPC service's
@@ -112,6 +126,9 @@ NS_ASSUME_NONNULL_BEGIN
} else {
header.sessionID = 0;
}
+
+ SDLControlFramePayloadRPCStartService *startServicePayload = [[SDLControlFramePayloadRPCStartService alloc] initWithVersion:SDLMaxProxyProtocolVersion];
+ servicePayload = startServicePayload.data;
} break;
default: {
header.sessionID = [self sdl_retrieveSessionIDforServiceType:SDLServiceTypeRPC];
@@ -120,11 +137,12 @@ NS_ASSUME_NONNULL_BEGIN
header.frameType = SDLFrameTypeControl;
header.serviceType = serviceType;
header.frameData = SDLFrameInfoStartService;
+ header.bytesInPayload = (UInt32)payload.length;
// Sending a StartSession with the encrypted bit set causes module to initiate SSL Handshake with a ClientHello message, which should be handled by the 'processControlService' method.
header.encrypted = encryption;
- return [SDLProtocolMessage messageWithHeader:header andPayload:nil];
+ return [SDLProtocolMessage messageWithHeader:header andPayload:servicePayload];
}
- (void)sdl_initializeTLSEncryptionWithCompletionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler {
@@ -162,7 +180,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)endServiceWithType:(SDLServiceType)serviceType {
- SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].protocolVersion];
+ SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].majorProtocolVersion];
header.frameType = SDLFrameTypeControl;
header.serviceType = serviceType;
header.frameData = SDLFrameInfoEndService;
@@ -181,7 +199,7 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)sendRPC:(SDLRPCMessage *)message encrypted:(BOOL)encryption error:(NSError *__autoreleasing *)error {
NSParameterAssert(message != nil);
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[message serializeAsDictionary:[SDLGlobals sharedGlobals].protocolVersion] options:kNilOptions error:error];
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[message serializeAsDictionary:[SDLGlobals sharedGlobals].majorProtocolVersion] options:kNilOptions error:error];
if (error != nil) {
SDLLogW(@"Error encoding JSON data: %@", *error);
@@ -192,14 +210,15 @@ NS_ASSUME_NONNULL_BEGIN
// Build the message payload. Include the binary header if necessary
// VERSION DEPENDENT CODE
- switch ([SDLGlobals sharedGlobals].protocolVersion) {
+ switch ([SDLGlobals sharedGlobals].majorProtocolVersion) {
case 1: {
// No binary header in version 1
messagePayload = jsonData;
} break;
case 2: // Fallthrough
case 3: // Fallthrough
- case 4: {
+ case 4: // Fallthrough
+ case 5: {
// Build a binary header
// Serialize the RPC data into an NSData
SDLRPCPayload *rpcPayload = [[SDLRPCPayload alloc] init];
@@ -229,12 +248,12 @@ NS_ASSUME_NONNULL_BEGIN
}
} break;
default: {
- NSAssert(NO, @"Attempting to send an RPC based on an unknown version number: %@, message: %@", @([SDLGlobals sharedGlobals].protocolVersion), message);
+ NSAssert(NO, @"Attempting to send an RPC based on an unknown version number: %@, message: %@", @([SDLGlobals sharedGlobals].majorProtocolVersion), message);
} break;
}
// Build the protocol level header & message
- SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].protocolVersion];
+ SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].majorProtocolVersion];
header.encrypted = encryption;
header.frameType = SDLFrameTypeSingle;
header.serviceType = (message.bulkData.length <= 0) ? SDLServiceTypeRPC : SDLServiceTypeBulkData;
@@ -243,7 +262,7 @@ NS_ASSUME_NONNULL_BEGIN
header.bytesInPayload = (UInt32)messagePayload.length;
// V2+ messages need to have message ID property set.
- if ([SDLGlobals sharedGlobals].protocolVersion >= 2) {
+ if ([SDLGlobals sharedGlobals].majorProtocolVersion >= 2) {
[((SDLV2ProtocolHeader *)header) setMessageID:++_messageID];
}
@@ -251,11 +270,11 @@ NS_ASSUME_NONNULL_BEGIN
SDLProtocolMessage *protocolMessage = [SDLProtocolMessage messageWithHeader:header andPayload:messagePayload];
// See if the message is small enough to send in one transmission. If not, break it up into smaller messages and send.
- if (protocolMessage.size < [SDLGlobals sharedGlobals].maxMTUSize) {
+ if (protocolMessage.size < [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC]) {
SDLLogV(@"Sending protocol message: %@", protocolMessage);
[self sdl_sendDataToTransport:protocolMessage.data onService:SDLServiceTypeRPC];
} else {
- NSArray<SDLProtocolMessage *> *messages = [SDLProtocolMessageDisassembler disassemble:protocolMessage withLimit:[SDLGlobals sharedGlobals].maxMTUSize];
+ NSArray<SDLProtocolMessage *> *messages = [SDLProtocolMessageDisassembler disassemble:protocolMessage withLimit:[[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC]];
for (SDLProtocolMessage *smallerMessage in messages) {
SDLLogV(@"Sending protocol message: %@", smallerMessage);
[self sdl_sendDataToTransport:smallerMessage.data onService:SDLServiceTypeRPC];
@@ -292,7 +311,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)sdl_sendRawData:(NSData *)data onService:(SDLServiceType)service encryption:(BOOL)encryption {
- SDLV2ProtocolHeader *header = [[SDLV2ProtocolHeader alloc] initWithVersion:[SDLGlobals sharedGlobals].protocolVersion];
+ SDLV2ProtocolHeader *header = [[SDLV2ProtocolHeader alloc] initWithVersion:[SDLGlobals sharedGlobals].majorProtocolVersion];
header.encrypted = encryption;
header.frameType = SDLFrameTypeSingle;
header.serviceType = service;
@@ -312,11 +331,11 @@ NS_ASSUME_NONNULL_BEGIN
SDLProtocolMessage *message = [SDLProtocolMessage messageWithHeader:header andPayload:data];
- if (message.size < [SDLGlobals sharedGlobals].maxMTUSize) {
+ if (message.size < [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC]) {
SDLLogV(@"Sending protocol message: %@", message);
[self sdl_sendDataToTransport:message.data onService:header.serviceType];
} else {
- NSArray<SDLProtocolMessage *> *messages = [SDLProtocolMessageDisassembler disassemble:message withLimit:[SDLGlobals sharedGlobals].maxMTUSize];
+ NSArray<SDLProtocolMessage *> *messages = [SDLProtocolMessageDisassembler disassemble:message withLimit:[[SDLGlobals sharedGlobals] mtuSizeForServiceType:service]];
for (SDLProtocolMessage *smallerMessage in messages) {
SDLLogV(@"Sending protocol message: %@", smallerMessage);
[self sdl_sendDataToTransport:smallerMessage.data onService:header.serviceType];
@@ -331,7 +350,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)handleBytesFromTransport:(NSData *)receivedData {
// Initialize the receive buffer which will contain bytes while messages are constructed.
if (self.receiveBuffer == nil) {
- self.receiveBuffer = [NSMutableData dataWithCapacity:(4 * [SDLGlobals sharedGlobals].maxMTUSize)];
+ self.receiveBuffer = [NSMutableData dataWithCapacity:(4 * [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC])];
}
// Save the data
@@ -341,7 +360,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)processMessages {
- UInt8 incomingVersion = [SDLProtocolMessage determineVersion:self.receiveBuffer];
+ UInt8 incomingVersion = [SDLProtocolHeader determineVersion:self.receiveBuffer];
// If we have enough bytes, create the header.
SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:incomingVersion];
@@ -394,65 +413,114 @@ NS_ASSUME_NONNULL_BEGIN
}
}
-- (void)handleProtocolStartSessionACK:(SDLProtocolHeader *)header {
- switch (header.serviceType) {
- case SDLServiceTypeRPC: {
- [SDLGlobals sharedGlobals].maxHeadUnitVersion = header.version;
- } break;
- default:
- break;
+// TODO: This is a v4 packet (create new delegate methods)
+- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK {
+ // V5 Packet
+ if (startServiceACK.header.version >= 5) {
+ switch (startServiceACK.header.serviceType) {
+ case SDLServiceTypeRPC: {
+ SDLControlFramePayloadRPCStartServiceAck *startServiceACKPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithData:startServiceACK.payload];
+// NSLog(@"ServiceAckPayload: %@", startServiceACKPayload);
+
+ if (startServiceACKPayload.mtu != SDLControlFrameInt64NotFound) {
+ [[SDLGlobals sharedGlobals] setDynamicMTUSize:startServiceACKPayload.mtu forServiceType:startServiceACK.header.serviceType];
+ }
+ [SDLGlobals sharedGlobals].maxHeadUnitVersion = (startServiceACKPayload.protocolVersion != nil) ? startServiceACKPayload.protocolVersion : [NSString stringWithFormat:@"%u.0.0", startServiceACK.header.version];
+ // TODO: Hash id?
+ } break;
+ default:
+ break;
+ }
+ } else {
+ // V4 and below packet
+ switch (startServiceACK.header.serviceType) {
+ case SDLServiceTypeRPC: {
+ [SDLGlobals sharedGlobals].maxHeadUnitVersion = [NSString stringWithFormat:@"%u.0.0", startServiceACK.header.version];
+ } break;
+ default:
+ break;
+ }
}
// Store the header of this service away for future use
- self.serviceHeaders[@(header.serviceType)] = [header copy];
+ self.serviceHeaders[@(startServiceACK.header.serviceType)] = [startServiceACK.header copy];
// Pass along to all the listeners
for (id<SDLProtocolListener> listener in self.protocolDelegateTable.allObjects) {
- if ([listener respondsToSelector:@selector(handleProtocolStartSessionACK:)]) {
- [listener handleProtocolStartSessionACK:header];
+ if ([listener respondsToSelector:@selector(handleProtocolStartServiceACKMessage:)]) {
+ [listener handleProtocolStartServiceACKMessage:startServiceACK];
}
- if ([listener respondsToSelector:@selector(handleProtocolStartSessionACK:sessionID:version:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- [listener handleProtocolStartSessionACK:header.serviceType
- sessionID:header.sessionID
- version:header.version];
+ if ([listener respondsToSelector:@selector(handleProtocolStartSessionACK:)]) {
+ [listener handleProtocolStartSessionACK:startServiceACK.header];
+ }
+
+ if ([listener respondsToSelector:@selector(handleProtocolStartSessionACK:sessionID:version:)]) {
+ [listener handleProtocolStartSessionACK:startServiceACK.header.serviceType
+ sessionID:startServiceACK.header.sessionID
+ version:startServiceACK.header.version];
#pragma clang diagnostic pop
}
}
}
-- (void)handleProtocolStartSessionNACK:(SDLServiceType)serviceType {
+- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK {
+ [self sdl_logControlNAKPayload:startServiceNAK];
+
for (id<SDLProtocolListener> listener in self.protocolDelegateTable.allObjects) {
+ if ([listener respondsToSelector:@selector(handleProtocolStartServiceNAKMessage:)]) {
+ [listener handleProtocolStartServiceNAKMessage:startServiceNAK];
+ }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([listener respondsToSelector:@selector(handleProtocolStartSessionNACK:)]) {
- [listener handleProtocolStartSessionNACK:serviceType];
+ [listener handleProtocolStartSessionNACK:startServiceNAK.header.serviceType];
}
+#pragma clang diagnostic pop
}
}
-- (void)handleProtocolEndSessionACK:(SDLServiceType)serviceType {
+- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK {
// Remove the session id
- [self.serviceHeaders removeObjectForKey:@(serviceType)];
+ [self.serviceHeaders removeObjectForKey:@(endServiceACK.header.serviceType)];
for (id<SDLProtocolListener> listener in self.protocolDelegateTable.allObjects) {
+ if ([listener respondsToSelector:@selector(handleProtocolEndServiceACKMessage:)]) {
+ [listener handleProtocolEndServiceACKMessage:endServiceACK];
+ }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([listener respondsToSelector:@selector(handleProtocolEndSessionACK:)]) {
- [listener handleProtocolEndSessionACK:serviceType];
+ [listener handleProtocolEndSessionACK:endServiceACK.header.serviceType];
}
}
+#pragma clang diagnostic pop
}
-- (void)handleProtocolEndSessionNACK:(SDLServiceType)serviceType {
+- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK {
+ [self sdl_logControlNAKPayload:endServiceNAK];
+
for (id<SDLProtocolListener> listener in self.protocolDelegateTable.allObjects) {
+ if ([listener respondsToSelector:@selector(handleProtocolEndServiceNAKMessage:)]) {
+ [listener handleProtocolEndServiceNAKMessage:endServiceNAK];
+ }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([listener respondsToSelector:@selector(handleProtocolEndSessionNACK:)]) {
- [listener handleProtocolEndSessionNACK:serviceType];
+ [listener handleProtocolEndSessionNACK:endServiceNAK.header.serviceType];
}
}
+#pragma clang diagnostic pop
}
- (void)handleHeartbeatForSession:(Byte)session {
// Respond with a heartbeat ACK
- SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].protocolVersion];
+ SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:[SDLGlobals sharedGlobals].majorProtocolVersion];
header.frameType = SDLFrameTypeControl;
header.serviceType = SDLServiceTypeControl;
header.frameData = SDLFrameInfoHeartbeatACK;
@@ -513,6 +581,16 @@ NS_ASSUME_NONNULL_BEGIN
}
}
+- (void)sdl_logControlNAKPayload:(SDLProtocolMessage *)nakMessage {
+ if (nakMessage.header.version >= 5) {
+ SDLControlFramePayloadNak *endServiceNakPayload = [[SDLControlFramePayloadNak alloc] initWithData:nakMessage.payload];
+ NSArray<NSString *> *rejectedParams = endServiceNakPayload.rejectedParams;
+ if (rejectedParams.count > 0) {
+ SDLLogE(@"Start Service NAK'd, service type: %@, rejectedParams: %@", @(nakMessage.header.serviceType), rejectedParams);
+ }
+ }
+}
+
#pragma mark - TLS Handshake
// TODO: These should be split out to a separate class to be tested properly
diff --git a/SmartDeviceLink/SDLProtocolHeader.h b/SmartDeviceLink/SDLProtocolHeader.h
index 750dd590f..cfef757fe 100644
--- a/SmartDeviceLink/SDLProtocolHeader.h
+++ b/SmartDeviceLink/SDLProtocolHeader.h
@@ -59,6 +59,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)parse:(NSData *)data;
- (NSString *)description;
+ (__kindof SDLProtocolHeader *)headerForVersion:(UInt8)version;
++ (UInt8)determineVersion:(NSData *)data;
@end
diff --git a/SmartDeviceLink/SDLProtocolHeader.m b/SmartDeviceLink/SDLProtocolHeader.m
index 6dbf21c38..2c193fecb 100644
--- a/SmartDeviceLink/SDLProtocolHeader.m
+++ b/SmartDeviceLink/SDLProtocolHeader.m
@@ -57,16 +57,26 @@ NS_ASSUME_NONNULL_BEGIN
} break;
case 2: // Fallthrough
case 3: // Fallthrough
- case 4: {
+ case 4: // Fallthrough
+ case 5: {
return [[SDLV2ProtocolHeader alloc] initWithVersion:version];
} break;
default: {
- NSString *reason = [NSString stringWithFormat:@"The version of header that is being created is unknown: %@", @(version)];
- @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:@{ @"requestedVersion": @(version) }];
+ // Assume V2 header for unknown header versions and hope it doesn't break
+ return [[SDLV2ProtocolHeader alloc] initWithVersion:version];
} break;
}
}
+// For use in decoding a stream of bytes.
+// Pass in bytes representing message (or beginning of message)
+// Looks at and parses first byte to determine version.
++ (UInt8)determineVersion:(NSData *)data {
+ UInt8 firstByte = ((UInt8 *)data.bytes)[0];
+ UInt8 version = firstByte >> 4;
+ return version;
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLProtocolListener.h b/SmartDeviceLink/SDLProtocolListener.h
index 20ad1eafd..0657fc2c0 100644
--- a/SmartDeviceLink/SDLProtocolListener.h
+++ b/SmartDeviceLink/SDLProtocolListener.h
@@ -10,11 +10,18 @@ NS_ASSUME_NONNULL_BEGIN
@protocol SDLProtocolListener <NSObject>
@optional
-- (void)handleProtocolStartSessionACK:(SDLServiceType)serviceType sessionID:(Byte)sessionID version:(Byte)version __deprecated_msg("use handleProtocolStartSessionACK: instead");
-- (void)handleProtocolStartSessionACK:(SDLProtocolHeader *)header;
-- (void)handleProtocolStartSessionNACK:(SDLServiceType)serviceType;
-- (void)handleProtocolEndSessionACK:(SDLServiceType)serviceType;
-- (void)handleProtocolEndSessionNACK:(SDLServiceType)serviceType;
+// v4.7.0 protocol handlers
+- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK;
+- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK;
+- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK;
+- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK;
+
+// Older protocol handlers
+- (void)handleProtocolStartSessionACK:(SDLServiceType)serviceType sessionID:(Byte)sessionID version:(Byte)version __deprecated_msg("use handleProtocolStartSessionACKMessage: instead");
+- (void)handleProtocolStartSessionACK:(SDLProtocolHeader *)header __deprecated_msg("use handleProtocolStartSessionACKMessage: instead");
+- (void)handleProtocolStartSessionNACK:(SDLServiceType)serviceType __deprecated_msg("use handleProtocolStartSessionNAKMessage: instead");
+- (void)handleProtocolEndSessionACK:(SDLServiceType)serviceType __deprecated_msg("use handleProtocolEndSessionACKMessage: instead");
+- (void)handleProtocolEndSessionNACK:(SDLServiceType)serviceType __deprecated_msg("use handleProtocolEndSessionNAKMessage: instead");
- (void)handleHeartbeatForSession:(Byte)session;
- (void)handleHeartbeatACK;
- (void)onProtocolMessageReceived:(SDLProtocolMessage *)msg;
diff --git a/SmartDeviceLink/SDLProtocolMessage.h b/SmartDeviceLink/SDLProtocolMessage.h
index c4400a8c7..893c6ee09 100644
--- a/SmartDeviceLink/SDLProtocolMessage.h
+++ b/SmartDeviceLink/SDLProtocolMessage.h
@@ -13,13 +13,13 @@ NS_ASSUME_NONNULL_BEGIN
@property (nullable, strong, nonatomic) NSData *payload;
@property (strong, nonatomic, readonly) NSData *data;
-+ (id)messageWithHeader:(SDLProtocolHeader *)header andPayload:(nullable NSData *)payload; // Returns a V1 or V2 object
++ (instancetype)messageWithHeader:(SDLProtocolHeader *)header andPayload:(nullable NSData *)payload; // Returns a V1 or V2 object
- (NSUInteger)size;
- (NSString *)description;
- (nullable NSDictionary<NSString *, id> *)rpcDictionary; // Use for RPC type messages to obtain the data in a dictionary
-+ (UInt8)determineVersion:(NSData *)data;
++ (UInt8)determineVersion:(NSData *)data __deprecated_msg(("Use SDLProtocolHeader determineVersion: instead"));
@end
diff --git a/SmartDeviceLink/SDLProtocolMessage.m b/SmartDeviceLink/SDLProtocolMessage.m
index 3b6e023ff..b4a5fb5d9 100644
--- a/SmartDeviceLink/SDLProtocolMessage.m
+++ b/SmartDeviceLink/SDLProtocolMessage.m
@@ -16,19 +16,20 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLProtocolMessage
-// For use in decoding a stream of bytes.
-// Pass in bytes representing message (or beginning of message)
-// Looks at and parses first byte to determine version.
-+ (UInt8)determineVersion:(NSData *)data {
- UInt8 firstByte = ((UInt8 *)data.bytes)[0];
- UInt8 version = firstByte >> 4;
- return version;
-}
+// Returns a V1 or V2 object
++ (instancetype)messageWithHeader:(SDLProtocolHeader *)header andPayload:(nullable NSData *)payload {
+ SDLProtocolMessage *newMessage = nil;
-- (instancetype)init {
- if (self = [super init]) {
+ UInt8 version = header.version;
+ if (version == 1) {
+ newMessage = [[SDLV1ProtocolMessage alloc] initWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload];
+ } else if (version >= 2) {
+ newMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload];
+ } else {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Attempted to create an SDLMessage, but the version of the header passed was 0" userInfo:nil];
}
- return self;
+
+ return newMessage;
}
- (nullable NSDictionary<NSString *, id> *)rpcDictionary {
@@ -48,6 +49,10 @@ NS_ASSUME_NONNULL_BEGIN
return dataOut;
}
++ (UInt8)determineVersion:(NSData *)data {
+ return [SDLProtocolHeader determineVersion:data];
+}
+
- (NSString *)description {
// Print the header data.
NSMutableString *description = [[NSMutableString alloc] init];
@@ -81,22 +86,6 @@ NS_ASSUME_NONNULL_BEGIN
return description;
}
-// Returns a V1 or V2 object
-+ (id)messageWithHeader:(SDLProtocolHeader *)header andPayload:(nullable NSData *)payload {
- SDLProtocolMessage *newMessage = nil;
-
- UInt8 version = header.version;
- if (version == 1) {
- newMessage = [[SDLV1ProtocolMessage alloc] initWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload];
- } else if (version >= 2) {
- newMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload];
- } else {
- @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Attempted to create an SDLMessage, but the version of the header passed was 0" userInfo:nil];
- }
-
- return newMessage;
-}
-
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m
index 67b7709d6..cb12229cf 100644
--- a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m
+++ b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m
@@ -53,32 +53,23 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sdl_dispatchControlMessage:(SDLProtocolMessage *)message {
switch (message.header.frameData) {
case SDLFrameInfoStartServiceACK: {
- if ([self.delegate respondsToSelector:@selector(handleProtocolStartSessionACK:sessionID:version:)]) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- [self.delegate handleProtocolStartSessionACK:message.header.serviceType
- sessionID:message.header.sessionID
- version:message.header.version];
-#pragma clang diagnostic pop
- }
-
- if ([self.delegate respondsToSelector:@selector(handleProtocolStartSessionACK:)]) {
- [self.delegate handleProtocolStartSessionACK:message.header];
+ if ([self.delegate respondsToSelector:@selector(handleProtocolStartServiceACKMessage:)]) {
+ [self.delegate handleProtocolStartServiceACKMessage:message];
}
} break;
case SDLFrameInfoStartServiceNACK: {
- if ([self.delegate respondsToSelector:@selector(handleProtocolStartSessionNACK:)]) {
- [self.delegate handleProtocolStartSessionNACK:message.header.serviceType];
+ if ([self.delegate respondsToSelector:@selector(handleProtocolStartServiceNAKMessage:)]) {
+ [self.delegate handleProtocolStartServiceNAKMessage:message];
}
} break;
case SDLFrameInfoEndServiceACK: {
- if ([self.delegate respondsToSelector:@selector(handleProtocolEndSessionACK:)]) {
- [self.delegate handleProtocolEndSessionACK:message.header.serviceType];
+ if ([self.delegate respondsToSelector:@selector(handleProtocolEndServiceACKMessage:)]) {
+ [self.delegate handleProtocolEndServiceACKMessage:message];
}
} break;
case SDLFrameInfoEndServiceNACK: {
- if ([self.delegate respondsToSelector:@selector(handleProtocolStartSessionNACK:)]) {
- [self.delegate handleProtocolEndSessionNACK:message.header.serviceType];
+ if ([self.delegate respondsToSelector:@selector(handleProtocolStartServiceNAKMessage:)]) {
+ [self.delegate handleProtocolEndServiceNAKMessage:message];
}
} break;
case SDLFrameInfoHeartbeat: {
@@ -91,7 +82,7 @@ NS_ASSUME_NONNULL_BEGIN
[self.delegate handleHeartbeatACK];
}
} break;
- default: break;
+ default: break; // Other frame data is possible, but we don't care about them
}
}
diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m
index a86d57980..b933011a0 100644
--- a/SmartDeviceLink/SDLProxy.m
+++ b/SmartDeviceLink/SDLProxy.m
@@ -352,7 +352,7 @@ static float DefaultConnectionTimeout = 45.0;
self.protocol.securityManager.appId = self.appId;
}
- if ([SDLGlobals sharedGlobals].protocolVersion >= 4) {
+ if ([SDLGlobals sharedGlobals].majorProtocolVersion >= 4) {
[self sendMobileHMIState];
// Send SDL updates to application state
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendMobileHMIState) name:UIApplicationDidBecomeActiveNotification object:nil];
@@ -743,7 +743,7 @@ static float DefaultConnectionTimeout = 45.0;
// Grab some bytes from the stream and send them in a SDLPutFile RPC Request
NSUInteger currentStreamOffset = [[stream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedIntegerValue];
- NSMutableData *buffer = [NSMutableData dataWithLength:[SDLGlobals sharedGlobals].maxMTUSize];
+ NSMutableData *buffer = [NSMutableData dataWithLength:[[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC]];
NSUInteger nBytesRead = [(NSInputStream *)stream read:(uint8_t *)buffer.mutableBytes maxLength:buffer.length];
if (nBytesRead > 0) {
NSData *data = [buffer subdataWithRange:NSMakeRange(0, nBytesRead)];
diff --git a/SmartDeviceLink/SDLUploadFileOperation.h b/SmartDeviceLink/SDLUploadFileOperation.h
index 5b3d55f24..40c4b36c4 100644
--- a/SmartDeviceLink/SDLUploadFileOperation.h
+++ b/SmartDeviceLink/SDLUploadFileOperation.h
@@ -11,6 +11,7 @@
#import "SDLAsynchronousOperation.h"
#import "SDLFileManagerConstants.h"
+
@protocol SDLConnectionManagerType;
@class SDLFileWrapper;
@@ -32,4 +33,4 @@ NS_ASSUME_NONNULL_BEGIN
@end
-NS_ASSUME_NONNULL_END \ No newline at end of file
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUploadFileOperation.m b/SmartDeviceLink/SDLUploadFileOperation.m
index b1648bd4c..44af473ce 100644
--- a/SmartDeviceLink/SDLUploadFileOperation.m
+++ b/SmartDeviceLink/SDLUploadFileOperation.m
@@ -9,6 +9,7 @@
#import "SDLUploadFileOperation.h"
#import "SDLConnectionManagerType.h"
+#import "SDLError.h"
#import "SDLFile.h"
#import "SDLFileWrapper.h"
#import "SDLGlobals.h"
@@ -21,11 +22,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - SDLUploadFileOperation
-@interface SDLUploadFileOperation ()
+@interface SDLUploadFileOperation () <NSStreamDelegate>
@property (strong, nonatomic) SDLFileWrapper *fileWrapper;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
-
@end
@@ -52,111 +52,183 @@ NS_ASSUME_NONNULL_BEGIN
- (void)start {
[super start];
- [self sdl_sendPutFiles:[self.class sdl_splitFile:self.fileWrapper.file mtuSize:[SDLGlobals sharedGlobals].maxMTUSize] withCompletion:self.fileWrapper.completionHandler];
+ [self sdl_sendFile:self.fileWrapper.file mtuSize:[[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeRPC] withCompletion:self.fileWrapper.completionHandler];
}
-- (void)sdl_sendPutFiles:(NSArray<SDLPutFile *> *)putFiles withCompletion:(SDLFileManagerUploadCompletionHandler)completion {
- __block BOOL stop = NO;
+/**
+ Sends data asynchronously to the SDL Core by breaking the data into smaller packets, each of which is sent via a putfile. To prevent large files from eating up memory, the data packet is deleted once it is sent via a putfile. If the SDL Core receives all the putfiles successfully, a success response with the amount of free storage space left on the SDL Core is returned. Otherwise the error returned by the SDL Core is passed along.
+
+ @param file The file containing the data to be sent to the SDL Core
+ @param mtuSize The maximum packet size allowed
+ @param completion Closure returning whether or not the upload was a success
+ */
+- (void)sdl_sendFile:(SDLFile *)file mtuSize:(NSUInteger)mtuSize withCompletion:(SDLFileManagerUploadCompletionHandler)completion {
__block NSError *streamError = nil;
__block NSUInteger bytesAvailable = 0;
__block NSInteger highestCorrelationIDReceived = -1;
+ NSInputStream *inputStream = [self sdl_openInputStreamWithFile:file];
+
+ // If the file does not exist or the passed data is nil, return an error
+ if (inputStream == nil) {
+ return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
+ }
+
dispatch_group_t putFileGroup = dispatch_group_create();
dispatch_group_enter(putFileGroup);
- // When the putfiles all complete, run this block
+ // Waits for all packets be sent before returning whether or not the upload was a success
__weak typeof(self) weakself = self;
dispatch_group_notify(putFileGroup, dispatch_get_main_queue(), ^{
- if (streamError != nil || stop) {
+ typeof(weakself) strongself = weakself;
+ if (streamError != nil || strongself.isCancelled) {
completion(NO, bytesAvailable, streamError);
} else {
completion(YES, bytesAvailable, nil);
}
-
[weakself finishOperation];
});
- for (SDLPutFile *putFile in putFiles) {
+ // Break the data into small pieces, each of which will be sent in a separate putfile
+ NSUInteger currentOffset = 0;
+ for (int i = 0; i < (((file.fileSize - 1) / mtuSize) + 1); i++) {
dispatch_group_enter(putFileGroup);
+
+ // The putfile's length parameter is based on the current offset
+ SDLPutFile *putFile = [[SDLPutFile alloc] initWithFileName:file.name fileType:file.fileType persistentFile:file.isPersistent];
+ putFile.offset = @(currentOffset);
+ putFile.length = @([[self class] sdl_getPutFileLengthForOffset:currentOffset fileSize:file.fileSize mtuSize:mtuSize]);
+
+ // Get a chunk of data from the input stream
+ NSUInteger dataSize = [[self class] sdl_getDataSizeForOffset:currentOffset fileSize:file.fileSize mtuSize:mtuSize];
+ putFile.bulkData = [[self class] sdl_getDataChunkWithSize:dataSize inputStream:inputStream];
+ currentOffset += dataSize;
+
__weak typeof(self) weakself = self;
- [self.connectionManager sendManagerRequest:putFile
- withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
- typeof(weakself) strongself = weakself;
- // If we've already encountered an error, then just abort
- // TODO: Is this the right way to handle this case? Should we just abort everything in the future? Should we be deleting what we sent? Should we have an automatic retry strategy based on what the error was?
- if (strongself.isCancelled) {
- stop = YES;
- }
-
- if (stop) {
- dispatch_group_leave(putFileGroup);
- BLOCK_RETURN;
- }
-
- // If we encounted an error, abort in the future and call the completion handler
- if (error != nil || response == nil || ![response.success boolValue]) {
- stop = YES;
- streamError = error;
-
- dispatch_group_leave(putFileGroup);
- BLOCK_RETURN;
- }
-
- // If we haven't encounted an error
- SDLPutFileResponse *putFileResponse = (SDLPutFileResponse *)response;
-
- // We need to do this to make sure our bytesAvailable is accurate
- if ([request.correlationID integerValue] > highestCorrelationIDReceived) {
- highestCorrelationIDReceived = [request.correlationID integerValue];
- bytesAvailable = [putFileResponse.spaceAvailable unsignedIntegerValue];
- }
-
- dispatch_group_leave(putFileGroup);
- }];
+ [self.connectionManager sendManagerRequest:putFile withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
+ typeof(weakself) strongself = weakself;
+
+ // Check if the upload process has been cancelled by another packet. If so, stop the upload process.
+ // TODO: Is this the right way to handle this case? Should we just abort everything in the future? Should we be deleting what we sent? Should we have an automatic retry strategy based on what the error was?
+ if (strongself.isCancelled) {
+ dispatch_group_leave(putFileGroup);
+ BLOCK_RETURN;
+ }
+
+ // If the SDL Core returned an error, cancel the upload the process in the future
+ if (error != nil || response == nil || ![response.success boolValue] || strongself.isCancelled) {
+ [strongself cancel];
+ streamError = error;
+ dispatch_group_leave(putFileGroup);
+ BLOCK_RETURN;
+ }
+
+ // If no errors, watch for a response containing the amount of storage left on the SDL Core
+ if ([[self class] sdl_newHighestCorrelationID:request highestCorrelationIDReceived:highestCorrelationIDReceived]) {
+ highestCorrelationIDReceived = [request.correlationID integerValue];
+ bytesAvailable = [(SDLPutFileResponse *)response spaceAvailable].unsignedIntegerValue;
+ }
+
+ dispatch_group_leave(putFileGroup);
+ }];
}
-
dispatch_group_leave(putFileGroup);
}
-+ (NSArray<SDLPutFile *> *)sdl_splitFile:(SDLFile *)file mtuSize:(NSUInteger)mtuSize {
- NSData *fileData = [file.data copy];
- NSUInteger currentOffset = 0;
- NSMutableArray<SDLPutFile *> *putFiles = [NSMutableArray array];
+/**
+ Opens a socket for reading data.
+
+ @param file The file containing the data or the file url of the data
+ */
+- (NSInputStream *)sdl_openInputStreamWithFile:(SDLFile *)file {
+ NSInputStream *inputStream = file.inputStream;
+ [inputStream setDelegate:self];
+ [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
+ forMode:NSDefaultRunLoopMode];
+ [inputStream open];
+ return inputStream;
+}
- // http://stackoverflow.com/a/503201 Make sure we get the exact number of packets we need
- for (int i = 0; i < (((fileData.length - 1) / mtuSize) + 1); i++) {
- SDLPutFile *putFile = [[SDLPutFile alloc] initWithFileName:file.name fileType:file.fileType persistentFile:file.isPersistent];
- putFile.offset = @(currentOffset);
+/**
+ Returns the length of the data being sent in the putfile. The first putfile's length is unique in that it sends the full size of the data. For the rest of the putfiles, the length parameter is equal to the size of the chunk of data being sent in the putfile.
+
+ @param currentOffset The current position in the file
+ @param fileSize The size of the file
+ @param mtuSize The maximum packet size allowed
+ @return The the length of the data being sent in the putfile
+ */
++ (NSUInteger)sdl_getPutFileLengthForOffset:(NSUInteger)currentOffset fileSize:(unsigned long long)fileSize mtuSize:(NSUInteger)mtuSize {
+ NSInteger putFileLength = 0;
+ if (currentOffset == 0) {
+ // The first putfile sends the full file size
+ putFileLength = (NSInteger)fileSize;
+ } else if ((fileSize - currentOffset) < mtuSize) {
+ // The last putfile sends the size of the remaining data
+ putFileLength = (NSInteger)(fileSize - currentOffset);
+ } else {
+ // All other putfiles send the maximum allowed packet size
+ putFileLength = mtuSize;
+ }
+ return putFileLength;
+}
- // Set the length putfile based on the offset
- if (currentOffset == 0) {
- // If the offset is 0, the putfile expects to have the full file length within it
- putFile.length = @(fileData.length);
- } else if ((fileData.length - currentOffset) < mtuSize) {
- // The file length remaining is less than our total MTU size, so use the file length remaining
- putFile.length = @(fileData.length - currentOffset);
- } else {
- // The file length remaining is greater than our total MTU size, and the offset is not zero, we will fill the packet with our max MTU size
- putFile.length = @(mtuSize);
- }
+/**
+ Gets the size of the data to be sent in a packet. Packet size can not be greater than the max MTU size allowed by the SDL Core.
+
+ @param currentOffset The position in the file where to start reading data
+ @param fileSize The size of the file
+ @param mtuSize The maximum packet size allowed
+ @return The size of the data to be sent in the packet.
+ */
++ (NSUInteger)sdl_getDataSizeForOffset:(NSUInteger)currentOffset fileSize:(unsigned long long)fileSize mtuSize:(NSUInteger)mtuSize {
+ NSInteger dataSize = 0;
+ NSUInteger fileSizeRemaining = (NSUInteger)(fileSize - currentOffset);
+ if (fileSizeRemaining < mtuSize) {
+ dataSize = fileSizeRemaining;
+ } else {
+ dataSize = mtuSize;
+ }
+ return dataSize;
+}
- // Place the data and set the new offset
- if (currentOffset == 0 && (mtuSize < [putFile.length unsignedIntegerValue])) {
- putFile.bulkData = [fileData subdataWithRange:NSMakeRange(currentOffset, mtuSize)];
- currentOffset = mtuSize;
- } else {
- putFile.bulkData = [fileData subdataWithRange:NSMakeRange(currentOffset, [putFile.length unsignedIntegerValue])];
- currentOffset += [putFile.length unsignedIntegerValue];
- }
+/**
+ Reads a chunk of data from a socket.
- [putFiles addObject:putFile];
+ @param size The amount of data to read from the input stream
+ @param inputStream The socket from which to read the data
+ @return The data read from the socket
+ */
++ (nullable NSData *)sdl_getDataChunkWithSize:(NSInteger)size inputStream:(NSInputStream *)inputStream {
+ if (size <= 0) {
+ return nil;
+ }
+
+ Byte buffer[size];
+ NSInteger bytesRead = [inputStream read:buffer maxLength:size];
+ if (bytesRead) {
+ return [[NSData alloc] initWithBytes:(const void*)buffer length:size];
+ } else {
+ // TODO: return a custom error?
+ return nil;
}
-
- return putFiles;
}
+/**
+ One of the responses returned by the SDL Core will contain the correct remaining free storage size on the SDL Core. Since communication with the SDL Core is asynchronous, there is no way to predict which response contains the correct bytes available other than to watch for the largest correlation id, since that will be the last response sent by the SDL Core.
+
+ @param request The newest response returned by the SDL Core for a putfile
+ @param highestCorrelationIDReceived The largest currently received correlation id
+ @return Whether or not the newest request contains the highest correlationId
+ */
++ (BOOL)sdl_newHighestCorrelationID:(SDLRPCRequest *)request highestCorrelationIDReceived:(NSInteger)highestCorrelationIDReceived {
+ if ([request.correlationID integerValue] > highestCorrelationIDReceived) {
+ return true;
+ }
+
+ return false;
+}
-#pragma mark Property Overrides
+#pragma mark - Property Overrides
- (nullable NSString *)name {
return self.fileWrapper.file.name;
@@ -166,6 +238,19 @@ NS_ASSUME_NONNULL_BEGIN
return NSOperationQueuePriorityNormal;
}
+#pragma mark - NSStreamDelegate
+
+- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
+ switch (eventCode) {
+ case NSStreamEventEndEncountered:
+ // Close the input stream once all the data has been read
+ [aStream close];
+ [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ default:
+ break;
+ }
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLV2ProtocolHeader.m b/SmartDeviceLink/SDLV2ProtocolHeader.m
index 9b179ec75..edb6a060e 100644
--- a/SmartDeviceLink/SDLV2ProtocolHeader.m
+++ b/SmartDeviceLink/SDLV2ProtocolHeader.m
@@ -107,7 +107,7 @@ const int V2PROTOCOL_HEADERSIZE = 12;
}
NSMutableString *description = [[NSMutableString alloc] init];
- [description appendFormat:@"Version:%i, compressed:%i, frameType:%@(%i), serviceType:%i, frameData:%@(%i), sessionID:%i, dataSize:%i, messageID:%i ",
+ [description appendFormat:@"Version:%i, encrypted:%i, frameType:%@(%i), serviceType:%i, frameData:%@(%i), sessionID:%i, dataSize:%i, messageID:%i ",
self.version,
self.encrypted,
frameTypeString,
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
index b0ecb8bb9..4c8756f78 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
@@ -235,8 +235,8 @@ describe(@"SDLFileManager", ^{
});
it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).to(equal(testResponseBytesAvailable));
- expect(@(completionSuccess)).to(equal(@YES));
+ expect(@(completionBytesAvailable)).toEventually(equal(testResponseBytesAvailable));
+ expect(@(completionSuccess)).toEventually(equal(@YES));
expect(completionError).to(beNil());
});
});
@@ -266,7 +266,7 @@ describe(@"SDLFileManager", ^{
it(@"should call the completion handler with the correct data", ^{
expect(@(completionBytesAvailable)).to(equal(@0));
expect(@(completionSuccess)).to(equal(testResponseSuccess));
- expect(completionError).to(beNil());
+ expect(completionError).toEventually(beNil());
});
});
@@ -356,8 +356,8 @@ describe(@"SDLFileManager", ^{
});
it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).to(equal(testResponseBytesAvailable));
- expect(@(completionSuccess)).to(equal(@YES));
+ expect(@(completionBytesAvailable)).toEventually(equal(testResponseBytesAvailable));
+ expect(@(completionSuccess)).toEventually(equal(@YES));
expect(completionError).to(beNil());
});
});
@@ -389,7 +389,7 @@ describe(@"SDLFileManager", ^{
it(@"should call the completion handler with the correct data", ^{
expect(@(completionBytesAvailable)).to(equal(@0));
expect(@(completionSuccess)).to(equal(testResponseSuccess));
- expect(completionError).to(beNil());
+ expect(completionError).toEventually(beNil());
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFileSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFileSpec.m
index c994c00a9..7e92db8af 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLFileSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFileSpec.m
@@ -16,7 +16,7 @@ describe(@"SDLFile", ^{
__block NSString *testFileType = nil;
__block BOOL testPersistence = NO;
- context(@"using test data", ^{
+ context(@"using data", ^{
testName = @"Example Name";
testData = [@"Example Data" dataUsingEncoding:NSUTF8StringEncoding];
testFileType = @"mp3";
@@ -34,6 +34,10 @@ describe(@"SDLFile", ^{
it(@"should correctly store data", ^{
expect(testFile.data).to(equal(testData));
});
+
+ it(@"should correctly store persistance", ^{
+ expect(testFile.persistent).to(equal(@YES));
+ });
it(@"should correctly store name", ^{
expect(testFile.name).to(equal(testName));
@@ -49,7 +53,7 @@ describe(@"SDLFile", ^{
});
});
- context(@"when created with a file", ^{
+ context(@"when created with a file url", ^{
__block NSURL *testFileURL = nil;
__block NSString *testFileName = nil;
@@ -62,7 +66,7 @@ describe(@"SDLFile", ^{
testFile = [[SDLFile alloc] initWithFileURL:testFileURL name:testFileName persistent:NO];
});
- it(@"should be nil", ^{
+ it(@"it should be nil", ^{
expect(testFile).to(beNil());
});
});
@@ -76,16 +80,20 @@ describe(@"SDLFile", ^{
testFile = [SDLFile fileAtFileURL:testFileURL name:testFileName];
});
-
- it(@"should correctly store data", ^{
- expect(testFile.data).to(equal([NSData dataWithContentsOfURL:testFileURL]));
+
+ it(@"should correctly store the file url", ^{
+ expect(testFile.fileURL).to(equal(testFileURL));
+ });
+
+ it(@"should not store any data", ^{
+ expect(testFile.data.length).to(beGreaterThan(0));
});
- it(@"should correctly store name", ^{
+ it(@"should correctly store the file name", ^{
expect(testFile.name).to(match(testFileName));
});
- it(@"should correctly store file type", ^{
+ it(@"should correctly store the file type", ^{
expect(testFile.fileType).to(equal(SDLFileTypeJPEG));
});
@@ -106,11 +114,15 @@ describe(@"SDLFile", ^{
testFile = [SDLFile persistentFileAtFileURL:testFileURL name:testFileName];
});
-
- it(@"should correctly store data", ^{
- expect(testFile.data).to(equal([NSData dataWithContentsOfURL:testFileURL]));
+
+ it(@"should correctly store the file url", ^{
+ expect(testFile.fileURL).to(equal(testFileURL));
});
-
+
+ it(@"should not store any data", ^{
+ expect(testFile.data.length).to(beGreaterThan(0));
+ });
+
it(@"should correctly store name", ^{
expect(testFile.name).to(equal(testFileName));
});
@@ -213,6 +225,19 @@ describe(@"SDLFile", ^{
expect(testFile.fileType).to(equal(SDLFileTypeBinary));
});
});
+
+ // FIXME: - Add test cases for audio file types
+ context(@"wav", ^{
+
+ });
+
+ context(@"mp3", ^{
+
+ });
+
+ context(@"aac", ^{
+
+ });
});
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
index c081197a9..6d9474568 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
@@ -13,158 +13,313 @@
QuickSpecBegin(SDLUploadFileOperationSpec)
-describe(@"Upload File Operation", ^{
+describe(@"Streaming upload of data", ^{
__block NSString *testFileName = nil;
__block NSData *testFileData = nil;
__block SDLFile *testFile = nil;
__block SDLFileWrapper *testFileWrapper = nil;
-
+ __block NSInteger numberOfPutFiles = 0;
+
__block TestConnectionManager *testConnectionManager = nil;
__block SDLUploadFileOperation *testOperation = nil;
-
+
__block BOOL successResult = NO;
__block NSUInteger bytesAvailableResult = NO;
__block NSError *errorResult = nil;
-
+
beforeEach(^{
- // Set the head unit size small so we have a low MTU size
- [SDLGlobals sharedGlobals].maxHeadUnitVersion = 2;
+ [SDLGlobals sharedGlobals].maxHeadUnitVersion = @"2.0.0";
+
+ testFileName = nil;
+ testFileData = nil;
+ testFile = nil;
+ testFileWrapper = nil;
+ numberOfPutFiles = 0;
+
+ testOperation = nil;
+ testConnectionManager = nil;
+
+ successResult = NO;
+ bytesAvailableResult = NO;
+ errorResult = nil;
+ });
+
+ context(@"When uploading data", ^{
+ context(@"data should be split into smaller packets if too large to send all at once", ^{
+ context(@"both data in memory and on disk can be uploaded", ^{
+ it(@"should split the data from a short chunk of text in memory correctly", ^{
+ testFileName = @"TestSmallMemory";
+ testFileData = [@"test1234" dataUsingEncoding:NSUTF8StringEncoding];
+ testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ });
+
+ it(@"should split the data from a large image in memory correctly", ^{
+ testFileName = @"TestLargeMemory";
+ UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
+ testFileData = UIImageJPEGRepresentation(testImage, 1.0);
+ testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ });
+
+ it(@"should split the data from a small text file correctly", ^{
+ NSString *fileName = @"testFileJSON";
+ testFileName = fileName;
+ NSString *textFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"];
+ NSURL *textFileURL = [[NSURL alloc] initFileURLWithPath:textFilePath];
+ testFile = [SDLFile fileAtFileURL:textFileURL name:fileName];
+ testFileData = [[NSData alloc] initWithContentsOfURL:textFileURL];
+ });
+
+ it(@"should split the data from a large image file correctly", ^{
+ NSString *fileName = @"testImagePNG";
+ testFileName = fileName;
+ NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
+ NSURL *imageFileURL = [[NSURL alloc] initFileURLWithPath:imageFilePath];
+ testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
+
+ // For testing: get data to check if data chunks are being created correctly
+ testFileData = [[NSData alloc] initWithContentsOfURL:imageFileURL];
+ });
+
+ afterEach(^{
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ successResult = success;
+ bytesAvailableResult = bytesAvailable;
+ errorResult = error;
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testConnectionManager = [[TestConnectionManager alloc] init];
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+ });
+ });
+
+ afterEach(^{
+ expect(@(testOperation.queuePriority)).to(equal(@(NSOperationQueuePriorityNormal)));
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+
+ // Test all packets for offset, length, and data
+ for (NSUInteger index = 0; index < numberOfPutFiles; index++) {
+ SDLPutFile *putFile = putFiles[index];
+
+ NSUInteger mtuSize = [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData];
+
+ expect(putFile.offset).to(equal(@(index * mtuSize)));
+ expect(putFile.persistentFile).to(equal(@NO));
+ expect(putFile.syncFileName).to(equal(testFileName));
+ expect(putFile.bulkData).to(equal([testFileData subdataWithRange:NSMakeRange((index * mtuSize), MIN(putFile.length.unsignedIntegerValue, mtuSize))]));
+
+ // Length is used to inform the SDL Core of the total incoming packet size
+ if (index == 0) {
+ // The first putfile sent should have the full file size
+ expect(putFile.length).to(equal(@([testFile fileSize])));
+ } else if (index == numberOfPutFiles - 1) {
+ // The last pufile contains the remaining data size
+ expect(putFile.length).to(equal(@([testFile fileSize] - (index * mtuSize))));
+ } else {
+ // All other putfiles contain the max data size for a putfile packet
+ expect(putFile.length).to(equal(@(mtuSize)));
+ }
+ }
+ });
+ });
+
+ afterEach(^{
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ NSInteger spaceLeft = 11212512;
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(@(successResult)).toEventually(equal(@YES));
+ expect(@(bytesAvailableResult)).toEventually(equal(spaceLeft));
+ expect(errorResult).toEventually(beNil());
+ expect(@(testOperation.finished)).toEventually(equal(@YES));
+ expect(@(testOperation.executing)).toEventually(equal(@NO));
+ });
});
-
- context(@"running a small file operation", ^{
+
+ context(@"When a response to the data upload comes back", ^{
beforeEach(^{
- testFileName = @"test file";
- testFileData = [@"test1234" dataUsingEncoding:NSUTF8StringEncoding];
+ testFileName = @"TestLargeMemory";
+ UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
+ testFileData = UIImageJPEGRepresentation(testImage, 1.0);
testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
successResult = success;
bytesAvailableResult = bytesAvailable;
errorResult = error;
}];
-
+
+ NSUInteger mtuSize = [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / mtuSize) + 1);
+
testConnectionManager = [[TestConnectionManager alloc] init];
testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
-
[testOperation start];
- [NSThread sleepForTimeInterval:0.5];
});
-
- it(@"should have a priority of 'normal'", ^{
- expect(@(testOperation.queuePriority)).to(equal(@(NSOperationQueuePriorityNormal)));
- });
-
- it(@"should send putfiles", ^{
- SDLPutFile *putFile = testConnectionManager.receivedRequests.lastObject;
- expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLPutFile class]));
- expect(putFile.bulkData).to(equal(testFileData));
- expect(putFile.length).to(equal(@(testFileData.length)));
- expect(putFile.offset).to(equal(@0));
- expect(putFile.persistentFile).to(equal(@NO));
- expect(putFile.syncFileName).to(equal(testFileName));
- });
-
- context(@"when a good response comes back", ^{
- __block SDLPutFileResponse *goodResponse = nil;
- __block NSNumber *responseSpaceAvailable = nil;
- __block NSMutableArray<NSString *> *responseFileNames = nil;
-
+
+ context(@"If data was sent successfully", ^{
+ __block SDLPutFileResponse *goodResponse = nil;
+ __block NSInteger spaceLeft = 0;
+
beforeEach(^{
- responseSpaceAvailable = @(11212512);
- responseFileNames = [NSMutableArray arrayWithArray:@[@"test1", @"test2"]];
-
- goodResponse = [[SDLPutFileResponse alloc] init];
- goodResponse.success = @YES;
- goodResponse.spaceAvailable = responseSpaceAvailable;
-
- [testConnectionManager respondToLastRequestWithResponse:goodResponse];
+ goodResponse = nil;
+ spaceLeft = 11212512;
+ });
+
+ it(@"should have called the completion handler with success only if all packets were sent successfully", ^{
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
});
-
- it(@"should have called the completion handler with proper data", ^{
+
+ afterEach(^{
expect(@(successResult)).toEventually(equal(@YES));
- expect(@(bytesAvailableResult)).toEventually(equal(responseSpaceAvailable));
+ expect(@(bytesAvailableResult)).toEventually(equal(spaceLeft));
expect(errorResult).toEventually(beNil());
- });
-
- it(@"should be set to finished", ^{
+
expect(@(testOperation.finished)).toEventually(equal(@YES));
expect(@(testOperation.executing)).toEventually(equal(@NO));
});
});
-
- context(@"when a bad response comes back", ^{
- __block SDLPutFileResponse *badResponse = nil;
- __block NSNumber *responseSpaceAvailable = nil;
-
+
+ context(@"If data was not sent successfully", ^{
+ __block SDLPutFileResponse *response = nil;
__block NSString *responseErrorDescription = nil;
__block NSString *responseErrorReason = nil;
-
+ __block NSInteger spaceLeft = 0;
+
beforeEach(^{
- responseSpaceAvailable = @(0);
-
- responseErrorDescription = @"some description";
- responseErrorReason = @"some reason";
-
- badResponse = [[SDLPutFileResponse alloc] init];
- badResponse.success = @NO;
- badResponse.spaceAvailable = responseSpaceAvailable;
-
- [testConnectionManager respondToLastRequestWithResponse:badResponse error:[NSError sdl_lifecycle_unknownRemoteErrorWithDescription:responseErrorDescription andReason:responseErrorReason]];
+ response = nil;
+ responseErrorDescription = nil;
+ responseErrorReason = nil;
+ spaceLeft = 11212512;
+ });
+
+ it(@"should have called the completion handler with error if the first packet was not sent successfully", ^{
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ response = [[SDLPutFileResponse alloc] init];
+ response.spaceAvailable = @(spaceLeft);
+ NSError *error = nil;
+
+ if (i == 0) {
+ // Only the first packet is sent unsuccessfully
+ response.success = @NO;
+ responseErrorDescription = @"some description";
+ responseErrorReason = @"some reason";
+ error = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:responseErrorDescription andReason:responseErrorReason];
+ } else {
+ response.success = @YES;
+ }
+
+ [testConnectionManager respondToRequestWithResponse:response requestNumber:i error:error];
+ }
});
-
- it(@"should have called completion handler with error", ^{
+
+ it(@"should have called the completion handler with error if the last packet was not sent successfully", ^{
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ response = [[SDLPutFileResponse alloc] init];
+ response.spaceAvailable = @(spaceLeft);
+ NSError *error = nil;
+
+ if (i == (numberOfPutFiles - 1)) {
+ // Only the last packet is sent unsuccessfully
+ response.success = @NO;
+ responseErrorDescription = @"some description";
+ responseErrorReason = @"some reason";
+ error = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:responseErrorDescription andReason:responseErrorReason];
+ } else {
+ response.success = @YES;
+ }
+
+ [testConnectionManager respondToRequestWithResponse:response requestNumber:i error:error];
+ }
+ });
+
+ it(@"should have called the completion handler with error if all packets were not sent successfully", ^{
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ response = [[SDLPutFileResponse alloc] init];
+ response.success = @NO;
+ response.spaceAvailable = @(spaceLeft);
+
+ responseErrorDescription = @"some description";
+ responseErrorReason = @"some reason";
+
+ [testConnectionManager respondToRequestWithResponse:response requestNumber:i error:[NSError sdl_lifecycle_unknownRemoteErrorWithDescription:responseErrorDescription andReason:responseErrorReason]];
+ }
+ });
+
+ afterEach(^{
expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
expect(@(successResult)).toEventually(equal(@NO));
- expect(@(bytesAvailableResult)).toEventually(equal(@0));
});
});
});
-
- context(@"sending a large file", ^{
+
+ context(@"When an incorrect file url is passed", ^{
beforeEach(^{
- UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
-
- testFileName = @"test file";
- testFileData = UIImageJPEGRepresentation(testImage, 0.80);
+ NSString *fileName = @"testImagePNG";
+ testFileName = fileName;
+ NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
+ NSURL *imageFileURL = [[NSURL alloc] initWithString:imageFilePath]; // This will fail because local file paths need to be init with initFileURLWithPath
+ testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ successResult = success;
+ bytesAvailableResult = bytesAvailable;
+ errorResult = error;
+ }];
+
+ testConnectionManager = [[TestConnectionManager alloc] init];
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+ });
+
+ it(@"should have called the completion handler with an error", ^{
+ expect(errorResult).toEventually(equal([NSError sdl_fileManager_fileDoesNotExistError]));
+ expect(@(successResult)).toEventually(equal(@NO));
+ });
+ });
+
+ context(@"When empty data is passed", ^{
+ beforeEach(^{
+ testFileName = @"TestEmptyMemory";
+ testFileData = [@"" dataUsingEncoding:NSUTF8StringEncoding];
testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+
testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
successResult = success;
bytesAvailableResult = bytesAvailable;
errorResult = error;
}];
-
+
testConnectionManager = [[TestConnectionManager alloc] init];
testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
-
[testOperation start];
- [NSThread sleepForTimeInterval:0.5];
});
-
- it(@"should send correct putfiles", ^{
- NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
-
- NSUInteger numberOfPutFiles = (((testFileData.length - 1) / [SDLGlobals sharedGlobals].maxMTUSize) + 1);
- expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
-
- // Test all PutFiles pieces for offset & length.
- for (NSUInteger index = 0; index < numberOfPutFiles; index++) {
- SDLPutFile *putFile = putFiles[index];
-
- expect(putFile.offset).to(equal(@(index * [SDLGlobals sharedGlobals].maxMTUSize)));
- expect(putFile.persistentFile).to(equal(@NO));
- expect(putFile.syncFileName).to(equal(testFileName));
- expect(putFile.bulkData).to(equal([testFileData subdataWithRange:NSMakeRange((index * [SDLGlobals sharedGlobals].maxMTUSize), MIN(putFile.length.unsignedIntegerValue, [SDLGlobals sharedGlobals].maxMTUSize))]));
-
- // First Putfile has some differences due to informing core of the total incoming packet size.
- if (index == 0) {
- expect(putFile.length).to(equal(@(testFileData.length)));
- } else if (index == numberOfPutFiles - 1) {
- expect(putFile.length).to(equal(@(testFileData.length - (index * [SDLGlobals sharedGlobals].maxMTUSize))));
- } else {
- expect(putFile.length).to(equal(@([SDLGlobals sharedGlobals].maxMTUSize)));
- }
- }
-
+
+ it(@"should have called the completion handler with an error", ^{
+ expect(errorResult).toEventually(equal([NSError sdl_fileManager_fileDoesNotExistError]));
+ expect(@(successResult)).toEventually(equal(@NO));
});
});
});
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadNakSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadNakSpec.m
new file mode 100644
index 000000000..ef0d8fae2
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadNakSpec.m
@@ -0,0 +1,57 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadNak.h"
+
+QuickSpecBegin(SDLControlFramePayloadNakSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadNak *testPayload = nil;
+ __block NSArray<NSString *> *testParams = nil;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testParams = @[@"testParam1", @"testParam2"];
+ testPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:testParams];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<3e000000 0472656a 65637465 64506172 616d7300 29000000 0230000b 00000074 65737450 6172616d 31000231 000b0000 00746573 74506172 616d3200 0000>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testParams = nil;
+ testPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:testParams];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadNak *testPayload = nil;
+ __block NSData *testData = nil;
+ __block NSArray<NSString *> *testParams = nil;
+
+ beforeEach(^{
+ testParams = @[@"testParam1", @"testParam2"];
+
+ SDLControlFramePayloadNak *firstPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:testParams];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadNak alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.rejectedParams).to(equal(testParams));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadVideoStartServiceSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadVideoStartServiceSpec.m
new file mode 100644
index 000000000..1af113777
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFramePayloadVideoStartServiceSpec.m
@@ -0,0 +1,80 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadVideoStartService.h"
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingProtocol.h"
+
+QuickSpecBegin(SDLControlFramePayloadVideoStartServiceSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadVideoStartService *testPayload = nil;
+ __block int32_t testHeight = SDLControlFrameInt32NotFound;
+ __block int32_t testWidth = SDLControlFrameInt32NotFound;
+ __block SDLVideoStreamingCodec testCodec = nil;
+ __block SDLVideoStreamingProtocol testProtocol = nil;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testHeight = 59794;
+ testWidth = 363;
+ testCodec = SDLVideoStreamingCodecH265;
+ testProtocol = SDLVideoStreamingProtocolRTMP;
+
+ testPayload = [[SDLControlFramePayloadVideoStartService alloc] initWithVideoHeight:testHeight width:testWidth protocol:testProtocol codec:testCodec];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<49000000 02766964 656f5072 6f746f63 6f6c0005 00000052 544d5000 10776964 7468006b 01000002 76696465 6f436f64 65630005 00000048 32363500 10686569 67687400 92e90000 00>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testHeight = SDLControlFrameInt32NotFound;
+ testWidth = SDLControlFrameInt32NotFound;
+ testCodec = nil;
+ testProtocol = nil;
+
+ testPayload = [[SDLControlFramePayloadVideoStartService alloc] initWithVideoHeight:testHeight width:testWidth protocol:testProtocol codec:testCodec];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadVideoStartService *testPayload = nil;
+ __block NSData *testData = nil;
+ __block int32_t testHeight = SDLControlFrameInt32NotFound;
+ __block int32_t testWidth = SDLControlFrameInt32NotFound;
+ __block SDLVideoStreamingCodec testCodec = nil;
+ __block SDLVideoStreamingProtocol testProtocol = nil;
+
+ beforeEach(^{
+ testHeight = 787;
+ testWidth = 36365;
+ testCodec = SDLVideoStreamingCodecTheora;
+ testProtocol = SDLVideoStreamingProtocolRTSP;
+
+ SDLControlFramePayloadVideoStartService *firstPayload = [[SDLControlFramePayloadVideoStartService alloc] initWithVideoHeight:testHeight width:testWidth protocol:testProtocol codec:testCodec];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadVideoStartService alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.height).to(equal(testHeight));
+ expect(testPayload.width).to(equal(testWidth));
+ expect(testPayload.videoCodec).to(equal(testCodec));
+ expect(testPayload.videoProtocol).to(equal(testProtocol));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFrameVideoStartServiceAckSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFrameVideoStartServiceAckSpec.m
new file mode 100644
index 000000000..cc7db881c
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/ControlFramePayloadSpecs/SDLControlFrameVideoStartServiceAckSpec.m
@@ -0,0 +1,86 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadVideoStartServiceAck.h"
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingProtocol.h"
+
+QuickSpecBegin(SDLControlFramePayloadVideoStartServiceAckSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadVideoStartServiceAck *testPayload = nil;
+ __block int64_t testMTU = SDLControlFrameInt64NotFound;
+ __block int32_t testHeight = SDLControlFrameInt32NotFound;
+ __block int32_t testWidth = SDLControlFrameInt32NotFound;
+ __block SDLVideoStreamingCodec testCodec = nil;
+ __block SDLVideoStreamingProtocol testProtocol = nil;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testMTU = 1247988;
+ testHeight = 5974;
+ testWidth = 36;
+ testCodec = SDLVideoStreamingCodecH264;
+ testProtocol = SDLVideoStreamingProtocolRAW;
+
+ testPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testHeight width:testWidth protocol:testProtocol codec:testCodec];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<55000000 126d7475 00f40a13 00000000 00027669 64656f50 726f746f 636f6c00 04000000 52415700 10776964 74680024 00000002 76696465 6f436f64 65630005 00000048 32363400 10686569 67687400 56170000 00>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testMTU = SDLControlFrameInt64NotFound;
+ testHeight = SDLControlFrameInt32NotFound;
+ testWidth = SDLControlFrameInt32NotFound;
+ testCodec = nil;
+ testProtocol = nil;
+
+ testPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testHeight width:testWidth protocol:testProtocol codec:testCodec];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadVideoStartServiceAck *testPayload = nil;
+ __block NSData *testData = nil;
+ __block int64_t testMTU = SDLControlFrameInt64NotFound;
+ __block int32_t testHeight = SDLControlFrameInt32NotFound;
+ __block int32_t testWidth = SDLControlFrameInt32NotFound;
+ __block SDLVideoStreamingCodec testCodec = nil;
+ __block SDLVideoStreamingProtocol testProtocol = nil;
+
+ beforeEach(^{
+ testMTU = 4584651;
+ testHeight = 787;
+ testWidth = 36365;
+ testCodec = SDLVideoStreamingCodecVP8;
+ testProtocol = SDLVideoStreamingProtocolRTSP;
+
+ SDLControlFramePayloadVideoStartServiceAck *firstPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testHeight width:testWidth protocol:testProtocol codec:testCodec];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.mtu).to(equal(testMTU));
+ expect(testPayload.height).to(equal(testHeight));
+ expect(testPayload.width).to(equal(testWidth));
+ expect(testPayload.videoCodec).to(equal(testCodec));
+ expect(testPayload.videoProtocol).to(equal(testProtocol));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m
index 12c5e248d..c83cd1242 100644
--- a/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m
+++ b/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m
@@ -26,4 +26,16 @@ describe(@"HeaderForVersion Tests", ^ {
});
});
+describe(@"DetermineVersion Tests", ^ {
+ it(@"Should return the correct version", ^ {
+ const char bytesV1[8] = {0x10 | SDLFrameTypeFirst, SDLServiceTypeBulkData, SDLFrameInfoStartServiceACK, 0x5E, 0x00, 0x00, 0x00, 0x00};
+ NSData* messageV1 = [NSData dataWithBytes:bytesV1 length:8];
+ expect(@([SDLProtocolHeader determineVersion:messageV1])).to(equal(@1));
+
+ const char bytesV2[12] = {0x20 | SDLFrameTypeFirst, SDLServiceTypeBulkData, SDLFrameInfoStartServiceACK, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44};
+ NSData* messageV2 = [NSData dataWithBytes:bytesV2 length:12];
+ expect(@([SDLProtocolHeader determineVersion:messageV2])).to(equal(@2));
+ });
+});
+
QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolMessageSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolMessageSpec.m
index 4ab0eabb8..8c6f03f9c 100644
--- a/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolMessageSpec.m
+++ b/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolMessageSpec.m
@@ -38,18 +38,6 @@ describe(@"MessageWithHeader Tests", ^ {
});
});
-describe(@"DetermineVersion Tests", ^ {
- it(@"Should return the correct version", ^ {
- const char bytesV1[8] = {0x10 | SDLFrameTypeFirst, SDLServiceTypeBulkData, SDLFrameInfoStartServiceACK, 0x5E, 0x00, 0x00, 0x00, 0x00};
- NSData* messageV1 = [NSData dataWithBytes:bytesV1 length:8];
- expect(@([SDLProtocolMessage determineVersion:messageV1])).to(equal(@1));
-
- const char bytesV2[12] = {0x20 | SDLFrameTypeFirst, SDLServiceTypeBulkData, SDLFrameInfoStartServiceACK, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44};
- NSData* messageV2 = [NSData dataWithBytes:bytesV2 length:12];
- expect(@([SDLProtocolMessage determineVersion:messageV2])).to(equal(@2));
- });
-});
-
describe(@"Data tests", ^ {
it(@"Should return the correct data", ^ {
SDLProtocolMessage* testMessage = [[SDLProtocolMessage alloc] init];
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m
index 6562a2349..635dea80d 100644
--- a/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m
+++ b/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m
@@ -52,7 +52,7 @@ describe(@"Send StartService Tests", ^ {
}] sendData:[OCMArg any]];
testProtocol.transport = transportMock;
- [testProtocol startServiceWithType:SDLServiceTypeBulkData];
+ [testProtocol startServiceWithType:SDLServiceTypeBulkData payload:nil];
expect(@(verified)).toEventually(beTruthy());
});
@@ -74,7 +74,7 @@ describe(@"Send EndSession Tests", ^ {
SDLV1ProtocolHeader *testHeader = [[SDLV1ProtocolHeader alloc] init];
testHeader.serviceType = SDLServiceTypeRPC;
testHeader.sessionID = 0x03;
- [testProtocol handleProtocolStartSessionACK:testHeader];
+ [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]];
__block BOOL verified = NO;
id transportMock = OCMClassMock([SDLAbstractTransport class]);
@@ -103,7 +103,7 @@ describe(@"Send EndSession Tests", ^ {
SDLV2ProtocolHeader *testHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:2];
testHeader.serviceType = SDLServiceTypeRPC;
testHeader.sessionID = 0x61;
- [testProtocol handleProtocolStartSessionACK:testHeader];
+ [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]];
__block BOOL verified = NO;
id transportMock = OCMClassMock([SDLAbstractTransport class]);
@@ -141,7 +141,7 @@ describe(@"SendRPCRequest Tests", ^ {
SDLV1ProtocolHeader *testHeader = [[SDLV1ProtocolHeader alloc] init];
testHeader.serviceType = SDLServiceTypeRPC;
testHeader.sessionID = 0xFF;
- [testProtocol handleProtocolStartSessionACK:testHeader];
+ [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]];
__block BOOL verified = NO;
id transportMock = OCMClassMock([SDLAbstractTransport class]);
@@ -181,7 +181,7 @@ describe(@"SendRPCRequest Tests", ^ {
SDLV2ProtocolHeader *testHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:2];
testHeader.serviceType = SDLServiceTypeRPC;
testHeader.sessionID = 0x01;
- [testProtocol handleProtocolStartSessionACK:testHeader];
+ [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]];
__block BOOL verified = NO;
id transportMock = OCMClassMock([SDLAbstractTransport class]);
@@ -339,9 +339,9 @@ xdescribe(@"HandleProtocolSessionStarted Tests", ^ {
testHeader.bytesInPayload = 0;
[testProtocol.protocolDelegateTable addObject:delegateMock];
- [testProtocol handleProtocolStartSessionACK:testHeader];
+ [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]];
- OCMExpect([delegateMock handleProtocolStartSessionACK:testHeader]);
+ OCMExpect([delegateMock handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]);
});
});
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadAudioStartServiceAckSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadAudioStartServiceAckSpec.m
new file mode 100644
index 000000000..a168fc39d
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadAudioStartServiceAckSpec.m
@@ -0,0 +1,60 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadAudioStartServiceAck.h"
+
+QuickSpecBegin(SDLControlFramePayloadAudioStartServiceAckSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadAudioStartServiceAck *testPayload = nil;
+ __block int64_t testMTU = 0;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testMTU = 598464979;
+
+ testPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithMTU:testMTU];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<12000000 126d7475 00d3d9ab 23000000 0000>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testMTU = SDLControlFrameInt64NotFound;
+
+ testPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithMTU:testMTU];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadAudioStartServiceAck *testPayload = nil;
+ __block NSData *testData = nil;
+ __block int64_t testMTU = 0;
+
+ beforeEach(^{
+ testMTU = 989786483;
+
+ SDLControlFramePayloadAudioStartServiceAck *firstPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithMTU:testMTU];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.mtu).to(equal(testMTU));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadEndServiceSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadEndServiceSpec.m
new file mode 100644
index 000000000..8f7a0c3d2
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadEndServiceSpec.m
@@ -0,0 +1,58 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadEndService.h"
+
+QuickSpecBegin(SDLControlFramePayloadEndServiceSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadEndService *testPayload = nil;
+ __block int32_t testHashId = 0;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testHashId = 145768957;
+ testPayload = [[SDLControlFramePayloadEndService alloc] initWithHashId:testHashId];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<11000000 10686173 68496400 fd41b008 00>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testHashId = SDLControlFrameInt32NotFound;
+ testPayload = [[SDLControlFramePayloadEndService alloc] initWithHashId:testHashId];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadEndService *testPayload = nil;
+ __block NSData *testData = nil;
+ __block int32_t testHashId = 0;
+
+ beforeEach(^{
+ testHashId = 15457845;
+
+ SDLControlFramePayloadEndService *firstPayload = [[SDLControlFramePayloadEndService alloc] initWithHashId:testHashId];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadEndService alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.hashId).to(equal(testHashId));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceAckSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceAckSpec.m
new file mode 100644
index 000000000..ee6793249
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceAckSpec.m
@@ -0,0 +1,71 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadRPCStartServiceAck.h"
+
+QuickSpecBegin(SDLControlFramePayloadRPCStartServiceAckSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadRPCStartServiceAck *testPayload = nil;
+ __block int32_t testHashId = 0;
+ __block int64_t testMTU = 0;
+ __block NSString *testProtocolVersion = nil;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testHashId = 1457689;
+ testMTU = 5984649;
+ testProtocolVersion = @"1.32.32";
+
+ testPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithHashId:testHashId mtu:testMTU protocolVersion:testProtocolVersion];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<3b000000 10686173 68496400 193e1600 126d7475 0089515b 00000000 00027072 6f746f63 6f6c5665 7273696f 6e000800 0000312e 33322e33 320000>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testHashId = SDLControlFrameInt32NotFound;
+ testMTU = SDLControlFrameInt64NotFound;
+
+ testPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithHashId:testHashId mtu:testMTU protocolVersion:nil];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadRPCStartServiceAck *testPayload = nil;
+ __block NSData *testData = nil;
+ __block int32_t testHashId = 0;
+ __block int64_t testMTU = 0;
+ __block NSString *testProtocolVersion = nil;
+
+ beforeEach(^{
+ testHashId = 1545784;
+ testMTU = 989786483;
+ testProtocolVersion = @"3.89.5";
+
+ SDLControlFramePayloadRPCStartServiceAck *firstPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithHashId:testHashId mtu:testMTU protocolVersion:testProtocolVersion];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.hashId).to(equal(testHashId));
+ expect(testPayload.mtu).to(equal(testMTU));
+ expect(testPayload.protocolVersion).to(equal(testProtocolVersion));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceSpec.m
new file mode 100644
index 000000000..e8e773c8a
--- /dev/null
+++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLControlFramePayloadRPCStartServiceSpec.m
@@ -0,0 +1,60 @@
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadRPCStartService.h"
+
+QuickSpecBegin(SDLControlFramePayloadRPCStartServiceSpec)
+
+describe(@"Test encoding data", ^{
+ __block SDLControlFramePayloadRPCStartService *testPayload = nil;
+ __block NSString *testProtocolVersion = nil;
+
+ context(@"with paramaters", ^{
+ beforeEach(^{
+ testProtocolVersion = @"74.32.2";
+
+ testPayload = [[SDLControlFramePayloadRPCStartService alloc] initWithVersion:testProtocolVersion];
+ });
+
+ it(@"should create the correct data", ^{
+ expect(testPayload.data.description).to(equal(@"<22000000 0270726f 746f636f 6c566572 73696f6e 00080000 0037342e 33322e32 0000>"));
+ });
+ });
+
+ context(@"without parameters", ^{
+ beforeEach(^{
+ testProtocolVersion = nil;
+
+ testPayload = [[SDLControlFramePayloadRPCStartService alloc] initWithVersion:testProtocolVersion];
+ });
+
+ it(@"should create no data", ^{
+ expect(testPayload.data.length).to(equal(0));
+ });
+ });
+});
+
+describe(@"Test decoding data", ^{
+ __block SDLControlFramePayloadRPCStartService *testPayload = nil;
+ __block NSData *testData = nil;
+ __block NSString *testProtocolVersion = nil;
+
+ beforeEach(^{
+ testProtocolVersion = @"59.63.47";
+
+ SDLControlFramePayloadRPCStartService *firstPayload = [[SDLControlFramePayloadRPCStartService alloc] initWithVersion:testProtocolVersion];
+ testData = firstPayload.data;
+
+ testPayload = [[SDLControlFramePayloadRPCStartService alloc] initWithData:testData];
+ });
+
+ it(@"should output the correct params", ^{
+ expect(testPayload.protocolVersion).to(equal(testProtocolVersion));
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolMessageDisassemblerSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolMessageDisassemblerSpec.m
index c44b0e9d2..9dfc2c32f 100644
--- a/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolMessageDisassemblerSpec.m
+++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolMessageDisassemblerSpec.m
@@ -24,7 +24,7 @@ describe(@"Disassemble Tests", ^ {
char dummyBytes[dataLength];
SDLGlobals *globals = [[SDLGlobals alloc] init];
- globals.maxHeadUnitVersion = 2;
+ globals.maxHeadUnitVersion = @"2.0.0";
const char testPayloadHeader[12] = {0x20, 0x55, 0x64, 0x73, 0x12, 0x34, 0x43, 0x21, (dataLength >> 24) & 0xFF, (dataLength >> 16) & 0xFF, (dataLength >> 8) & 0xFF, dataLength & 0xFF};
@@ -43,7 +43,7 @@ describe(@"Disassemble Tests", ^ {
testMessage.header = testHeader;
testMessage.payload = payloadData;
- NSArray<SDLProtocolMessage *> *messageList = [SDLProtocolMessageDisassembler disassemble:testMessage withLimit:globals.maxMTUSize];
+ NSArray<SDLProtocolMessage *> *messageList = [SDLProtocolMessageDisassembler disassemble:testMessage withLimit:[globals mtuSizeForServiceType:testHeader.serviceType]];
//Payload length per message
UInt32 payloadLength = 1012; // v1/2 MTU(1024) - header length(12)
diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m
index 56617d02f..747a087b1 100644
--- a/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m
+++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m
@@ -38,7 +38,7 @@ describe(@"HandleReceivedMessage Tests", ^ {
router.delegate = delegateMock;
[router handleReceivedMessage:testMessage];
- OCMVerify([delegateMock handleProtocolStartSessionACK:testMessage.header]);
+ OCMVerify([delegateMock handleProtocolStartServiceACKMessage:testMessage]);
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m
index 137f6bca3..0d3b57ece 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m
@@ -16,12 +16,14 @@ describe(@"SDLHMICapabilities struct", ^{
__block SDLHMICapabilities *testStruct = nil;
__block NSNumber *somePhoneCallState = @NO;
__block NSNumber *someNavigationState = @YES;
+ __block NSNumber *someVideoStreamState = @NO;
context(@"When initialized with properties", ^{
beforeEach(^{
testStruct = [[SDLHMICapabilities alloc] init];
testStruct.phoneCall = somePhoneCallState;
testStruct.navigation = someNavigationState;
+ testStruct.videoStreaming = someVideoStreamState;
});
it(@"should properly set phone call", ^{
@@ -31,6 +33,10 @@ describe(@"SDLHMICapabilities struct", ^{
it(@"should properly set navigation", ^{
expect(testStruct.navigation).to(equal(someNavigationState));
});
+
+ it(@"should properly set video streaming", ^{
+ expect(testStruct.videoStreaming).to(equal(someVideoStreamState));
+ });
});
context(@"When initialized with a dictionary", ^{
@@ -49,6 +55,10 @@ describe(@"SDLHMICapabilities struct", ^{
it(@"should properly set navigation", ^{
expect(testStruct.navigation).to(equal(someNavigationState));
});
+
+ it(@"should properly set video streaming", ^{
+ expect(testStruct.videoStreaming).to(equal(someVideoStreamState));
+ });
});
context(@"When not initialized", ^{
@@ -63,6 +73,10 @@ describe(@"SDLHMICapabilities struct", ^{
it(@"navigation should be nil", ^{
expect(testStruct.navigation).to(beNil());
});
+
+ it(@"video streaming should be nil", ^{
+ expect(testStruct.videoStreaming).to(beNil());
+ });
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
index 7511fb7c2..0ab02a693 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
@@ -9,12 +9,13 @@
#import "SDLNavigationCapability.h"
#import "SDLPhoneCapability.h"
#import "SDLSystemCapabilityType.h"
-#import "SDLNames.h"
#import "SDLVideoStreamingCapability.h"
#import "SDLVideoStreamingCodec.h"
#import "SDLVideoStreamingFormat.h"
#import "SDLVideoStreamingProtocol.h"
+#import "SDLNames.h"
+
QuickSpecBegin(SDLSystemCapabilitySpec)
describe(@"Getter/Setter Tests", ^ {
diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h
index 8d240335e..18895a931 100644
--- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h
+++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h
@@ -42,10 +42,19 @@ NS_ASSUME_NONNULL_BEGIN
- (void)respondToLastRequestWithResponse:(__kindof SDLRPCResponse *_Nullable)response error:( NSError *_Nullable)error;
/**
+ * Call the last request's bloack with a specific response, request, and error.
+
+ @param response The RPC Response to pass into the last request's block.
+ @param requestNumber The request to pass into the last request's block.
+ @param error The error to pass into the last request's block.
+ */
+- (void)respondToRequestWithResponse:(__kindof SDLRPCResponse *)response requestNumber:(NSInteger)requestNumber error:(NSError *_Nullable)error;
+
+/**
* Remove all received requests.
*/
- (void)reset;
@end
-NS_ASSUME_NONNULL_END \ No newline at end of file
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m
index 9bc410ced..3bba56444 100644
--- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m
+++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m
@@ -37,6 +37,14 @@ NS_ASSUME_NONNULL_BEGIN
[self respondToLastRequestWithResponse:response error:nil];
}
+- (void)respondToRequestWithResponse:(__kindof SDLRPCResponse *)response requestNumber:(NSInteger)requestNumber error:(NSError *_Nullable)error {
+ if (self.lastRequestBlock != nil) {
+ self.lastRequestBlock([[self receivedRequests] objectAtIndex:requestNumber], response, error);
+ } else {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Attempted to respond to last request, but there was no last request block" userInfo:nil];
+ }
+}
+
- (void)respondToLastRequestWithResponse:(__kindof SDLRPCResponse *_Nullable)response error:(NSError *_Nullable)error {
if (self.lastRequestBlock != nil) {
self.lastRequestBlock(self.receivedRequests.lastObject, response, error);
diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/SDLGlobalsSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/SDLGlobalsSpec.m
index 8acaaadcf..7d203b75d 100644
--- a/SmartDeviceLinkTests/UtilitiesSpecs/SDLGlobalsSpec.m
+++ b/SmartDeviceLinkTests/UtilitiesSpecs/SDLGlobalsSpec.m
@@ -7,8 +7,6 @@ QuickSpecBegin(SDLGlobalsSpec)
describe(@"The SDLGlobals class", ^{
__block SDLGlobals *testGlobals = nil;
- __block NSNumber *v1And2MTUSize = @1024;
- __block NSNumber *v3And4MTUSize = @131084;
beforeEach(^{
testGlobals = [[SDLGlobals alloc] init];
@@ -16,70 +14,129 @@ describe(@"The SDLGlobals class", ^{
describe(@"when just initialized", ^{
it(@"should properly set protocol version", ^{
- expect(@(testGlobals.protocolVersion)).to(equal(@1));
+ expect(testGlobals.protocolVersion).to(equal(@"1.0.0"));
+ });
+
+ it(@"should properly set the major protocol version", ^{
+ expect(testGlobals.majorProtocolVersion).to(equal(1));
});
it(@"should properly set max head unit version", ^{
- expect(@(testGlobals.maxHeadUnitVersion)).to(equal(@0));
+ expect(testGlobals.maxHeadUnitVersion).to(equal(@"0.0.0"));
});
- it(@"should throw an exception trying to get max MTU size", ^{
- expect(@(testGlobals.maxMTUSize)).to(equal(v1And2MTUSize));
+ it(@"should give the v1 MTU size", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV1MTUSize));
});
});
describe(@"setting maxHeadUnitVersion should alter negotiated protocol version", ^{
it(@"should use the max head unit version when lower than max proxy version", ^{
- NSUInteger someIntLowerThanMaxProxyVersion = 2;
- testGlobals.maxHeadUnitVersion = someIntLowerThanMaxProxyVersion;
- expect(@(testGlobals.protocolVersion)).to(equal(@(someIntLowerThanMaxProxyVersion)));
- expect(@(testGlobals.maxHeadUnitVersion)).to(equal(@(someIntLowerThanMaxProxyVersion)));
+ NSString *someVersionLowerThanMaxProxyVersion = @"2.0.0";
+ testGlobals.maxHeadUnitVersion = someVersionLowerThanMaxProxyVersion;
+
+ expect(testGlobals.protocolVersion).to(equal(someVersionLowerThanMaxProxyVersion));
+ expect(testGlobals.maxHeadUnitVersion).to(equal(someVersionLowerThanMaxProxyVersion));
});
it(@"should use the max proxy version when lower than max head unit version", ^{
- NSUInteger someIntHigherThanMaxProxyVersion = 1000;
- testGlobals.maxHeadUnitVersion = someIntHigherThanMaxProxyVersion;
- expect(@(testGlobals.protocolVersion)).to(beLessThan(@(someIntHigherThanMaxProxyVersion)));
- expect(@(testGlobals.maxHeadUnitVersion)).to(equal(@(someIntHigherThanMaxProxyVersion)));
+ NSString *someVersionHigherThanMaxProxyVersion = @"1000.0.0";
+ testGlobals.maxHeadUnitVersion = someVersionHigherThanMaxProxyVersion;
+
+ expect(([testGlobals.protocolVersion compare:someVersionHigherThanMaxProxyVersion options:NSNumericSearch] == NSOrderedDescending)).to(beFalsy());
+ expect(testGlobals.maxHeadUnitVersion).to(equal(someVersionHigherThanMaxProxyVersion));
});
});
describe(@"getting the max MTU version", ^{
context(@"when protocol version is 1 - 2", ^{
it(@"should return the correct value when protocol version is 1", ^{
- testGlobals.maxHeadUnitVersion = 1;
- expect(@(testGlobals.maxMTUSize)).to(equal(v1And2MTUSize));
+ testGlobals.maxHeadUnitVersion = @"1.0.0";
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV1MTUSize));
});
it(@"should return the correct value when protocol version is 2", ^{
- testGlobals.maxHeadUnitVersion = 2;
- expect(@(testGlobals.maxMTUSize)).to(equal(v1And2MTUSize));
+ testGlobals.maxHeadUnitVersion = @"2.0.0";
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV1MTUSize));
});
});
context(@"when protocol version is 3 - 4", ^{
it(@"should return the correct value when protocol version is 3", ^{
- testGlobals.maxHeadUnitVersion = 3;
- expect(@(testGlobals.maxMTUSize)).to(equal(v3And4MTUSize));
+ testGlobals.maxHeadUnitVersion = @"3.0.0";
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV3MTUSize));
});
it(@"should return the correct value when protocol version is 4", ^{
- testGlobals.maxHeadUnitVersion = 4;
- expect(@(testGlobals.maxMTUSize)).to(equal(v3And4MTUSize));
+ testGlobals.maxHeadUnitVersion = @"4.0.0";
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV3MTUSize));
});
describe(@"when the max proxy version is lower than max head unit version", ^{
beforeEach(^{
- NSUInteger someIntHigherThanMaxProxyVersion = 1000;
- testGlobals.maxHeadUnitVersion = someIntHigherThanMaxProxyVersion;
+ NSString *someVersionHigherThanMaxProxyVersion = @"1000.0.0";
+ testGlobals.maxHeadUnitVersion = someVersionHigherThanMaxProxyVersion;
});
it(@"should return the v1 - 2 value", ^{
- expect(@(testGlobals.maxMTUSize)).to(equal(v1And2MTUSize));
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV1MTUSize));
});
});
});
});
+
+#pragma mark Dynamic MTU
+ describe(@"when dynamically setting MTU on protocol version 5", ^{
+ __block NSUInteger dynamicMTUSize1 = 12345;
+ __block NSUInteger dynamicMTUSize2 = 54321;
+
+ beforeEach(^{
+ testGlobals.maxHeadUnitVersion = @"5.0.0";
+ });
+
+ context(@"Setting the RPC service MTU", ^{
+ beforeEach(^{
+ [testGlobals setDynamicMTUSize:dynamicMTUSize1 forServiceType:SDLServiceTypeRPC];
+ });
+
+ it(@"should set the RPC service MTU", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(dynamicMTUSize1));
+ });
+
+ it(@"should have the video service fall back to the RPC service MTU", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeVideo]).to(equal(dynamicMTUSize1));
+ });
+ });
+
+ context(@"setting the video service MTU", ^{
+ beforeEach(^{
+ [testGlobals setDynamicMTUSize:dynamicMTUSize1 forServiceType:SDLServiceTypeVideo];
+ });
+
+ it(@"should not set the RPC service MTU", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(SDLV3MTUSize));
+ });
+
+ it(@"should have the video service fall back to the RPC service MTU", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeVideo]).to(equal(dynamicMTUSize1));
+ });
+ });
+
+ context(@"setting both the video service and RPC service MTU", ^{
+ beforeEach(^{
+ [testGlobals setDynamicMTUSize:dynamicMTUSize1 forServiceType:SDLServiceTypeRPC];
+ [testGlobals setDynamicMTUSize:dynamicMTUSize2 forServiceType:SDLServiceTypeVideo];
+ });
+
+ it(@"should set the RPC service MTU", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeRPC]).to(equal(dynamicMTUSize1));
+ });
+
+ it(@"should have the video service fall back to the RPC service MTU", ^{
+ expect([testGlobals mtuSizeForServiceType:SDLServiceTypeVideo]).to(equal(dynamicMTUSize2));
+ });
+ });
+ });
});
QuickSpecEnd
diff --git a/SmartDeviceLink_Example/Base.lproj/LaunchScreen.xib b/SmartDeviceLink_Example/Base.lproj/LaunchScreen.xib
index 22193a99b..c1427dc91 100644
--- a/SmartDeviceLink_Example/Base.lproj/LaunchScreen.xib
+++ b/SmartDeviceLink_Example/Base.lproj/LaunchScreen.xib
@@ -1,8 +1,12 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
+ <device id="retina4_7" orientation="portrait">
+ <adaptation id="fullscreen"/>
+ </device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
@@ -19,7 +23,7 @@
</constraints>
</imageView>
</subviews>
- <color key="backgroundColor" red="0.22352941176470587" green="0.30588235294117649" blue="0.37647058823529411" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="backgroundColor" red="0.22352941176470587" green="0.30588235294117649" blue="0.37647058823529411" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="poo-xI-0Ul" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="KOL-c5-JSi"/>
<constraint firstItem="poo-xI-0Ul" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="nBn-xL-3N7"/>
diff --git a/bson_c_lib b/bson_c_lib
new file mode 160000
+Subproject 9981c815541da97cc023bb510c172d09fefa908