├── STM32DeviceExample ├── Media │ └── stm32example.gif ├── STM32DeviceExample.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj └── STM32DeviceExample │ ├── STM32DeviceExample.entitlements │ ├── AppDelegate.swift │ ├── Info.plist │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── STM32Device.swift │ └── ViewController.swift ├── CleanFlightSerialExample ├── Media │ └── serialCFExample.gif ├── CleanFlightSerialExample │ ├── SerialDeviceSwift.entitlements │ ├── Info.plist │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── CleanFlightDevice.swift │ ├── ViewController.swift │ └── Base.lproj │ │ └── Main.storyboard └── CleanFlightSerialExample.xcodeproj │ └── project.pbxproj ├── RaceflightControllerHIDExample ├── Media │ └── rfHIDExample.gif ├── RaceflightControllerHIDExample.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj └── RaceflightControllerHIDExample │ ├── RaceflightControllerHIDExample.entitlements │ ├── AppDelegate.swift │ ├── Info.plist │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── RFDevice.swift │ └── ViewController.swift ├── USBDeviceSwift.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── STM32DeviceExample.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── USBDeviceSwift.xcscheme └── project.pbxproj ├── CHANGELOG.md ├── Package.swift ├── .gitignore ├── Sources ├── USBDeviceSwift.h ├── SerialDevice.swift ├── HIDDevice.swift ├── USBDevice.swift ├── SerialDeviceMonitor.swift ├── HIDDeviceMonitor.swift └── USBDeviceMonitor.swift ├── Supporting Files ├── Defaults.xcconfig └── Info.plist ├── USBDeviceSwift.xcworkspace └── contents.xcworkspacedata ├── LICENSE ├── README.md └── USBDeviceSwift.podspec /STM32DeviceExample/Media/stm32example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arti3DPlayer/USBDeviceSwift/HEAD/STM32DeviceExample/Media/stm32example.gif -------------------------------------------------------------------------------- /CleanFlightSerialExample/Media/serialCFExample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arti3DPlayer/USBDeviceSwift/HEAD/CleanFlightSerialExample/Media/serialCFExample.gif -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/Media/rfHIDExample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arti3DPlayer/USBDeviceSwift/HEAD/RaceflightControllerHIDExample/Media/rfHIDExample.gif -------------------------------------------------------------------------------- /USBDeviceSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/SerialDeviceSwift.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /USBDeviceSwift.xcodeproj/STM32DeviceExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample/STM32DeviceExample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.device.usb 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample/RaceflightControllerHIDExample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.device.usb 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.3 2 | 3 | - Updated all projects to Switf 4 4 | - Created Wiki documentation [here](https://github.com/Arti3DPlayer/USBDeviceSwift/wiki) 5 | - Added Serial device support 6 | 7 | ## 1.0.2 8 | - Explicitly set Swift version project-wide 9 | - Explicitly set Swift version in the pod spec (this was most likely what fixed #3) 10 | - Also updated the Xcode project to recommended defaults 11 | 12 | ## 1.0.1 13 | - Small fixes code and description fixes 14 | ## 1.0.0 15 | - Release 16 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | 3 | // 4 | // Package.swift 5 | // 6 | // 7 | // Created by Artem Hruzd on 6/14/17. 8 | // 9 | // 10 | 11 | import PackageDescription 12 | 13 | let package = Package( 14 | name: "USBDeviceSwift", 15 | products: [ 16 | .library( 17 | name: "USBDeviceSwift", 18 | targets: ["USBDeviceSwift"]), 19 | ], 20 | targets: [ 21 | .target( 22 | name: "USBDeviceSwift", 23 | path: "Sources"), 24 | ] 25 | ) 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## OS X Finder 2 | .DS_Store 3 | 4 | ## Build generated 5 | build/ 6 | DerivedData 7 | 8 | ## Various settings 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | 19 | ## Other 20 | *.xccheckout 21 | *.moved-aside 22 | *.xcuserstate 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | 29 | # Swift Package Manager 30 | .build/ 31 | 32 | # Carthage 33 | Carthage/Build 34 | -------------------------------------------------------------------------------- /Sources/USBDeviceSwift.h: -------------------------------------------------------------------------------- 1 | // 2 | // USBDeviceSwift.h 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/11/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for USBDeviceSwift. 12 | FOUNDATION_EXPORT double USBDeviceSwiftVersionNumber; 13 | 14 | //! Project version string for USBDeviceSwift. 15 | FOUNDATION_EXPORT const unsigned char USBDeviceSwiftVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Supporting Files/Defaults.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_ENUM_CONVERSION = YES 2 | CLANG_WARN_INT_CONVERSION = YES 3 | CLANG_WARN_CONSTANT_CONVERSION = YES 4 | CLANG_WARN_BOOL_CONVERSION = YES; 5 | CLANG_WARN_ASSIGN_ENUM = YES 6 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES 7 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES 8 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 9 | CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES 10 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES 11 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES 12 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES 13 | GCC_WARN_SHADOW = YES 14 | GCC_WARN_SIGN_COMPARE = YES 15 | GCC_TREAT_WARNINGS_AS_ERRORS = YES 16 | WARNING_CFLAGS = -Weverything -Wno-objc-missing-property-synthesis -Wno-gnu -Wno-float-equal -Wno-nullable-to-nonnull-conversion -Wno-auto-import -Wno-direct-ivar-access 17 | -------------------------------------------------------------------------------- /Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2017 Artem Hruzd. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /USBDeviceSwift.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 21 | 22 | 24 | 25 | 27 | 28 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // STM32DeviceExample 4 | // 5 | // Created by Artem Hruzd on 6/11/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | @NSApplicationMain 13 | class AppDelegate: NSObject, NSApplicationDelegate { 14 | //make sure that stm32DeviceMonitor always exist 15 | let stm32DeviceMonitor = USBDeviceMonitor([ 16 | USBMonitorData(vendorId: 0x0483, productId: 0xdf11) 17 | ]) 18 | 19 | func applicationDidFinishLaunching(_ aNotification: Notification) { 20 | // Insert code here to initialize your application 21 | 22 | let stm32DeviceDaemon = Thread(target: stm32DeviceMonitor, selector:#selector(stm32DeviceMonitor.start), object: nil) 23 | stm32DeviceDaemon.start() 24 | } 25 | 26 | func applicationWillTerminate(_ aNotification: Notification) { 27 | // Insert code here to tear down your application 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // RaceflightControllerHIDExample 4 | // 5 | // Created by Artem Hruzd on 6/14/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | @NSApplicationMain 13 | class AppDelegate: NSObject, NSApplicationDelegate { 14 | //make sure that rfDeviceMonitor always exist 15 | let rfDeviceMonitor = HIDDeviceMonitor([ 16 | HIDMonitorData(vendorId: 0x0483, productId: 0x5742) 17 | ], reportSize: 64) 18 | 19 | 20 | func applicationDidFinishLaunching(_ aNotification: Notification) { 21 | // Insert code here to initialize your application 22 | 23 | let rfDeviceDaemon = Thread(target: self.rfDeviceMonitor, selector:#selector(self.rfDeviceMonitor.start), object: nil) 24 | rfDeviceDaemon.start() 25 | } 26 | 27 | func applicationWillTerminate(_ aNotification: Notification) { 28 | // Insert code here to tear down your application 29 | } 30 | 31 | 32 | } 33 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 XMARTLABS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Sources/SerialDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SerialDevice.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import IOKit.serial 11 | 12 | 13 | public extension Notification.Name { 14 | static let SerialDeviceAdded = Notification.Name("SerialDeviceAdded") 15 | static let SerialDeviceRemoved = Notification.Name("SerialDeviceRemoved") 16 | } 17 | 18 | public struct SerialDevice { 19 | public let path:String 20 | public var name:String? // USB Product Name 21 | public var vendorName:String? //USB Vendor Name 22 | public var serialNumber:String? //USB Serial Number 23 | public var vendorId:Int? //USB Vendor id 24 | public var productId:Int? //USB Product id 25 | 26 | init(path:String) { 27 | self.path = path 28 | } 29 | } 30 | 31 | extension SerialDevice: Hashable { 32 | public var hashValue: Int { 33 | return "\(path)".hashValue 34 | } 35 | 36 | public static func ==(lhs: SerialDevice, rhs: SerialDevice) -> Bool { 37 | return lhs.path == rhs.path 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Artem Hruzd. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Artem Hruzd. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2018 Artem Hruzd. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SerialDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | @NSApplicationMain 13 | class AppDelegate: NSObject, NSApplicationDelegate { 14 | //make sure that cfDeviceMonitor always exist 15 | let cfDeviceMonitor = SerialDeviceMonitor() 16 | 17 | func applicationDidFinishLaunching(_ aNotification: Notification) { 18 | // Insert code here to initialize your application 19 | 20 | // Adding own function to filter serial devices that we need 21 | cfDeviceMonitor.filterDevices = {(devices: [SerialDevice]) -> [SerialDevice] in 22 | return devices.filter({$0.vendorId == 1155 && $0.productId == 22336}) 23 | } 24 | 25 | let cfDeviceDaemon = Thread(target: self.cfDeviceMonitor, selector:#selector(self.cfDeviceMonitor.start), object: nil) 26 | cfDeviceDaemon.start() 27 | } 28 | 29 | func applicationWillTerminate(_ aNotification: Notification) { 30 | // Insert code here to tear down your application 31 | } 32 | 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/CleanFlightDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CleanFlightDevice.swift 3 | // SerialDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import IOKit.serial 11 | import USBDeviceSwift 12 | 13 | public enum PortError: Int32, Error { 14 | case failedToOpen = -1 // refer to open() 15 | case invalidPath 16 | case mustReceiveOrTransmit 17 | case mustBeOpen 18 | case stringsMustBeUTF8 19 | } 20 | 21 | class CleanFlightDevice { 22 | var deviceInfo:SerialDevice 23 | var fileDescriptor:Int32? 24 | 25 | required init(_ deviceInfo:SerialDevice) { 26 | self.deviceInfo = deviceInfo 27 | } 28 | 29 | func openPort(toReceive receive: Bool, andTransmit transmit: Bool) throws { 30 | guard !deviceInfo.path.isEmpty else { 31 | throw PortError.invalidPath 32 | } 33 | 34 | guard receive || transmit else { 35 | throw PortError.mustReceiveOrTransmit 36 | } 37 | 38 | var readWriteParam : Int32 39 | 40 | if receive && transmit { 41 | readWriteParam = O_RDWR 42 | } else if receive { 43 | readWriteParam = O_RDONLY 44 | } else if transmit { 45 | readWriteParam = O_WRONLY 46 | } else { 47 | fatalError() 48 | } 49 | 50 | fileDescriptor = open(deviceInfo.path, readWriteParam | O_NOCTTY | O_EXLOCK) 51 | 52 | // Throw error if open() failed 53 | if fileDescriptor == PortError.failedToOpen.rawValue { 54 | throw PortError.failedToOpen 55 | } 56 | } 57 | 58 | public func closePort() { 59 | if let fileDescriptor = fileDescriptor { 60 | close(fileDescriptor) 61 | } 62 | fileDescriptor = nil 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # USBDeviceSwift 2 | 3 | **USBDeviceSwift** - is a wrapper for `IOKit.usb` and `IOKit.hid` and `IOKit.serial` written on pure Swift that allows you convenient work with USB devices. 4 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 18 | 19 |
8 | 9 | 11 | 12 |
16 | 17 |
20 | 21 | Working with `IOKit.usb` and `IOKit.hid` and `IOKit.serial` on Swift is a pain. A lot of not converted C code, pointers make your life harder. 22 | This library provides basic connect/disconnect events, converted functions to send and receive requests and examples. 23 | 24 | ## Getting Started 25 | 26 | ### Requirements 27 | 28 | * Mac OS X 10.10 29 | * Xcode 8+ 30 | * Swift 4 31 | 32 | ## Installation 33 | 34 | #### CocoaPods 35 | 36 | [CocoaPods](https://cocoapods.org/) is a dependency manager for Cocoa projects. 37 | 38 | Specify USBDeviceSwift into your project's `Podfile`: 39 | 40 | ```ruby 41 | # Uncomment the next line to define a global platform for your project 42 | # platform :ios, '9.0' 43 | 44 | target 'testusb' do 45 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 46 | use_frameworks! 47 | 48 | # Pods for testusb 49 | 50 | pod 'USBDeviceSwift' 51 | 52 | end 53 | ``` 54 | 55 | Then run the following command: 56 | 57 | ```bash 58 | $ pod install 59 | ``` 60 | 61 | #### Swift Package Manager 62 | 63 | [Swift Package Manager](https://swift.org/package-manager/) 64 | 65 | ``` 66 | import PackageDescription 67 | 68 | let package = Package( 69 | name: "Example project", 70 | dependencies: [ 71 | .Package(url: "https://github.com/Arti3DPlayer/USBDeviceSwift.git", majorVersion: 1), 72 | ] 73 | ) 74 | ``` 75 | 76 | ## Examples 77 | 78 | You will find all examples on Wiki page [here](https://github.com/Arti3DPlayer/USBDeviceSwift/wiki) 79 | 80 | ## License 81 | 82 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details 83 | 84 | ## Change Log 85 | 86 | This can be found in the [CHANGELOG.md](CHANGELOG.md) file. 87 | 88 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample/RFDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RFDevice.swift 3 | // RaceflightControllerHIDExample 4 | // 5 | // Created by Artem Hruzd on 6/17/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | class RFDevice: NSObject { 13 | let deviceInfo:HIDDevice 14 | 15 | required init(_ deviceInfo:HIDDevice) { 16 | self.deviceInfo = deviceInfo 17 | } 18 | 19 | func sendCommad(command:String) { 20 | let safeStr = command.trimmingCharacters(in: .whitespacesAndNewlines) 21 | if let commandData = safeStr.data(using: .utf8) { 22 | self.write(commandData) 23 | } 24 | } 25 | 26 | func write(_ data: Data) { 27 | var bytesArray = [UInt8](data) 28 | let reportId:UInt8 = 2 29 | bytesArray.insert(reportId, at: 0) 30 | bytesArray.append(0)// hack every report should end with 0 byte 31 | 32 | if (bytesArray.count > self.deviceInfo.reportSize) { 33 | print("Output data too large for USB report") 34 | return 35 | } 36 | 37 | let correctData = Data(bytes: UnsafePointer(bytesArray), count: self.deviceInfo.reportSize) 38 | 39 | IOHIDDeviceSetReport( 40 | self.deviceInfo.device, 41 | kIOHIDReportTypeOutput, 42 | CFIndex(reportId), 43 | (correctData as NSData).bytes.bindMemory(to: UInt8.self, capacity: correctData.count), 44 | correctData.count 45 | ) 46 | } 47 | 48 | // Additional: convertion bytes to specific string, removing garbage etc. 49 | func convertByteDataToString(_ data:Data, removeId:Bool=true, cleanGarbage:Bool=true) -> String { 50 | let count = data.count / MemoryLayout.size 51 | var array = [UInt8](repeating: 0, count: count) 52 | data.copyBytes(to: &array, count:count * MemoryLayout.size) 53 | if (array.count>0 && removeId) { 54 | array.remove(at: 0) 55 | } 56 | var strResp:String = "" 57 | for byte in array { 58 | strResp += String(UnicodeScalar(byte)) 59 | } 60 | if (cleanGarbage) { 61 | if let dotRange = strResp.range(of: "\0") { 62 | strResp.removeSubrange(dotRange.lowerBound.. [UInt8] { 37 | //Getting device interface from our pointer 38 | guard let deviceInterface = self.deviceInfo.deviceInterfacePtrPtr?.pointee?.pointee else { 39 | throw STM32DeviceError.DeviceInterfaceNotFound 40 | } 41 | 42 | var kr:Int32 = 0 43 | let length:Int = 6 44 | var requestPtr:[UInt8] = [UInt8](repeating: 0, count: length) 45 | // Creating request 46 | var request = IOUSBDevRequest(bmRequestType: 161, 47 | bRequest: STM32REQUEST.GETSTATUS.rawValue, 48 | wValue: 0, 49 | wIndex: 0, 50 | wLength: UInt16(length), 51 | pData: &requestPtr, 52 | wLenDone: 255) 53 | 54 | kr = deviceInterface.DeviceRequest(self.deviceInfo.deviceInterfacePtrPtr, &request) 55 | 56 | if (kr != kIOReturnSuccess) { 57 | throw STM32DeviceError.RequestError(desc: "Get device status request error: \(kr)") 58 | } 59 | 60 | return requestPtr 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Sources/HIDDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HIDDevice.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/14/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import IOKit.hid 12 | 13 | public extension Notification.Name { 14 | static let HIDDeviceDataReceived = Notification.Name("HIDDeviceDataReceived") 15 | static let HIDDeviceConnected = Notification.Name("HIDDeviceConnected") 16 | static let HIDDeviceDisconnected = Notification.Name("HIDDeviceDisconnected") 17 | } 18 | 19 | public struct HIDMonitorData { 20 | public let vendorId:Int 21 | public let productId:Int 22 | public var usagePage:Int? 23 | public var usage:Int? 24 | 25 | public init (vendorId:Int, productId:Int) { 26 | self.vendorId = vendorId 27 | self.productId = productId 28 | } 29 | 30 | public init (vendorId:Int, productId:Int, usagePage:Int?, usage:Int?) { 31 | self.vendorId = vendorId 32 | self.productId = productId 33 | self.usagePage = usagePage 34 | self.usage = usage 35 | } 36 | } 37 | 38 | public struct HIDDevice: Hashable, Identifiable { 39 | 40 | /// The underlying HID device. 41 | public let device: IOHIDDevice 42 | 43 | /// The report size. 44 | public let reportSize: Int 45 | 46 | /// The location ID of the device 47 | public let id: Int32 48 | 49 | /// The vendor ID. 50 | public let vendorId: Int16 51 | 52 | /// The product ID. 53 | public let productId: Int16 54 | 55 | /// The product name. 56 | public let name: String 57 | 58 | /// The manufacturer of the device. 59 | public let manufacturer: String 60 | 61 | /// The serial number of the device. 62 | public let serialNumber: String 63 | 64 | /// The version of the device. 65 | public let version: Int 66 | 67 | public init(device:IOHIDDevice) { 68 | self.device = device 69 | 70 | self.id = IOHIDDeviceGetProperty(self.device, kIOHIDLocationIDKey as CFString) as? Int32 ?? 0 71 | self.name = IOHIDDeviceGetProperty(device, kIOHIDProductKey as CFString) as? String ?? "" 72 | self.vendorId = IOHIDDeviceGetProperty(self.device, kIOHIDVendorIDKey as CFString) as? Int16 ?? 0 73 | self.productId = IOHIDDeviceGetProperty(self.device, kIOHIDProductIDKey as CFString) as? Int16 ?? 0 74 | self.reportSize = IOHIDDeviceGetProperty(self.device, kIOHIDMaxInputReportSizeKey as CFString) as? Int ?? 0 75 | 76 | self.manufacturer = IOHIDDeviceGetProperty(self.device, kIOHIDManufacturerKey as CFString) as? String ?? "" 77 | self.serialNumber = IOHIDDeviceGetProperty(self.device, kIOHIDSerialNumberKey as CFString) as? String ?? "" 78 | self.version = IOHIDDeviceGetProperty(self.device, kIOHIDVersionNumberKey as CFString) as? Int ?? 0 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Sources/USBDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // USBDevice.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/11/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import IOKit 11 | import IOKit.usb 12 | import IOKit.usb.IOUSBLib 13 | 14 | //from IOUSBLib.h 15 | public let kIOUSBDeviceUserClientTypeID = CFUUIDGetConstantUUIDWithBytes(nil, 16 | 0x9d, 0xc7, 0xb7, 0x80, 0x9e, 0xc0, 0x11, 0xD4, 17 | 0xa5, 0x4f, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61) 18 | public let kIOUSBDeviceInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil, 19 | 0x5c, 0x81, 0x87, 0xd0, 0x9e, 0xf3, 0x11, 0xD4, 20 | 0x8b, 0x45, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61) 21 | 22 | //from IOCFPlugin.h 23 | public let kIOCFPlugInInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil, 24 | 0xC2, 0x44, 0xE8, 0x58, 0x10, 0x9C, 0x11, 0xD4, 25 | 0x91, 0xD4, 0x00, 0x50, 0xE4, 0xC6, 0x42, 0x6F) 26 | 27 | 28 | /*! 29 | @defined USBmakebmRequestType 30 | @discussion Macro to encode the bRequest field of a Device Request. It is used when constructing an IOUSBDevRequest. 31 | */ 32 | 33 | public func USBmakebmRequestType(direction:Int, type:Int, recipient:Int) -> UInt8 { 34 | return UInt8((direction & kUSBRqDirnMask) << kUSBRqDirnShift)|UInt8((type & kUSBRqTypeMask) << kUSBRqTypeShift)|UInt8(recipient & kUSBRqRecipientMask) 35 | } 36 | 37 | public extension Notification.Name { 38 | static let USBDeviceConnected = Notification.Name("USBDeviceConnected") 39 | static let USBDeviceDisconnected = Notification.Name("USBDeviceDisconnected") 40 | } 41 | 42 | public struct USBMonitorData { 43 | public let vendorId:UInt16 44 | public let productId:UInt16 45 | 46 | public init (vendorId:UInt16, productId:UInt16) { 47 | self.vendorId = vendorId 48 | self.productId = productId 49 | } 50 | } 51 | 52 | public struct USBDevice { 53 | public let id:UInt64 54 | public let vendorId:UInt16 55 | public let productId:UInt16 56 | public let name:String 57 | 58 | public let deviceInterfacePtrPtr:UnsafeMutablePointer?>? 59 | public let plugInInterfacePtrPtr:UnsafeMutablePointer?>? 60 | 61 | public init(id:UInt64, 62 | vendorId:UInt16, 63 | productId:UInt16, 64 | name:String, 65 | deviceInterfacePtrPtr:UnsafeMutablePointer?>?, 66 | plugInInterfacePtrPtr:UnsafeMutablePointer?>?) { 67 | self.id = id 68 | self.vendorId = vendorId 69 | self.productId = productId 70 | self.name = name 71 | self.deviceInterfacePtrPtr = deviceInterfacePtrPtr 72 | self.plugInInterfacePtrPtr = plugInInterfacePtrPtr 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /USBDeviceSwift.xcodeproj/xcshareddata/xcschemes/USBDeviceSwift.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Sources/SerialDeviceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SerialDeviceMonitor.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import IOKit 12 | import IOKit.serial 13 | 14 | 15 | open class SerialDeviceMonitor { 16 | var serialDevices:[SerialDevice] = [] 17 | var portUsageIntervalTime:Float = 0.25 18 | open var filterDevices:((_ devices:[SerialDevice])->[SerialDevice])? 19 | 20 | public init() { 21 | } 22 | 23 | private func getParentProperty(device:io_object_t, key:String) -> AnyObject? { 24 | return IORegistryEntrySearchCFProperty(device, kIOServicePlane, key as CFString, kCFAllocatorDefault, IOOptionBits(kIORegistryIterateRecursively | kIORegistryIterateParents)) 25 | } 26 | 27 | func getDeviceProperty(device:io_object_t, key:String) -> AnyObject? { 28 | let cfKey = key as CFString 29 | let propValue = IORegistryEntryCreateCFProperty(device, cfKey, kCFAllocatorDefault, 0) 30 | 31 | return propValue?.takeRetainedValue() 32 | } 33 | 34 | func getSerialDevices(iterator: io_iterator_t) { 35 | var newSerialDevices:[SerialDevice] = [] 36 | while case let serialPort = IOIteratorNext(iterator), serialPort != 0 { 37 | guard let calloutDevice = getDeviceProperty(device: serialPort, key: kIOCalloutDeviceKey) as? String else { 38 | continue 39 | } 40 | 41 | var sd = SerialDevice(path: calloutDevice) 42 | sd.name = getParentProperty(device: serialPort, key: "USB Product Name") as? String 43 | sd.vendorName = getParentProperty(device: serialPort, key: "USB Vendor Name") as? String 44 | sd.serialNumber = getParentProperty(device: serialPort, key: "USB Serial Number") as? String 45 | sd.vendorId = getParentProperty(device: serialPort, key: "idVendor") as? Int 46 | sd.productId = getParentProperty(device: serialPort, key: "idProduct") as? Int 47 | 48 | newSerialDevices.append(sd) 49 | IOObjectRelease(serialPort) 50 | } 51 | IOObjectRelease(iterator) 52 | 53 | if (filterDevices != nil) { 54 | newSerialDevices = filterDevices!(newSerialDevices) 55 | } 56 | 57 | let oldSet = Set(serialDevices) 58 | let newSet = Set(newSerialDevices) 59 | 60 | 61 | 62 | for sd in oldSet.subtracting(newSet) { 63 | NotificationCenter.default.post(name: .SerialDeviceRemoved, object: ["device": sd]) 64 | } 65 | 66 | for sd in newSet.subtracting(oldSet) { 67 | NotificationCenter.default.post(name: .SerialDeviceAdded, object: ["device": sd]) 68 | } 69 | 70 | serialDevices = newSerialDevices 71 | } 72 | 73 | @objc open func start() { 74 | while true { 75 | var portIterator: io_iterator_t = 0 76 | var result: kern_return_t = KERN_FAILURE 77 | let classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue) as NSMutableDictionary 78 | classesToMatch[kIOSerialBSDTypeKey] = kIOSerialBSDAllTypes 79 | result = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, &portIterator) 80 | if result == KERN_SUCCESS { 81 | getSerialDevices(iterator: portIterator) 82 | } 83 | usleep(UInt32(portUsageIntervalTime*1000000)) 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Sources/HIDDeviceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HIDDeviceMonitor.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/14/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import IOKit.hid 12 | 13 | 14 | open class HIDDeviceMonitor { 15 | public let vp:[HIDMonitorData] 16 | public let reportSize:Int 17 | 18 | public init(_ vp:[HIDMonitorData], reportSize:Int) { 19 | self.vp = vp 20 | self.reportSize = reportSize 21 | } 22 | 23 | @objc open func start() { 24 | let managerRef = IOHIDManagerCreate(kCFAllocatorDefault, IOOptionBits(kIOHIDOptionsTypeNone)) 25 | var deviceMatches:[[String:Any]] = [] 26 | for vp in self.vp { 27 | var match = [kIOHIDProductIDKey: vp.productId, kIOHIDVendorIDKey: vp.vendorId] 28 | if let usagePage = vp.usagePage { 29 | match[kIOHIDDeviceUsagePageKey] = usagePage 30 | } 31 | if let usage = vp.usage { 32 | match[kIOHIDDeviceUsageKey] = usage 33 | } 34 | deviceMatches.append(match) 35 | } 36 | IOHIDManagerSetDeviceMatchingMultiple(managerRef, deviceMatches as CFArray) 37 | IOHIDManagerScheduleWithRunLoop(managerRef, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode.rawValue); 38 | IOHIDManagerOpen(managerRef, IOOptionBits(kIOHIDOptionsTypeNone)); 39 | 40 | let matchingCallback:IOHIDDeviceCallback = { inContext, inResult, inSender, inIOHIDDeviceRef in 41 | let this:HIDDeviceMonitor = unsafeBitCast(inContext, to: HIDDeviceMonitor.self) 42 | this.rawDeviceAdded(inResult, inSender: inSender!, inIOHIDDeviceRef: inIOHIDDeviceRef) 43 | } 44 | 45 | let removalCallback:IOHIDDeviceCallback = { inContext, inResult, inSender, inIOHIDDeviceRef in 46 | let this:HIDDeviceMonitor = unsafeBitCast(inContext, to: HIDDeviceMonitor.self) 47 | this.rawDeviceRemoved(inResult, inSender: inSender!, inIOHIDDeviceRef: inIOHIDDeviceRef) 48 | } 49 | IOHIDManagerRegisterDeviceMatchingCallback(managerRef, matchingCallback, unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) 50 | IOHIDManagerRegisterDeviceRemovalCallback(managerRef, removalCallback, unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) 51 | 52 | 53 | RunLoop.current.run() 54 | } 55 | 56 | open func read(_ inResult: IOReturn, inSender: UnsafeMutableRawPointer, type: IOHIDReportType, reportId: UInt32, report: UnsafeMutablePointer, reportLength: CFIndex) { 57 | let data = Data(bytes: UnsafePointer(report), count: reportLength) 58 | NotificationCenter.default.post(name: .HIDDeviceDataReceived, object: ["data": data]) 59 | } 60 | 61 | open func rawDeviceAdded(_ inResult: IOReturn, inSender: UnsafeMutableRawPointer, inIOHIDDeviceRef: IOHIDDevice!) { 62 | // It would be better to look up the report size and create a chunk of memory of that size 63 | let report = UnsafeMutablePointer.allocate(capacity: reportSize) 64 | let inputCallback : IOHIDReportCallback = { inContext, inResult, inSender, type, reportId, report, reportLength in 65 | let this:HIDDeviceMonitor = unsafeBitCast(inContext, to: HIDDeviceMonitor.self) 66 | this.read(inResult, inSender: inSender!, type: type, reportId: reportId, report: report, reportLength: reportLength) 67 | } 68 | 69 | //Hook up inputcallback 70 | IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef!, report, reportSize, inputCallback, unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) 71 | 72 | let device = HIDDevice(device:inIOHIDDeviceRef) 73 | NotificationCenter.default.post(name: .HIDDeviceConnected, object: ["device": device]) 74 | } 75 | 76 | open func rawDeviceRemoved(_ inResult: IOReturn, inSender: UnsafeMutableRawPointer, inIOHIDDeviceRef: IOHIDDevice!) { 77 | let device = HIDDevice(device:inIOHIDDeviceRef) 78 | NotificationCenter.default.post(name: .HIDDeviceDisconnected, object: [ 79 | "id": device.id, 80 | "device": device 81 | ]) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // STM32DeviceExample 4 | // 5 | // Created by Artem Hruzd on 6/11/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | class ViewController: NSViewController, NSComboBoxDataSource { 13 | @IBOutlet weak var devicesComboBox: NSComboBox! 14 | @IBOutlet weak var connectButton: NSButton! 15 | @IBOutlet weak var connectedDeviceLabel: NSTextField! 16 | @IBOutlet weak var dfuDeviceView: NSView! 17 | @IBOutlet weak var responseLabel: NSTextField! 18 | 19 | deinit { 20 | NotificationCenter.default.removeObserver(self) 21 | } 22 | 23 | @IBAction func getStatus(_ sender: Any) { 24 | do { 25 | let status = try self.connectedDevice?.getStatus() 26 | self.responseLabel.stringValue = "Response: \(status!)" 27 | } catch { 28 | self.responseLabel.stringValue = "Response: \(error)" 29 | } 30 | 31 | } 32 | 33 | @IBAction func connectDevice(_ sender: Any) { 34 | DispatchQueue.main.async { 35 | if (self.devices.count > 0) { 36 | if (self.connectedDevice != nil) { 37 | self.connectButton.title = "Connect" 38 | self.devicesComboBox.isEnabled = true 39 | self.connectedDevice = nil 40 | self.dfuDeviceView.isHidden = true 41 | } else { 42 | self.connectButton.title = "Disconnect" 43 | self.devicesComboBox.isEnabled = false 44 | self.connectedDevice = self.devices[self.devicesComboBox.integerValue] 45 | self.connectedDeviceLabel.stringValue = "Connected device: \(self.connectedDevice!.deviceInfo.name) (\(self.connectedDevice!.deviceInfo.vendorId), \(self.connectedDevice!.deviceInfo.productId))" 46 | self.dfuDeviceView.isHidden = false 47 | } 48 | } 49 | } 50 | } 51 | 52 | var connectedDevice:STM32Device? 53 | var devices:[STM32Device] = [] 54 | 55 | override func viewDidLoad() { 56 | super.viewDidLoad() 57 | 58 | // Do any additional setup after loading the view. 59 | 60 | NotificationCenter.default.addObserver(self, selector: #selector(self.usbConnected), name: .USBDeviceConnected, object: nil) 61 | NotificationCenter.default.addObserver(self, selector: #selector(self.usbDisconnected), name: .USBDeviceDisconnected, object: nil) 62 | 63 | self.devicesComboBox.isEditable = false 64 | self.devicesComboBox.completes = false 65 | self.dfuDeviceView.isHidden = true 66 | self.devicesComboBox.reloadData() 67 | } 68 | 69 | override var representedObject: Any? { 70 | didSet { 71 | // Update the view, if already loaded. 72 | } 73 | } 74 | 75 | func numberOfItems(in comboBox: NSComboBox) -> Int { 76 | return self.devices.count 77 | } 78 | 79 | func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? { 80 | return self.devices[index].deviceInfo.name 81 | } 82 | 83 | @objc func usbConnected(notification: NSNotification) { 84 | guard let nobj = notification.object as? NSDictionary else { 85 | return 86 | } 87 | 88 | guard let deviceInfo:USBDevice = nobj["device"] as? USBDevice else { 89 | return 90 | } 91 | let device = STM32Device(deviceInfo) 92 | DispatchQueue.main.async { 93 | self.devices.append(device) 94 | self.devicesComboBox.reloadData() 95 | } 96 | } 97 | 98 | @objc func usbDisconnected(notification: NSNotification) { 99 | guard let nobj = notification.object as? NSDictionary else { 100 | return 101 | } 102 | 103 | guard let id:UInt64 = nobj["id"] as? UInt64 else { 104 | return 105 | } 106 | DispatchQueue.main.async { 107 | if let index = self.devices.index(where: { $0.deviceInfo.id == id }) { 108 | self.devices.remove(at: index) 109 | if (id == self.connectedDevice?.deviceInfo.id) { 110 | self.connectButton.title = "Connect" 111 | self.devicesComboBox.isEnabled = true 112 | self.connectedDevice = nil 113 | self.dfuDeviceView.isHidden = true 114 | } 115 | } 116 | self.devicesComboBox.reloadData() 117 | } 118 | } 119 | 120 | } 121 | 122 | -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SerialDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | class ViewController: NSViewController { 13 | @IBOutlet weak var devicesComboBox: NSComboBox! 14 | @IBOutlet weak var connectButton: NSButton! 15 | @IBOutlet weak var connectedDeviceLabel: NSTextField! 16 | @IBOutlet weak var serialDeviceView: NSView! 17 | 18 | @IBAction func connectDevice(_ sender: Any) { 19 | DispatchQueue.main.async { 20 | if (self.devices.count > 0) { 21 | let device = self.devices[0] 22 | if (self.connectedDevice != nil) { 23 | self.connectedDevice?.closePort() 24 | self.connectButton.title = "Open port" 25 | self.devicesComboBox.isEnabled = true 26 | self.connectedDevice = nil 27 | self.serialDeviceView.isHidden = true 28 | } else { 29 | do { 30 | try device.openPort(toReceive: true, andTransmit: true) 31 | } catch PortError.failedToOpen { 32 | self.dialogOK(question: "Error", text: "Serial port \(device.deviceInfo.path) failed to open.") 33 | } catch { 34 | self.dialogOK(question: "Error", text: "\(error)") 35 | } 36 | self.connectButton.title = "Close port" 37 | self.devicesComboBox.isEnabled = false 38 | self.connectedDevice = device 39 | self.connectedDeviceLabel.stringValue = "Port opened: \(device.deviceInfo.path) (\(String(describing: device.deviceInfo.vendorId)), \(String(describing: device.deviceInfo.productId)))" 40 | self.serialDeviceView.isHidden = false 41 | } 42 | } 43 | } 44 | } 45 | 46 | var connectedDevice:CleanFlightDevice? 47 | var devices:[CleanFlightDevice] = [] 48 | 49 | override func viewDidLoad() { 50 | super.viewDidLoad() 51 | 52 | // Do any additional setup after loading the view. 53 | 54 | NotificationCenter.default.addObserver(self, selector: #selector(self.serialDeviceAdded), name: .SerialDeviceAdded, object: nil) 55 | NotificationCenter.default.addObserver(self, selector: #selector(self.serialDeviceRemoved), name: .SerialDeviceRemoved, object: nil) 56 | 57 | self.devicesComboBox.isEditable = false 58 | self.devicesComboBox.completes = false 59 | self.serialDeviceView.isHidden = true 60 | self.devicesComboBox.reloadData() 61 | } 62 | 63 | override var representedObject: Any? { 64 | didSet { 65 | // Update the view, if already loaded. 66 | } 67 | } 68 | 69 | @objc func serialDeviceAdded(notification: NSNotification) { 70 | guard let nobj = notification.object as? NSDictionary else { 71 | return 72 | } 73 | 74 | guard let deviceInfo:SerialDevice = nobj["device"] as? SerialDevice else { 75 | return 76 | } 77 | let device = CleanFlightDevice(deviceInfo) 78 | DispatchQueue.main.async { 79 | self.devices.append(device) 80 | self.devicesComboBox.reloadData() 81 | } 82 | } 83 | 84 | @objc func serialDeviceRemoved(notification: NSNotification) { 85 | guard let nobj = notification.object as? NSDictionary else { 86 | return 87 | } 88 | 89 | guard let deviceInfo:SerialDevice = nobj["device"] as? SerialDevice else { 90 | return 91 | } 92 | DispatchQueue.main.async { 93 | if let index = self.devices.index(where: { $0.deviceInfo.path == deviceInfo.path }) { 94 | self.devices.remove(at: index) 95 | if (deviceInfo.path == self.connectedDevice?.deviceInfo.path) { 96 | self.connectButton.title = "Connect" 97 | self.devicesComboBox.isEnabled = true 98 | self.connectedDevice = nil 99 | self.serialDeviceView.isHidden = true 100 | } 101 | } 102 | self.devicesComboBox.reloadData() 103 | } 104 | } 105 | 106 | func dialogOK(question: String, text: String, style:NSAlert.Style = .warning) { 107 | let myPopup: NSAlert = NSAlert() 108 | myPopup.messageText = question 109 | myPopup.informativeText = text 110 | myPopup.alertStyle = style 111 | myPopup.addButton(withTitle: "OK") 112 | myPopup.runModal() 113 | } 114 | 115 | 116 | } 117 | 118 | extension ViewController: NSComboBoxDataSource { 119 | func numberOfItems(in comboBox: NSComboBox) -> Int { 120 | return self.devices.count 121 | } 122 | 123 | func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? { 124 | return self.devices[index].deviceInfo.name 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // RaceflightControllerHIDExample 4 | // 5 | // Created by Artem Hruzd on 6/14/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import USBDeviceSwift 11 | 12 | class ViewController: NSViewController, NSComboBoxDataSource { 13 | @IBOutlet weak var devicesComboBox: NSComboBox! 14 | @IBOutlet weak var connectButton: NSButton! 15 | @IBOutlet weak var connectedDeviceLabel: NSTextField! 16 | @IBOutlet weak var rfDeviceView: NSView! 17 | 18 | @IBOutlet weak var outputTextFied: NSTextField! 19 | @IBOutlet weak var sendButton: NSButton! 20 | 21 | @IBOutlet var inputTextView: NSTextView! 22 | @IBOutlet weak var clearLogButton: NSButton! 23 | 24 | deinit { 25 | NotificationCenter.default.removeObserver(self) 26 | } 27 | 28 | @IBAction func sendOutputData(_ sender:AnyObject) { 29 | if let connectedDevice = self.connectedDevice, 30 | let field = self.outputTextFied { 31 | connectedDevice.sendCommad(command: field.stringValue) 32 | } 33 | } 34 | 35 | 36 | @IBAction func clearLog(sender: AnyObject) { 37 | DispatchQueue.main.async { 38 | self.inputTextView?.string = "" 39 | self.inputTextView?.scrollToBeginningOfDocument(self) 40 | } 41 | } 42 | 43 | override func viewWillDisappear() { 44 | NotificationCenter.default.removeObserver(self) 45 | super.viewWillDisappear() 46 | } 47 | 48 | 49 | @IBAction func connectDevice(_ sender: Any) { 50 | DispatchQueue.main.async { 51 | if (self.devices.count > 0) { 52 | if (self.connectedDevice != nil) { 53 | self.connectButton.title = "Connect" 54 | self.devicesComboBox.isEnabled = true 55 | self.connectedDevice = nil 56 | self.rfDeviceView.isHidden = true 57 | self.connectedDeviceLabel.isHidden = true 58 | } else { 59 | self.connectButton.title = "Disconnect" 60 | self.devicesComboBox.isEnabled = false 61 | self.connectedDevice = self.devices[self.devicesComboBox.integerValue] 62 | self.connectedDeviceLabel.isHidden = false 63 | self.connectedDeviceLabel.stringValue = "Connected device: \(self.connectedDevice!.deviceInfo.name) (\(self.connectedDevice!.deviceInfo.vendorId), \(self.connectedDevice!.deviceInfo.productId))" 64 | self.rfDeviceView.isHidden = false 65 | } 66 | } 67 | } 68 | } 69 | 70 | var connectedDevice:RFDevice? 71 | var devices:[RFDevice] = [] 72 | 73 | override func viewDidLoad() { 74 | super.viewDidLoad() 75 | 76 | // Do any additional setup after loading the view. 77 | 78 | NotificationCenter.default.addObserver(self, selector: #selector(self.usbConnected), name: .HIDDeviceConnected, object: nil) 79 | NotificationCenter.default.addObserver(self, selector: #selector(self.usbDisconnected), name: .HIDDeviceDisconnected, object: nil) 80 | NotificationCenter.default.addObserver(self, selector: #selector(self.hidReadData), name: .HIDDeviceDataReceived, object: nil) 81 | 82 | self.devicesComboBox.isEditable = false 83 | self.devicesComboBox.completes = false 84 | self.rfDeviceView.isHidden = true 85 | self.connectedDeviceLabel.isHidden = true 86 | self.devicesComboBox.reloadData() 87 | } 88 | 89 | override var representedObject: Any? { 90 | didSet { 91 | // Update the view, if already loaded. 92 | } 93 | } 94 | 95 | func numberOfItems(in comboBox: NSComboBox) -> Int { 96 | return self.devices.count 97 | } 98 | 99 | func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? { 100 | return self.devices[index].deviceInfo.name 101 | } 102 | 103 | @objc func usbConnected(notification: NSNotification) { 104 | guard let nobj = notification.object as? NSDictionary else { 105 | return 106 | } 107 | 108 | guard let deviceInfo:HIDDevice = nobj["device"] as? HIDDevice else { 109 | return 110 | } 111 | let device = RFDevice(deviceInfo) 112 | DispatchQueue.main.async { 113 | self.devices.append(device) 114 | self.devicesComboBox.reloadData() 115 | } 116 | } 117 | 118 | @objc func usbDisconnected(notification: NSNotification) { 119 | guard let nobj = notification.object as? NSDictionary else { 120 | return 121 | } 122 | 123 | guard let id:Int32 = nobj["id"] as? Int32 else { 124 | return 125 | } 126 | DispatchQueue.main.async { 127 | if let index = self.devices.index(where: { $0.deviceInfo.id == id }) { 128 | self.devices.remove(at: index) 129 | if (id == self.connectedDevice?.deviceInfo.id) { 130 | self.connectButton.title = "Connect" 131 | self.connectedDeviceLabel.isHidden = true 132 | self.devicesComboBox.isEnabled = true 133 | self.connectedDevice = nil 134 | self.rfDeviceView.isHidden = true 135 | } 136 | } 137 | self.devicesComboBox.reloadData() 138 | } 139 | } 140 | 141 | @objc func hidReadData(notification: Notification) { 142 | let obj = notification.object as! NSDictionary 143 | let data = obj["data"] as! Data 144 | 145 | if let str = self.connectedDevice?.convertByteDataToString(data) { 146 | DispatchQueue.main.async { 147 | self.inputTextView?.string = "\(self.inputTextView!.string)\(str)\n" 148 | self.inputTextView?.scrollToEndOfDocument(self) 149 | } 150 | } 151 | } 152 | 153 | } 154 | 155 | 156 | -------------------------------------------------------------------------------- /USBDeviceSwift.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint USBDeviceSwift.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "USBDeviceSwift" 19 | s.version = "1.0.3" 20 | s.summary = "USBDeviceSwift - is a wrapper for `IOKit` written on pure Swift that allows you convenient work with USB devices." 21 | s.swift_version = "4.0" 22 | 23 | # This description is used to generate tags and improve search results. 24 | # * Think: What does it do? Why did you write it? What is the focus? 25 | # * Try to keep it short, snappy and to the point. 26 | # * Write the description between the DESC delimiters below. 27 | # * Finally, don't worry about the indent, CocoaPods strips it! 28 | s.description = <<-DESC 29 | 30 | Working with `IOKit.usb` and `IOKit.hid` and `IOKit.serial` on Swift is a pain. A lot of not converted C code, pointers make your life harder. 31 | This library provides basic connect/disconnect events, converted functions to send and receive requests and examples. 32 | 33 | DESC 34 | 35 | s.homepage = "https://github.com/Arti3DPlayer/USBDeviceSwift" 36 | s.screenshots = "https://github.com/Arti3DPlayer/USBDeviceSwift/raw/1.0.0/STM32DeviceExample/Media/stm32example.gif", "https://github.com/Arti3DPlayer/USBDeviceSwift/raw/1.0.0/RaceflightControllerHIDExample/Media/rfHIDExample.gif" 37 | 38 | 39 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 40 | # 41 | # Licensing your code is important. See http://choosealicense.com for more info. 42 | # CocoaPods will detect a license file if there is a named LICENSE* 43 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 44 | # 45 | 46 | s.license = "MIT" 47 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 48 | 49 | 50 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 51 | # 52 | # Specify the authors of the library, with email addresses. Email addresses 53 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 54 | # accepts just a name if you'd rather not provide an email address. 55 | # 56 | # Specify a social_media_url where others can refer to, for example a twitter 57 | # profile URL. 58 | # 59 | 60 | s.author = { "Artem" => "arti3d.artem@gmail.com" } 61 | # Or just: s.author = "Artem" 62 | # s.authors = { "Artem" => "arti3d.artem@gmail.com" } 63 | # s.social_media_url = "http://twitter.com/Artem" 64 | 65 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 66 | # 67 | # If this Pod runs only on iOS or OS X, then specify the platform and 68 | # the deployment target. You can optionally include the target after the platform. 69 | # 70 | 71 | # s.platform = :ios 72 | s.platform = :osx, "10.10" 73 | 74 | # When using multiple platforms 75 | # s.ios.deployment_target = "5.0" 76 | # s.osx.deployment_target = "10.7" 77 | # s.watchos.deployment_target = "2.0" 78 | # s.tvos.deployment_target = "9.0" 79 | 80 | 81 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 82 | # 83 | # Specify the location from where the source should be retrieved. 84 | # Supports git, hg, bzr, svn and HTTP. 85 | # 86 | 87 | s.source = { :git => "https://github.com/Arti3DPlayer/USBDeviceSwift.git", :tag => "#{s.version}" } 88 | 89 | 90 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 91 | # 92 | # CocoaPods is smart about how it includes source code. For source files 93 | # giving a folder will include any swift, h, m, mm, c & cpp files. 94 | # For header files it will include any header in the folder. 95 | # Not including the public_header_files will make all headers public. 96 | # 97 | 98 | s.source_files = "Sources/**/*" 99 | 100 | # s.public_header_files = "Classes/**/*.h" 101 | 102 | 103 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 104 | # 105 | # A list of resources included with the Pod. These are copied into the 106 | # target bundle with a build phase script. Anything else will be cleaned. 107 | # You can preserve files from being cleaned, please don't preserve 108 | # non-essential files like tests, examples and documentation. 109 | # 110 | 111 | # s.resource = "icon.png" 112 | # s.resources = "Resources/*.png" 113 | 114 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 115 | 116 | 117 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 118 | # 119 | # Link your library with frameworks, or libraries. Libraries do not include 120 | # the lib prefix of their name. 121 | # 122 | 123 | # s.framework = "SomeFramework" 124 | # s.frameworks = "SomeFramework", "AnotherFramework" 125 | 126 | # s.library = "iconv" 127 | # s.libraries = "iconv", "xml2" 128 | 129 | 130 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 131 | # 132 | # If your library depends on compiler flags you can set them in the xcconfig hash 133 | # where they will only apply to your library. If you depend on other Podspecs 134 | # you can include multiple dependencies to ensure it works. 135 | 136 | # s.requires_arc = true 137 | 138 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 139 | # s.dependency "JSONKit", "~> 1.4" 140 | 141 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.0' } 142 | end 143 | -------------------------------------------------------------------------------- /Sources/USBDeviceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // USBDeviceMonitor.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/12/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | open class USBDeviceMonitor { 13 | public let vp:[USBMonitorData] 14 | 15 | public init(_ vp:[USBMonitorData]) { 16 | self.vp = vp 17 | } 18 | 19 | @objc open func start() { 20 | for vp in self.vp { 21 | var matchedIterator:io_iterator_t = 0 22 | var removalIterator:io_iterator_t = 0 23 | let notifyPort:IONotificationPortRef = IONotificationPortCreate(kIOMasterPortDefault) 24 | IONotificationPortSetDispatchQueue(notifyPort, DispatchQueue(label: "IODetector")) 25 | let matchingDict = IOServiceMatching(kIOUSBDeviceClassName) 26 | as NSMutableDictionary 27 | matchingDict[kUSBVendorID] = NSNumber(value: vp.vendorId) 28 | matchingDict[kUSBProductID] = NSNumber(value: vp.productId) 29 | 30 | let matchingCallback:IOServiceMatchingCallback = { (userData, iterator) in 31 | // Convert self to a void pointer, store that in the context, and convert it 32 | let this = Unmanaged.fromOpaque(userData!).takeUnretainedValue() 33 | this.rawDeviceAdded(iterator: iterator) 34 | } 35 | 36 | let removalCallback: IOServiceMatchingCallback = { 37 | (userData, iterator) in 38 | let this = Unmanaged.fromOpaque(userData!).takeUnretainedValue() 39 | this.rawDeviceRemoved(iterator: iterator) 40 | } 41 | 42 | let selfPtr = Unmanaged.passUnretained(self).toOpaque() 43 | 44 | IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, matchingDict, matchingCallback, selfPtr, &matchedIterator) 45 | IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, matchingDict, removalCallback, selfPtr, &removalIterator) 46 | 47 | self.rawDeviceAdded(iterator: matchedIterator) 48 | self.rawDeviceRemoved(iterator: removalIterator) 49 | 50 | } 51 | 52 | RunLoop.current.run() 53 | } 54 | 55 | open func rawDeviceAdded(iterator: io_iterator_t) { 56 | 57 | while case let usbDevice = IOIteratorNext(iterator), usbDevice != 0 { 58 | var score:Int32 = 0 59 | var kr:Int32 = 0 60 | var did:UInt64 = 0 61 | var vid:UInt16 = 0 62 | var pid:UInt16 = 0 63 | 64 | var deviceInterfacePtrPtr: UnsafeMutablePointer?>? 65 | var plugInInterfacePtrPtr: UnsafeMutablePointer?>? 66 | 67 | kr = IORegistryEntryGetRegistryEntryID(usbDevice, &did) 68 | 69 | if(kr != kIOReturnSuccess) { 70 | print("Error getting device id") 71 | } 72 | 73 | // io_name_t imports to swift as a tuple (Int8, ..., Int8) 128 ints 74 | // although in device_types.h it's defined: 75 | // typedef char io_name_t[128]; 76 | var deviceNameCString:[CChar] = [CChar](repeating: 0, count: 128) 77 | kr = IORegistryEntryGetName(usbDevice, &deviceNameCString) 78 | 79 | if(kr != kIOReturnSuccess) { 80 | print("Error getting device name") 81 | } 82 | 83 | let name = String.init(cString: &deviceNameCString) 84 | 85 | // Get plugInInterface for current USB device 86 | kr = IOCreatePlugInInterfaceForService( 87 | usbDevice, 88 | kIOUSBDeviceUserClientTypeID, 89 | kIOCFPlugInInterfaceID, 90 | &plugInInterfacePtrPtr, 91 | &score) 92 | 93 | // USB device object is no longer needed. 94 | IOObjectRelease(usbDevice) 95 | 96 | // Dereference pointer for the plug-in interface 97 | if (kr != kIOReturnSuccess) { 98 | continue 99 | } 100 | 101 | guard let plugInInterface = plugInInterfacePtrPtr?.pointee?.pointee else { 102 | print("Unable to get Plug-In Interface") 103 | continue 104 | } 105 | 106 | // use plug in interface to get a device interface 107 | kr = withUnsafeMutablePointer(to: &deviceInterfacePtrPtr) { 108 | $0.withMemoryRebound(to: Optional.self, capacity: 1) { 109 | plugInInterface.QueryInterface( 110 | plugInInterfacePtrPtr, 111 | CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), 112 | $0) 113 | } 114 | } 115 | 116 | // dereference pointer for the device interface 117 | if (kr != kIOReturnSuccess) { 118 | continue 119 | } 120 | 121 | guard let deviceInterface = deviceInterfacePtrPtr?.pointee?.pointee else { 122 | print("Unable to get Device Interface") 123 | continue 124 | } 125 | 126 | kr = deviceInterface.USBDeviceOpen(deviceInterfacePtrPtr) 127 | 128 | // kIOReturnExclusiveAccess is not a problem as we can still do some things 129 | if (kr != kIOReturnSuccess && kr != kIOReturnExclusiveAccess) { 130 | print("Could not open device (error: \(kr))") 131 | continue 132 | } 133 | 134 | kr = deviceInterface.GetDeviceVendor(deviceInterfacePtrPtr, &vid) 135 | if (kr != kIOReturnSuccess) { 136 | continue 137 | } 138 | 139 | kr = deviceInterface.GetDeviceProduct(deviceInterfacePtrPtr, &pid) 140 | if (kr != kIOReturnSuccess) { 141 | continue 142 | } 143 | 144 | let device = USBDevice( 145 | id: did, 146 | vendorId: vid, 147 | productId: pid, 148 | name:name, 149 | deviceInterfacePtrPtr:deviceInterfacePtrPtr, 150 | plugInInterfacePtrPtr:plugInInterfacePtrPtr 151 | ) 152 | 153 | NotificationCenter.default.post(name: .USBDeviceConnected, object: [ 154 | "device": device 155 | ]) 156 | } 157 | } 158 | 159 | open func rawDeviceRemoved(iterator: io_iterator_t) { 160 | while case let usbDevice = IOIteratorNext(iterator), usbDevice != 0 { 161 | var kr:Int32 = 0 162 | var did:UInt64 = 0 163 | 164 | kr = IORegistryEntryGetRegistryEntryID(usbDevice, &did) 165 | 166 | if(kr != kIOReturnSuccess) { 167 | print("Error getting device id") 168 | } 169 | 170 | // USB device object is no longer needed. 171 | kr = IOObjectRelease(usbDevice) 172 | 173 | if (kr != kIOReturnSuccess) 174 | { 175 | print("Couldn’t release raw device object (error: \(kr))") 176 | continue 177 | } 178 | 179 | NotificationCenter.default.post(name: .USBDeviceDisconnected, object: [ 180 | "id": did 181 | ]) 182 | } 183 | } 184 | } 185 | 186 | -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3F8A57A1205287F500E5BD99 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A57A0205287F500E5BD99 /* AppDelegate.swift */; }; 11 | 3F8A57A3205287F500E5BD99 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A57A2205287F500E5BD99 /* ViewController.swift */; }; 12 | 3F8A57A5205287F500E5BD99 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3F8A57A4205287F500E5BD99 /* Assets.xcassets */; }; 13 | 3F8A57A8205287F500E5BD99 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3F8A57A6205287F500E5BD99 /* Main.storyboard */; }; 14 | 3F8A57B120528AF300E5BD99 /* USBDeviceSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F8A57B220528AF300E5BD99 /* USBDeviceSwift.framework */; }; 15 | 3FF1D90F2052FDD40046DF07 /* CleanFlightDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FF1D90E2052FDD40046DF07 /* CleanFlightDevice.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 3F8A579D205287F500E5BD99 /* CleanFlightSerialExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CleanFlightSerialExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 3F8A57A0205287F500E5BD99 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 21 | 3F8A57A2205287F500E5BD99 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 22 | 3F8A57A4205287F500E5BD99 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 23 | 3F8A57A7205287F500E5BD99 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 24 | 3F8A57A9205287F500E5BD99 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | 3F8A57AA205287F500E5BD99 /* SerialDeviceSwift.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SerialDeviceSwift.entitlements; sourceTree = ""; }; 26 | 3F8A57B220528AF300E5BD99 /* USBDeviceSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = USBDeviceSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 3FF1D90E2052FDD40046DF07 /* CleanFlightDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CleanFlightDevice.swift; sourceTree = ""; }; 28 | /* End PBXFileReference section */ 29 | 30 | /* Begin PBXFrameworksBuildPhase section */ 31 | 3F8A579A205287F500E5BD99 /* Frameworks */ = { 32 | isa = PBXFrameworksBuildPhase; 33 | buildActionMask = 2147483647; 34 | files = ( 35 | 3F8A57B120528AF300E5BD99 /* USBDeviceSwift.framework in Frameworks */, 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 3F8A5794205287F500E5BD99 = { 43 | isa = PBXGroup; 44 | children = ( 45 | 3F8A579F205287F500E5BD99 /* CleanFlightSerialExample */, 46 | 3F8A579E205287F500E5BD99 /* Products */, 47 | 3F8A57B020528AF300E5BD99 /* Frameworks */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | 3F8A579E205287F500E5BD99 /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 3F8A579D205287F500E5BD99 /* CleanFlightSerialExample.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | 3F8A579F205287F500E5BD99 /* CleanFlightSerialExample */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 3F8A57A0205287F500E5BD99 /* AppDelegate.swift */, 63 | 3FF1D90E2052FDD40046DF07 /* CleanFlightDevice.swift */, 64 | 3F8A57A2205287F500E5BD99 /* ViewController.swift */, 65 | 3F8A57A4205287F500E5BD99 /* Assets.xcassets */, 66 | 3F8A57A6205287F500E5BD99 /* Main.storyboard */, 67 | 3F8A57A9205287F500E5BD99 /* Info.plist */, 68 | 3F8A57AA205287F500E5BD99 /* SerialDeviceSwift.entitlements */, 69 | ); 70 | path = CleanFlightSerialExample; 71 | sourceTree = ""; 72 | }; 73 | 3F8A57B020528AF300E5BD99 /* Frameworks */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 3F8A57B220528AF300E5BD99 /* USBDeviceSwift.framework */, 77 | ); 78 | name = Frameworks; 79 | sourceTree = ""; 80 | }; 81 | /* End PBXGroup section */ 82 | 83 | /* Begin PBXNativeTarget section */ 84 | 3F8A579C205287F500E5BD99 /* CleanFlightSerialExample */ = { 85 | isa = PBXNativeTarget; 86 | buildConfigurationList = 3F8A57AD205287F500E5BD99 /* Build configuration list for PBXNativeTarget "CleanFlightSerialExample" */; 87 | buildPhases = ( 88 | 3F8A5799205287F500E5BD99 /* Sources */, 89 | 3F8A579A205287F500E5BD99 /* Frameworks */, 90 | 3F8A579B205287F500E5BD99 /* Resources */, 91 | ); 92 | buildRules = ( 93 | ); 94 | dependencies = ( 95 | ); 96 | name = CleanFlightSerialExample; 97 | productName = SerialDeviceSwift; 98 | productReference = 3F8A579D205287F500E5BD99 /* CleanFlightSerialExample.app */; 99 | productType = "com.apple.product-type.application"; 100 | }; 101 | /* End PBXNativeTarget section */ 102 | 103 | /* Begin PBXProject section */ 104 | 3F8A5795205287F500E5BD99 /* Project object */ = { 105 | isa = PBXProject; 106 | attributes = { 107 | LastSwiftUpdateCheck = 0920; 108 | LastUpgradeCheck = 0920; 109 | ORGANIZATIONNAME = "Artem Hruzd"; 110 | TargetAttributes = { 111 | 3F8A579C205287F500E5BD99 = { 112 | CreatedOnToolsVersion = 9.2; 113 | ProvisioningStyle = Automatic; 114 | SystemCapabilities = { 115 | com.apple.Sandbox = { 116 | enabled = 0; 117 | }; 118 | }; 119 | }; 120 | }; 121 | }; 122 | buildConfigurationList = 3F8A5798205287F500E5BD99 /* Build configuration list for PBXProject "CleanFlightSerialExample" */; 123 | compatibilityVersion = "Xcode 8.0"; 124 | developmentRegion = en; 125 | hasScannedForEncodings = 0; 126 | knownRegions = ( 127 | en, 128 | Base, 129 | ); 130 | mainGroup = 3F8A5794205287F500E5BD99; 131 | productRefGroup = 3F8A579E205287F500E5BD99 /* Products */; 132 | projectDirPath = ""; 133 | projectRoot = ""; 134 | targets = ( 135 | 3F8A579C205287F500E5BD99 /* CleanFlightSerialExample */, 136 | ); 137 | }; 138 | /* End PBXProject section */ 139 | 140 | /* Begin PBXResourcesBuildPhase section */ 141 | 3F8A579B205287F500E5BD99 /* Resources */ = { 142 | isa = PBXResourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | 3F8A57A5205287F500E5BD99 /* Assets.xcassets in Resources */, 146 | 3F8A57A8205287F500E5BD99 /* Main.storyboard in Resources */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | /* End PBXResourcesBuildPhase section */ 151 | 152 | /* Begin PBXSourcesBuildPhase section */ 153 | 3F8A5799205287F500E5BD99 /* Sources */ = { 154 | isa = PBXSourcesBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | 3F8A57A3205287F500E5BD99 /* ViewController.swift in Sources */, 158 | 3F8A57A1205287F500E5BD99 /* AppDelegate.swift in Sources */, 159 | 3FF1D90F2052FDD40046DF07 /* CleanFlightDevice.swift in Sources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXSourcesBuildPhase section */ 164 | 165 | /* Begin PBXVariantGroup section */ 166 | 3F8A57A6205287F500E5BD99 /* Main.storyboard */ = { 167 | isa = PBXVariantGroup; 168 | children = ( 169 | 3F8A57A7205287F500E5BD99 /* Base */, 170 | ); 171 | name = Main.storyboard; 172 | sourceTree = ""; 173 | }; 174 | /* End PBXVariantGroup section */ 175 | 176 | /* Begin XCBuildConfiguration section */ 177 | 3F8A57AB205287F500E5BD99 /* Debug */ = { 178 | isa = XCBuildConfiguration; 179 | buildSettings = { 180 | ALWAYS_SEARCH_USER_PATHS = NO; 181 | CLANG_ANALYZER_NONNULL = YES; 182 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 183 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 184 | CLANG_CXX_LIBRARY = "libc++"; 185 | CLANG_ENABLE_MODULES = YES; 186 | CLANG_ENABLE_OBJC_ARC = YES; 187 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 188 | CLANG_WARN_BOOL_CONVERSION = YES; 189 | CLANG_WARN_COMMA = YES; 190 | CLANG_WARN_CONSTANT_CONVERSION = YES; 191 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 192 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 193 | CLANG_WARN_EMPTY_BODY = YES; 194 | CLANG_WARN_ENUM_CONVERSION = YES; 195 | CLANG_WARN_INFINITE_RECURSION = YES; 196 | CLANG_WARN_INT_CONVERSION = YES; 197 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 198 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 199 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 200 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 201 | CLANG_WARN_STRICT_PROTOTYPES = YES; 202 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 203 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 204 | CLANG_WARN_UNREACHABLE_CODE = YES; 205 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 206 | CODE_SIGN_IDENTITY = "Mac Developer"; 207 | COPY_PHASE_STRIP = NO; 208 | DEBUG_INFORMATION_FORMAT = dwarf; 209 | ENABLE_STRICT_OBJC_MSGSEND = YES; 210 | ENABLE_TESTABILITY = YES; 211 | GCC_C_LANGUAGE_STANDARD = gnu11; 212 | GCC_DYNAMIC_NO_PIC = NO; 213 | GCC_NO_COMMON_BLOCKS = YES; 214 | GCC_OPTIMIZATION_LEVEL = 0; 215 | GCC_PREPROCESSOR_DEFINITIONS = ( 216 | "DEBUG=1", 217 | "$(inherited)", 218 | ); 219 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 220 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 221 | GCC_WARN_UNDECLARED_SELECTOR = YES; 222 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 223 | GCC_WARN_UNUSED_FUNCTION = YES; 224 | GCC_WARN_UNUSED_VARIABLE = YES; 225 | MACOSX_DEPLOYMENT_TARGET = 10.13; 226 | MTL_ENABLE_DEBUG_INFO = YES; 227 | ONLY_ACTIVE_ARCH = YES; 228 | SDKROOT = macosx; 229 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 230 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 231 | SWIFT_VERSION = 4.0; 232 | }; 233 | name = Debug; 234 | }; 235 | 3F8A57AC205287F500E5BD99 /* Release */ = { 236 | isa = XCBuildConfiguration; 237 | buildSettings = { 238 | ALWAYS_SEARCH_USER_PATHS = NO; 239 | CLANG_ANALYZER_NONNULL = YES; 240 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 242 | CLANG_CXX_LIBRARY = "libc++"; 243 | CLANG_ENABLE_MODULES = YES; 244 | CLANG_ENABLE_OBJC_ARC = YES; 245 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 246 | CLANG_WARN_BOOL_CONVERSION = YES; 247 | CLANG_WARN_COMMA = YES; 248 | CLANG_WARN_CONSTANT_CONVERSION = YES; 249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 250 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 251 | CLANG_WARN_EMPTY_BODY = YES; 252 | CLANG_WARN_ENUM_CONVERSION = YES; 253 | CLANG_WARN_INFINITE_RECURSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 258 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 259 | CLANG_WARN_STRICT_PROTOTYPES = YES; 260 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 261 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | CODE_SIGN_IDENTITY = "Mac Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 267 | ENABLE_NS_ASSERTIONS = NO; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu11; 270 | GCC_NO_COMMON_BLOCKS = YES; 271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 273 | GCC_WARN_UNDECLARED_SELECTOR = YES; 274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 275 | GCC_WARN_UNUSED_FUNCTION = YES; 276 | GCC_WARN_UNUSED_VARIABLE = YES; 277 | MACOSX_DEPLOYMENT_TARGET = 10.13; 278 | MTL_ENABLE_DEBUG_INFO = NO; 279 | SDKROOT = macosx; 280 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 281 | SWIFT_VERSION = 4.0; 282 | }; 283 | name = Release; 284 | }; 285 | 3F8A57AE205287F500E5BD99 /* Debug */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CODE_SIGN_STYLE = Automatic; 290 | COMBINE_HIDPI_IMAGES = YES; 291 | DEVELOPMENT_TEAM = LGTF372X5G; 292 | INFOPLIST_FILE = CleanFlightSerialExample/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.SerialDeviceSwift; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_VERSION = 4.0; 297 | }; 298 | name = Debug; 299 | }; 300 | 3F8A57AF205287F500E5BD99 /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 304 | CODE_SIGN_STYLE = Automatic; 305 | COMBINE_HIDPI_IMAGES = YES; 306 | DEVELOPMENT_TEAM = LGTF372X5G; 307 | INFOPLIST_FILE = CleanFlightSerialExample/Info.plist; 308 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 309 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.SerialDeviceSwift; 310 | PRODUCT_NAME = "$(TARGET_NAME)"; 311 | SWIFT_VERSION = 4.0; 312 | }; 313 | name = Release; 314 | }; 315 | /* End XCBuildConfiguration section */ 316 | 317 | /* Begin XCConfigurationList section */ 318 | 3F8A5798205287F500E5BD99 /* Build configuration list for PBXProject "CleanFlightSerialExample" */ = { 319 | isa = XCConfigurationList; 320 | buildConfigurations = ( 321 | 3F8A57AB205287F500E5BD99 /* Debug */, 322 | 3F8A57AC205287F500E5BD99 /* Release */, 323 | ); 324 | defaultConfigurationIsVisible = 0; 325 | defaultConfigurationName = Release; 326 | }; 327 | 3F8A57AD205287F500E5BD99 /* Build configuration list for PBXNativeTarget "CleanFlightSerialExample" */ = { 328 | isa = XCConfigurationList; 329 | buildConfigurations = ( 330 | 3F8A57AE205287F500E5BD99 /* Debug */, 331 | 3F8A57AF205287F500E5BD99 /* Release */, 332 | ); 333 | defaultConfigurationIsVisible = 0; 334 | defaultConfigurationName = Release; 335 | }; 336 | /* End XCConfigurationList section */ 337 | }; 338 | rootObject = 3F8A5795205287F500E5BD99 /* Project object */; 339 | } 340 | -------------------------------------------------------------------------------- /STM32DeviceExample/STM32DeviceExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3F1B1DEE1EED61B1004279DF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1B1DED1EED61B1004279DF /* AppDelegate.swift */; }; 11 | 3F1B1DF01EED61B1004279DF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1B1DEF1EED61B1004279DF /* ViewController.swift */; }; 12 | 3F1B1DF21EED61B1004279DF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3F1B1DF11EED61B1004279DF /* Assets.xcassets */; }; 13 | 3F1B1DF51EED61B1004279DF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3F1B1DF31EED61B1004279DF /* Main.storyboard */; }; 14 | 3F1B1E031EED6575004279DF /* USBDeviceSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F1B1E021EED6575004279DF /* USBDeviceSwift.framework */; }; 15 | 3F47996A1EEEB7E50095CBFF /* STM32Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4799691EEEB7E50095CBFF /* STM32Device.swift */; }; 16 | 3F7D970E1EF0308F0013C965 /* Media in Resources */ = {isa = PBXBuildFile; fileRef = 3F7D970D1EF0308F0013C965 /* Media */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 3F06D51D2053F89000985C42 /* STM32DeviceExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = STM32DeviceExample.entitlements; sourceTree = ""; }; 21 | 3F1B1DEA1EED61B1004279DF /* STM32DeviceExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = STM32DeviceExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 3F1B1DED1EED61B1004279DF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 23 | 3F1B1DEF1EED61B1004279DF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 24 | 3F1B1DF11EED61B1004279DF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 25 | 3F1B1DF41EED61B1004279DF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 3F1B1DF61EED61B1004279DF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 27 | 3F1B1E021EED6575004279DF /* USBDeviceSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = USBDeviceSwift.framework; path = "../../../Library/Developer/Xcode/DerivedData/USBDeviceSwift-gknxknqrvuzujydouczavzvsmjto/Build/Products/Debug/USBDeviceSwift.framework"; sourceTree = ""; }; 28 | 3F4799691EEEB7E50095CBFF /* STM32Device.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STM32Device.swift; sourceTree = ""; }; 29 | 3F7D970D1EF0308F0013C965 /* Media */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Media; sourceTree = SOURCE_ROOT; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | 3F1B1DE71EED61B1004279DF /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | 3F1B1E031EED6575004279DF /* USBDeviceSwift.framework in Frameworks */, 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 3F1B1DE11EED61B1004279DF = { 45 | isa = PBXGroup; 46 | children = ( 47 | 3F7D970D1EF0308F0013C965 /* Media */, 48 | 3F1B1DEC1EED61B1004279DF /* STM32DeviceExample */, 49 | 3F1B1DEB1EED61B1004279DF /* Products */, 50 | 3F1B1E011EED6574004279DF /* Frameworks */, 51 | ); 52 | sourceTree = ""; 53 | }; 54 | 3F1B1DEB1EED61B1004279DF /* Products */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | 3F1B1DEA1EED61B1004279DF /* STM32DeviceExample.app */, 58 | ); 59 | name = Products; 60 | sourceTree = ""; 61 | }; 62 | 3F1B1DEC1EED61B1004279DF /* STM32DeviceExample */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 3F06D51D2053F89000985C42 /* STM32DeviceExample.entitlements */, 66 | 3F1B1DED1EED61B1004279DF /* AppDelegate.swift */, 67 | 3F1B1DEF1EED61B1004279DF /* ViewController.swift */, 68 | 3F4799691EEEB7E50095CBFF /* STM32Device.swift */, 69 | 3F1B1DF11EED61B1004279DF /* Assets.xcassets */, 70 | 3F1B1DF31EED61B1004279DF /* Main.storyboard */, 71 | 3F1B1DF61EED61B1004279DF /* Info.plist */, 72 | ); 73 | path = STM32DeviceExample; 74 | sourceTree = ""; 75 | }; 76 | 3F1B1E011EED6574004279DF /* Frameworks */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 3F1B1E021EED6575004279DF /* USBDeviceSwift.framework */, 80 | ); 81 | name = Frameworks; 82 | sourceTree = ""; 83 | }; 84 | /* End PBXGroup section */ 85 | 86 | /* Begin PBXNativeTarget section */ 87 | 3F1B1DE91EED61B1004279DF /* STM32DeviceExample */ = { 88 | isa = PBXNativeTarget; 89 | buildConfigurationList = 3F1B1DF91EED61B1004279DF /* Build configuration list for PBXNativeTarget "STM32DeviceExample" */; 90 | buildPhases = ( 91 | 3F1B1DE61EED61B1004279DF /* Sources */, 92 | 3F1B1DE71EED61B1004279DF /* Frameworks */, 93 | 3F1B1DE81EED61B1004279DF /* Resources */, 94 | ); 95 | buildRules = ( 96 | ); 97 | dependencies = ( 98 | ); 99 | name = STM32DeviceExample; 100 | productName = STM32DeviceExample; 101 | productReference = 3F1B1DEA1EED61B1004279DF /* STM32DeviceExample.app */; 102 | productType = "com.apple.product-type.application"; 103 | }; 104 | /* End PBXNativeTarget section */ 105 | 106 | /* Begin PBXProject section */ 107 | 3F1B1DE21EED61B1004279DF /* Project object */ = { 108 | isa = PBXProject; 109 | attributes = { 110 | LastSwiftUpdateCheck = 0830; 111 | LastUpgradeCheck = 0900; 112 | ORGANIZATIONNAME = "Artem Hruzd"; 113 | TargetAttributes = { 114 | 3F1B1DE91EED61B1004279DF = { 115 | CreatedOnToolsVersion = 8.3.3; 116 | DevelopmentTeam = LGTF372X5G; 117 | LastSwiftMigration = 0920; 118 | ProvisioningStyle = Automatic; 119 | SystemCapabilities = { 120 | com.apple.Sandbox = { 121 | enabled = 1; 122 | }; 123 | }; 124 | }; 125 | }; 126 | }; 127 | buildConfigurationList = 3F1B1DE51EED61B1004279DF /* Build configuration list for PBXProject "STM32DeviceExample" */; 128 | compatibilityVersion = "Xcode 3.2"; 129 | developmentRegion = English; 130 | hasScannedForEncodings = 0; 131 | knownRegions = ( 132 | en, 133 | Base, 134 | ); 135 | mainGroup = 3F1B1DE11EED61B1004279DF; 136 | productRefGroup = 3F1B1DEB1EED61B1004279DF /* Products */; 137 | projectDirPath = ""; 138 | projectRoot = ""; 139 | targets = ( 140 | 3F1B1DE91EED61B1004279DF /* STM32DeviceExample */, 141 | ); 142 | }; 143 | /* End PBXProject section */ 144 | 145 | /* Begin PBXResourcesBuildPhase section */ 146 | 3F1B1DE81EED61B1004279DF /* Resources */ = { 147 | isa = PBXResourcesBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 3F7D970E1EF0308F0013C965 /* Media in Resources */, 151 | 3F1B1DF21EED61B1004279DF /* Assets.xcassets in Resources */, 152 | 3F1B1DF51EED61B1004279DF /* Main.storyboard in Resources */, 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | /* End PBXResourcesBuildPhase section */ 157 | 158 | /* Begin PBXSourcesBuildPhase section */ 159 | 3F1B1DE61EED61B1004279DF /* Sources */ = { 160 | isa = PBXSourcesBuildPhase; 161 | buildActionMask = 2147483647; 162 | files = ( 163 | 3F47996A1EEEB7E50095CBFF /* STM32Device.swift in Sources */, 164 | 3F1B1DF01EED61B1004279DF /* ViewController.swift in Sources */, 165 | 3F1B1DEE1EED61B1004279DF /* AppDelegate.swift in Sources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXSourcesBuildPhase section */ 170 | 171 | /* Begin PBXVariantGroup section */ 172 | 3F1B1DF31EED61B1004279DF /* Main.storyboard */ = { 173 | isa = PBXVariantGroup; 174 | children = ( 175 | 3F1B1DF41EED61B1004279DF /* Base */, 176 | ); 177 | name = Main.storyboard; 178 | sourceTree = ""; 179 | }; 180 | /* End PBXVariantGroup section */ 181 | 182 | /* Begin XCBuildConfiguration section */ 183 | 3F1B1DF71EED61B1004279DF /* Debug */ = { 184 | isa = XCBuildConfiguration; 185 | buildSettings = { 186 | ALWAYS_SEARCH_USER_PATHS = NO; 187 | CLANG_ANALYZER_NONNULL = YES; 188 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 190 | CLANG_CXX_LIBRARY = "libc++"; 191 | CLANG_ENABLE_MODULES = YES; 192 | CLANG_ENABLE_OBJC_ARC = YES; 193 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 194 | CLANG_WARN_BOOL_CONVERSION = YES; 195 | CLANG_WARN_COMMA = YES; 196 | CLANG_WARN_CONSTANT_CONVERSION = YES; 197 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 198 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 199 | CLANG_WARN_EMPTY_BODY = YES; 200 | CLANG_WARN_ENUM_CONVERSION = YES; 201 | CLANG_WARN_INFINITE_RECURSION = YES; 202 | CLANG_WARN_INT_CONVERSION = YES; 203 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 204 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 206 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 207 | CLANG_WARN_STRICT_PROTOTYPES = YES; 208 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 209 | CLANG_WARN_UNREACHABLE_CODE = YES; 210 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 211 | CODE_SIGN_IDENTITY = "-"; 212 | COPY_PHASE_STRIP = NO; 213 | DEBUG_INFORMATION_FORMAT = dwarf; 214 | ENABLE_STRICT_OBJC_MSGSEND = YES; 215 | ENABLE_TESTABILITY = YES; 216 | GCC_C_LANGUAGE_STANDARD = gnu99; 217 | GCC_DYNAMIC_NO_PIC = NO; 218 | GCC_NO_COMMON_BLOCKS = YES; 219 | GCC_OPTIMIZATION_LEVEL = 0; 220 | GCC_PREPROCESSOR_DEFINITIONS = ( 221 | "DEBUG=1", 222 | "$(inherited)", 223 | ); 224 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 225 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 226 | GCC_WARN_UNDECLARED_SELECTOR = YES; 227 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 228 | GCC_WARN_UNUSED_FUNCTION = YES; 229 | GCC_WARN_UNUSED_VARIABLE = YES; 230 | MACOSX_DEPLOYMENT_TARGET = 10.10; 231 | MTL_ENABLE_DEBUG_INFO = YES; 232 | ONLY_ACTIVE_ARCH = YES; 233 | SDKROOT = macosx; 234 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 235 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 236 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 237 | SWIFT_VERSION = 4.0; 238 | }; 239 | name = Debug; 240 | }; 241 | 3F1B1DF81EED61B1004279DF /* Release */ = { 242 | isa = XCBuildConfiguration; 243 | buildSettings = { 244 | ALWAYS_SEARCH_USER_PATHS = NO; 245 | CLANG_ANALYZER_NONNULL = YES; 246 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 248 | CLANG_CXX_LIBRARY = "libc++"; 249 | CLANG_ENABLE_MODULES = YES; 250 | CLANG_ENABLE_OBJC_ARC = YES; 251 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 252 | CLANG_WARN_BOOL_CONVERSION = YES; 253 | CLANG_WARN_COMMA = YES; 254 | CLANG_WARN_CONSTANT_CONVERSION = YES; 255 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 256 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 257 | CLANG_WARN_EMPTY_BODY = YES; 258 | CLANG_WARN_ENUM_CONVERSION = YES; 259 | CLANG_WARN_INFINITE_RECURSION = YES; 260 | CLANG_WARN_INT_CONVERSION = YES; 261 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 262 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 264 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 265 | CLANG_WARN_STRICT_PROTOTYPES = YES; 266 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 267 | CLANG_WARN_UNREACHABLE_CODE = YES; 268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 269 | CODE_SIGN_IDENTITY = "-"; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 272 | ENABLE_NS_ASSERTIONS = NO; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_NO_COMMON_BLOCKS = YES; 276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 278 | GCC_WARN_UNDECLARED_SELECTOR = YES; 279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 280 | GCC_WARN_UNUSED_FUNCTION = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | MACOSX_DEPLOYMENT_TARGET = 10.10; 283 | MTL_ENABLE_DEBUG_INFO = NO; 284 | SDKROOT = macosx; 285 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 286 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 287 | SWIFT_VERSION = 4.0; 288 | }; 289 | name = Release; 290 | }; 291 | 3F1B1DFA1EED61B1004279DF /* Debug */ = { 292 | isa = XCBuildConfiguration; 293 | buildSettings = { 294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 295 | CODE_SIGN_ENTITLEMENTS = STM32DeviceExample/STM32DeviceExample.entitlements; 296 | COMBINE_HIDPI_IMAGES = YES; 297 | DEVELOPMENT_TEAM = LGTF372X5G; 298 | INFOPLIST_FILE = STM32DeviceExample/Info.plist; 299 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 300 | MACOSX_DEPLOYMENT_TARGET = 10.10; 301 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.STM32DeviceExample; 302 | PRODUCT_NAME = "$(TARGET_NAME)"; 303 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 304 | SWIFT_VERSION = 4.0; 305 | }; 306 | name = Debug; 307 | }; 308 | 3F1B1DFB1EED61B1004279DF /* Release */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 312 | CODE_SIGN_ENTITLEMENTS = STM32DeviceExample/STM32DeviceExample.entitlements; 313 | COMBINE_HIDPI_IMAGES = YES; 314 | DEVELOPMENT_TEAM = LGTF372X5G; 315 | INFOPLIST_FILE = STM32DeviceExample/Info.plist; 316 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 317 | MACOSX_DEPLOYMENT_TARGET = 10.10; 318 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.STM32DeviceExample; 319 | PRODUCT_NAME = "$(TARGET_NAME)"; 320 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 321 | SWIFT_VERSION = 4.0; 322 | }; 323 | name = Release; 324 | }; 325 | /* End XCBuildConfiguration section */ 326 | 327 | /* Begin XCConfigurationList section */ 328 | 3F1B1DE51EED61B1004279DF /* Build configuration list for PBXProject "STM32DeviceExample" */ = { 329 | isa = XCConfigurationList; 330 | buildConfigurations = ( 331 | 3F1B1DF71EED61B1004279DF /* Debug */, 332 | 3F1B1DF81EED61B1004279DF /* Release */, 333 | ); 334 | defaultConfigurationIsVisible = 0; 335 | defaultConfigurationName = Release; 336 | }; 337 | 3F1B1DF91EED61B1004279DF /* Build configuration list for PBXNativeTarget "STM32DeviceExample" */ = { 338 | isa = XCConfigurationList; 339 | buildConfigurations = ( 340 | 3F1B1DFA1EED61B1004279DF /* Debug */, 341 | 3F1B1DFB1EED61B1004279DF /* Release */, 342 | ); 343 | defaultConfigurationIsVisible = 0; 344 | defaultConfigurationName = Release; 345 | }; 346 | /* End XCConfigurationList section */ 347 | }; 348 | rootObject = 3F1B1DE21EED61B1004279DF /* Project object */; 349 | } 350 | -------------------------------------------------------------------------------- /RaceflightControllerHIDExample/RaceflightControllerHIDExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3F0F35FD1F0504BB00782AAA /* Media in Resources */ = {isa = PBXBuildFile; fileRef = 3F0F35FC1F0504BB00782AAA /* Media */; }; 11 | 3F6C3D9A1EF156890069B6CC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6C3D991EF156890069B6CC /* AppDelegate.swift */; }; 12 | 3F6C3D9C1EF156890069B6CC /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6C3D9B1EF156890069B6CC /* ViewController.swift */; }; 13 | 3F6C3D9E1EF156890069B6CC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3F6C3D9D1EF156890069B6CC /* Assets.xcassets */; }; 14 | 3F6C3DA11EF156890069B6CC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3F6C3D9F1EF156890069B6CC /* Main.storyboard */; }; 15 | 3F6C3DB11EF159480069B6CC /* USBDeviceSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F6C3DB01EF159480069B6CC /* USBDeviceSwift.framework */; }; 16 | 3FC5575F1EF52DB200374FFC /* RFDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FC5575E1EF52DB200374FFC /* RFDevice.swift */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 3F0F35FC1F0504BB00782AAA /* Media */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Media; sourceTree = ""; }; 21 | 3F6C3D961EF156890069B6CC /* RaceflightControllerHIDExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RaceflightControllerHIDExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 3F6C3D991EF156890069B6CC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 23 | 3F6C3D9B1EF156890069B6CC /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 24 | 3F6C3D9D1EF156890069B6CC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 25 | 3F6C3DA01EF156890069B6CC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 3F6C3DA21EF156890069B6CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 27 | 3F6C3DB01EF159480069B6CC /* USBDeviceSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = USBDeviceSwift.framework; path = "../../../Library/Developer/Xcode/DerivedData/USBDeviceSwift-cdeduymzzojyolehaknqwrmbhevl/Build/Products/Debug/USBDeviceSwift.framework"; sourceTree = ""; }; 28 | 3FC5575E1EF52DB200374FFC /* RFDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RFDevice.swift; sourceTree = ""; }; 29 | 3FC557601EF539AB00374FFC /* RaceflightControllerHIDExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RaceflightControllerHIDExample.entitlements; sourceTree = ""; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | 3F6C3D931EF156890069B6CC /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | 3F6C3DB11EF159480069B6CC /* USBDeviceSwift.framework in Frameworks */, 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 3F6C3D8D1EF156890069B6CC = { 45 | isa = PBXGroup; 46 | children = ( 47 | 3F0F35FC1F0504BB00782AAA /* Media */, 48 | 3F6C3D981EF156890069B6CC /* RaceflightControllerHIDExample */, 49 | 3F6C3D971EF156890069B6CC /* Products */, 50 | 3F6C3DAF1EF159470069B6CC /* Frameworks */, 51 | ); 52 | sourceTree = ""; 53 | }; 54 | 3F6C3D971EF156890069B6CC /* Products */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | 3F6C3D961EF156890069B6CC /* RaceflightControllerHIDExample.app */, 58 | ); 59 | name = Products; 60 | sourceTree = ""; 61 | }; 62 | 3F6C3D981EF156890069B6CC /* RaceflightControllerHIDExample */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 3FC557601EF539AB00374FFC /* RaceflightControllerHIDExample.entitlements */, 66 | 3F6C3D991EF156890069B6CC /* AppDelegate.swift */, 67 | 3F6C3D9B1EF156890069B6CC /* ViewController.swift */, 68 | 3FC5575E1EF52DB200374FFC /* RFDevice.swift */, 69 | 3F6C3D9D1EF156890069B6CC /* Assets.xcassets */, 70 | 3F6C3D9F1EF156890069B6CC /* Main.storyboard */, 71 | 3F6C3DA21EF156890069B6CC /* Info.plist */, 72 | ); 73 | path = RaceflightControllerHIDExample; 74 | sourceTree = ""; 75 | }; 76 | 3F6C3DAF1EF159470069B6CC /* Frameworks */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 3F6C3DB01EF159480069B6CC /* USBDeviceSwift.framework */, 80 | ); 81 | name = Frameworks; 82 | sourceTree = ""; 83 | }; 84 | /* End PBXGroup section */ 85 | 86 | /* Begin PBXNativeTarget section */ 87 | 3F6C3D951EF156890069B6CC /* RaceflightControllerHIDExample */ = { 88 | isa = PBXNativeTarget; 89 | buildConfigurationList = 3F6C3DA51EF156890069B6CC /* Build configuration list for PBXNativeTarget "RaceflightControllerHIDExample" */; 90 | buildPhases = ( 91 | 3F6C3D921EF156890069B6CC /* Sources */, 92 | 3F6C3D931EF156890069B6CC /* Frameworks */, 93 | 3F6C3D941EF156890069B6CC /* Resources */, 94 | ); 95 | buildRules = ( 96 | ); 97 | dependencies = ( 98 | ); 99 | name = RaceflightControllerHIDExample; 100 | productName = RaceflightControllerHIDExample; 101 | productReference = 3F6C3D961EF156890069B6CC /* RaceflightControllerHIDExample.app */; 102 | productType = "com.apple.product-type.application"; 103 | }; 104 | /* End PBXNativeTarget section */ 105 | 106 | /* Begin PBXProject section */ 107 | 3F6C3D8E1EF156890069B6CC /* Project object */ = { 108 | isa = PBXProject; 109 | attributes = { 110 | LastSwiftUpdateCheck = 0830; 111 | LastUpgradeCheck = 0900; 112 | ORGANIZATIONNAME = "Artem Hruzd"; 113 | TargetAttributes = { 114 | 3F6C3D951EF156890069B6CC = { 115 | CreatedOnToolsVersion = 8.3.3; 116 | DevelopmentTeam = LGTF372X5G; 117 | LastSwiftMigration = 0920; 118 | ProvisioningStyle = Automatic; 119 | SystemCapabilities = { 120 | com.apple.Sandbox = { 121 | enabled = 1; 122 | }; 123 | }; 124 | }; 125 | }; 126 | }; 127 | buildConfigurationList = 3F6C3D911EF156890069B6CC /* Build configuration list for PBXProject "RaceflightControllerHIDExample" */; 128 | compatibilityVersion = "Xcode 3.2"; 129 | developmentRegion = English; 130 | hasScannedForEncodings = 0; 131 | knownRegions = ( 132 | en, 133 | Base, 134 | ); 135 | mainGroup = 3F6C3D8D1EF156890069B6CC; 136 | productRefGroup = 3F6C3D971EF156890069B6CC /* Products */; 137 | projectDirPath = ""; 138 | projectRoot = ""; 139 | targets = ( 140 | 3F6C3D951EF156890069B6CC /* RaceflightControllerHIDExample */, 141 | ); 142 | }; 143 | /* End PBXProject section */ 144 | 145 | /* Begin PBXResourcesBuildPhase section */ 146 | 3F6C3D941EF156890069B6CC /* Resources */ = { 147 | isa = PBXResourcesBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 3F0F35FD1F0504BB00782AAA /* Media in Resources */, 151 | 3F6C3D9E1EF156890069B6CC /* Assets.xcassets in Resources */, 152 | 3F6C3DA11EF156890069B6CC /* Main.storyboard in Resources */, 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | /* End PBXResourcesBuildPhase section */ 157 | 158 | /* Begin PBXSourcesBuildPhase section */ 159 | 3F6C3D921EF156890069B6CC /* Sources */ = { 160 | isa = PBXSourcesBuildPhase; 161 | buildActionMask = 2147483647; 162 | files = ( 163 | 3FC5575F1EF52DB200374FFC /* RFDevice.swift in Sources */, 164 | 3F6C3D9C1EF156890069B6CC /* ViewController.swift in Sources */, 165 | 3F6C3D9A1EF156890069B6CC /* AppDelegate.swift in Sources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXSourcesBuildPhase section */ 170 | 171 | /* Begin PBXVariantGroup section */ 172 | 3F6C3D9F1EF156890069B6CC /* Main.storyboard */ = { 173 | isa = PBXVariantGroup; 174 | children = ( 175 | 3F6C3DA01EF156890069B6CC /* Base */, 176 | ); 177 | name = Main.storyboard; 178 | sourceTree = ""; 179 | }; 180 | /* End PBXVariantGroup section */ 181 | 182 | /* Begin XCBuildConfiguration section */ 183 | 3F6C3DA31EF156890069B6CC /* Debug */ = { 184 | isa = XCBuildConfiguration; 185 | buildSettings = { 186 | ALWAYS_SEARCH_USER_PATHS = NO; 187 | CLANG_ANALYZER_NONNULL = YES; 188 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 190 | CLANG_CXX_LIBRARY = "libc++"; 191 | CLANG_ENABLE_MODULES = YES; 192 | CLANG_ENABLE_OBJC_ARC = YES; 193 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 194 | CLANG_WARN_BOOL_CONVERSION = YES; 195 | CLANG_WARN_COMMA = YES; 196 | CLANG_WARN_CONSTANT_CONVERSION = YES; 197 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 198 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 199 | CLANG_WARN_EMPTY_BODY = YES; 200 | CLANG_WARN_ENUM_CONVERSION = YES; 201 | CLANG_WARN_INFINITE_RECURSION = YES; 202 | CLANG_WARN_INT_CONVERSION = YES; 203 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 204 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 206 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 207 | CLANG_WARN_STRICT_PROTOTYPES = YES; 208 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 209 | CLANG_WARN_UNREACHABLE_CODE = YES; 210 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 211 | CODE_SIGN_IDENTITY = "-"; 212 | COPY_PHASE_STRIP = NO; 213 | DEBUG_INFORMATION_FORMAT = dwarf; 214 | ENABLE_STRICT_OBJC_MSGSEND = YES; 215 | ENABLE_TESTABILITY = YES; 216 | GCC_C_LANGUAGE_STANDARD = gnu99; 217 | GCC_DYNAMIC_NO_PIC = NO; 218 | GCC_NO_COMMON_BLOCKS = YES; 219 | GCC_OPTIMIZATION_LEVEL = 0; 220 | GCC_PREPROCESSOR_DEFINITIONS = ( 221 | "DEBUG=1", 222 | "$(inherited)", 223 | ); 224 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 225 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 226 | GCC_WARN_UNDECLARED_SELECTOR = YES; 227 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 228 | GCC_WARN_UNUSED_FUNCTION = YES; 229 | GCC_WARN_UNUSED_VARIABLE = YES; 230 | MACOSX_DEPLOYMENT_TARGET = 10.12; 231 | MTL_ENABLE_DEBUG_INFO = YES; 232 | ONLY_ACTIVE_ARCH = YES; 233 | SDKROOT = macosx; 234 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 235 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 236 | SWIFT_VERSION = 4.0; 237 | }; 238 | name = Debug; 239 | }; 240 | 3F6C3DA41EF156890069B6CC /* Release */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | CLANG_ANALYZER_NONNULL = YES; 245 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 246 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 247 | CLANG_CXX_LIBRARY = "libc++"; 248 | CLANG_ENABLE_MODULES = YES; 249 | CLANG_ENABLE_OBJC_ARC = YES; 250 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_COMMA = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INFINITE_RECURSION = YES; 259 | CLANG_WARN_INT_CONVERSION = YES; 260 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 261 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 263 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 264 | CLANG_WARN_STRICT_PROTOTYPES = YES; 265 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 266 | CLANG_WARN_UNREACHABLE_CODE = YES; 267 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 268 | CODE_SIGN_IDENTITY = "-"; 269 | COPY_PHASE_STRIP = NO; 270 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 271 | ENABLE_NS_ASSERTIONS = NO; 272 | ENABLE_STRICT_OBJC_MSGSEND = YES; 273 | GCC_C_LANGUAGE_STANDARD = gnu99; 274 | GCC_NO_COMMON_BLOCKS = YES; 275 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 276 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 277 | GCC_WARN_UNDECLARED_SELECTOR = YES; 278 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 279 | GCC_WARN_UNUSED_FUNCTION = YES; 280 | GCC_WARN_UNUSED_VARIABLE = YES; 281 | MACOSX_DEPLOYMENT_TARGET = 10.12; 282 | MTL_ENABLE_DEBUG_INFO = NO; 283 | SDKROOT = macosx; 284 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 285 | SWIFT_VERSION = 4.0; 286 | }; 287 | name = Release; 288 | }; 289 | 3F6C3DA61EF156890069B6CC /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 293 | CODE_SIGN_ENTITLEMENTS = RaceflightControllerHIDExample/RaceflightControllerHIDExample.entitlements; 294 | COMBINE_HIDPI_IMAGES = YES; 295 | DEVELOPMENT_TEAM = LGTF372X5G; 296 | INFOPLIST_FILE = RaceflightControllerHIDExample/Info.plist; 297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 298 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.RaceflightControllerHIDExample; 299 | PRODUCT_NAME = "$(TARGET_NAME)"; 300 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 301 | SWIFT_VERSION = 4.0; 302 | }; 303 | name = Debug; 304 | }; 305 | 3F6C3DA71EF156890069B6CC /* Release */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 309 | CODE_SIGN_ENTITLEMENTS = RaceflightControllerHIDExample/RaceflightControllerHIDExample.entitlements; 310 | COMBINE_HIDPI_IMAGES = YES; 311 | DEVELOPMENT_TEAM = LGTF372X5G; 312 | INFOPLIST_FILE = RaceflightControllerHIDExample/Info.plist; 313 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 314 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.RaceflightControllerHIDExample; 315 | PRODUCT_NAME = "$(TARGET_NAME)"; 316 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 317 | SWIFT_VERSION = 4.0; 318 | }; 319 | name = Release; 320 | }; 321 | /* End XCBuildConfiguration section */ 322 | 323 | /* Begin XCConfigurationList section */ 324 | 3F6C3D911EF156890069B6CC /* Build configuration list for PBXProject "RaceflightControllerHIDExample" */ = { 325 | isa = XCConfigurationList; 326 | buildConfigurations = ( 327 | 3F6C3DA31EF156890069B6CC /* Debug */, 328 | 3F6C3DA41EF156890069B6CC /* Release */, 329 | ); 330 | defaultConfigurationIsVisible = 0; 331 | defaultConfigurationName = Release; 332 | }; 333 | 3F6C3DA51EF156890069B6CC /* Build configuration list for PBXNativeTarget "RaceflightControllerHIDExample" */ = { 334 | isa = XCConfigurationList; 335 | buildConfigurations = ( 336 | 3F6C3DA61EF156890069B6CC /* Debug */, 337 | 3F6C3DA71EF156890069B6CC /* Release */, 338 | ); 339 | defaultConfigurationIsVisible = 0; 340 | defaultConfigurationName = Release; 341 | }; 342 | /* End XCConfigurationList section */ 343 | }; 344 | rootObject = 3F6C3D8E1EF156890069B6CC /* Project object */; 345 | } 346 | -------------------------------------------------------------------------------- /USBDeviceSwift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3F4799681EEE923E0095CBFF /* USBDeviceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4799671EEE923E0095CBFF /* USBDeviceMonitor.swift */; }; 11 | 3F6C3D881EF134BE0069B6CC /* Supporting Files in Resources */ = {isa = PBXBuildFile; fileRef = 3F6C3D871EF134BE0069B6CC /* Supporting Files */; }; 12 | 3F6C3D8A1EF14D4C0069B6CC /* HIDDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6C3D891EF14D4C0069B6CC /* HIDDevice.swift */; }; 13 | 3F6C3D8C1EF14D740069B6CC /* HIDDeviceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6C3D8B1EF14D740069B6CC /* HIDDeviceMonitor.swift */; }; 14 | 3F8A574D2052851400E5BD99 /* SerialDeviceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A574C2052851400E5BD99 /* SerialDeviceMonitor.swift */; }; 15 | 3F8A574F2052853000E5BD99 /* SerialDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A574E2052853000E5BD99 /* SerialDevice.swift */; }; 16 | 3F9E47E91EED5B59001D4FDD /* USBDeviceSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F9E47E71EED5B59001D4FDD /* USBDeviceSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 3F9E47F01EED5ECF001D4FDD /* USBDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F9E47EF1EED5ECF001D4FDD /* USBDevice.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 3F4799671EEE923E0095CBFF /* USBDeviceMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = USBDeviceMonitor.swift; sourceTree = ""; }; 22 | 3F6C3D871EF134BE0069B6CC /* Supporting Files */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "Supporting Files"; sourceTree = ""; }; 23 | 3F6C3D891EF14D4C0069B6CC /* HIDDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HIDDevice.swift; sourceTree = ""; }; 24 | 3F6C3D8B1EF14D740069B6CC /* HIDDeviceMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HIDDeviceMonitor.swift; sourceTree = ""; }; 25 | 3F8A574C2052851400E5BD99 /* SerialDeviceMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialDeviceMonitor.swift; sourceTree = ""; }; 26 | 3F8A574E2052853000E5BD99 /* SerialDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialDevice.swift; sourceTree = ""; }; 27 | 3F9E47E41EED5B59001D4FDD /* USBDeviceSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = USBDeviceSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 3F9E47E71EED5B59001D4FDD /* USBDeviceSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = USBDeviceSwift.h; sourceTree = ""; }; 29 | 3F9E47EF1EED5ECF001D4FDD /* USBDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = USBDevice.swift; sourceTree = ""; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | 3F9E47E01EED5B59001D4FDD /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 3F1B1DFE1EED6281004279DF /* Frameworks */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | ); 47 | name = Frameworks; 48 | sourceTree = ""; 49 | }; 50 | 3F9E47DA1EED5B59001D4FDD = { 51 | isa = PBXGroup; 52 | children = ( 53 | 3F6C3D871EF134BE0069B6CC /* Supporting Files */, 54 | 3F9E47E61EED5B59001D4FDD /* Sources */, 55 | 3F9E47E51EED5B59001D4FDD /* Products */, 56 | 3F1B1DFE1EED6281004279DF /* Frameworks */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | 3F9E47E51EED5B59001D4FDD /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 3F9E47E41EED5B59001D4FDD /* USBDeviceSwift.framework */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | 3F9E47E61EED5B59001D4FDD /* Sources */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 3F9E47E71EED5B59001D4FDD /* USBDeviceSwift.h */, 72 | 3F9E47EF1EED5ECF001D4FDD /* USBDevice.swift */, 73 | 3F4799671EEE923E0095CBFF /* USBDeviceMonitor.swift */, 74 | 3F6C3D891EF14D4C0069B6CC /* HIDDevice.swift */, 75 | 3F6C3D8B1EF14D740069B6CC /* HIDDeviceMonitor.swift */, 76 | 3F8A574E2052853000E5BD99 /* SerialDevice.swift */, 77 | 3F8A574C2052851400E5BD99 /* SerialDeviceMonitor.swift */, 78 | ); 79 | path = Sources; 80 | sourceTree = ""; 81 | }; 82 | /* End PBXGroup section */ 83 | 84 | /* Begin PBXHeadersBuildPhase section */ 85 | 3F9E47E11EED5B59001D4FDD /* Headers */ = { 86 | isa = PBXHeadersBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | 3F9E47E91EED5B59001D4FDD /* USBDeviceSwift.h in Headers */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | /* End PBXHeadersBuildPhase section */ 94 | 95 | /* Begin PBXNativeTarget section */ 96 | 3F9E47E31EED5B59001D4FDD /* USBDeviceSwift */ = { 97 | isa = PBXNativeTarget; 98 | buildConfigurationList = 3F9E47EC1EED5B59001D4FDD /* Build configuration list for PBXNativeTarget "USBDeviceSwift" */; 99 | buildPhases = ( 100 | 3F9E47DF1EED5B59001D4FDD /* Sources */, 101 | 3F9E47E01EED5B59001D4FDD /* Frameworks */, 102 | 3F9E47E11EED5B59001D4FDD /* Headers */, 103 | 3F9E47E21EED5B59001D4FDD /* Resources */, 104 | ); 105 | buildRules = ( 106 | ); 107 | dependencies = ( 108 | ); 109 | name = USBDeviceSwift; 110 | productName = USBDeviceSwift; 111 | productReference = 3F9E47E41EED5B59001D4FDD /* USBDeviceSwift.framework */; 112 | productType = "com.apple.product-type.framework"; 113 | }; 114 | /* End PBXNativeTarget section */ 115 | 116 | /* Begin PBXProject section */ 117 | 3F9E47DB1EED5B59001D4FDD /* Project object */ = { 118 | isa = PBXProject; 119 | attributes = { 120 | LastUpgradeCheck = 0900; 121 | ORGANIZATIONNAME = "Artem Hruzd"; 122 | TargetAttributes = { 123 | 3F9E47E31EED5B59001D4FDD = { 124 | CreatedOnToolsVersion = 8.3.3; 125 | DevelopmentTeam = LGTF372X5G; 126 | LastSwiftMigration = 0920; 127 | ProvisioningStyle = Automatic; 128 | }; 129 | }; 130 | }; 131 | buildConfigurationList = 3F9E47DE1EED5B59001D4FDD /* Build configuration list for PBXProject "USBDeviceSwift" */; 132 | compatibilityVersion = "Xcode 3.2"; 133 | developmentRegion = English; 134 | hasScannedForEncodings = 0; 135 | knownRegions = ( 136 | en, 137 | ); 138 | mainGroup = 3F9E47DA1EED5B59001D4FDD; 139 | productRefGroup = 3F9E47E51EED5B59001D4FDD /* Products */; 140 | projectDirPath = ""; 141 | projectRoot = ""; 142 | targets = ( 143 | 3F9E47E31EED5B59001D4FDD /* USBDeviceSwift */, 144 | ); 145 | }; 146 | /* End PBXProject section */ 147 | 148 | /* Begin PBXResourcesBuildPhase section */ 149 | 3F9E47E21EED5B59001D4FDD /* Resources */ = { 150 | isa = PBXResourcesBuildPhase; 151 | buildActionMask = 2147483647; 152 | files = ( 153 | 3F6C3D881EF134BE0069B6CC /* Supporting Files in Resources */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXResourcesBuildPhase section */ 158 | 159 | /* Begin PBXSourcesBuildPhase section */ 160 | 3F9E47DF1EED5B59001D4FDD /* Sources */ = { 161 | isa = PBXSourcesBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | 3F9E47F01EED5ECF001D4FDD /* USBDevice.swift in Sources */, 165 | 3F8A574F2052853000E5BD99 /* SerialDevice.swift in Sources */, 166 | 3F8A574D2052851400E5BD99 /* SerialDeviceMonitor.swift in Sources */, 167 | 3F4799681EEE923E0095CBFF /* USBDeviceMonitor.swift in Sources */, 168 | 3F6C3D8C1EF14D740069B6CC /* HIDDeviceMonitor.swift in Sources */, 169 | 3F6C3D8A1EF14D4C0069B6CC /* HIDDevice.swift in Sources */, 170 | ); 171 | runOnlyForDeploymentPostprocessing = 0; 172 | }; 173 | /* End PBXSourcesBuildPhase section */ 174 | 175 | /* Begin XCBuildConfiguration section */ 176 | 3F9E47EA1EED5B59001D4FDD /* Debug */ = { 177 | isa = XCBuildConfiguration; 178 | buildSettings = { 179 | ALWAYS_SEARCH_USER_PATHS = NO; 180 | CLANG_ANALYZER_NONNULL = YES; 181 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 182 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 183 | CLANG_CXX_LIBRARY = "libc++"; 184 | CLANG_ENABLE_MODULES = YES; 185 | CLANG_ENABLE_OBJC_ARC = YES; 186 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 187 | CLANG_WARN_BOOL_CONVERSION = YES; 188 | CLANG_WARN_COMMA = YES; 189 | CLANG_WARN_CONSTANT_CONVERSION = YES; 190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 191 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 192 | CLANG_WARN_EMPTY_BODY = YES; 193 | CLANG_WARN_ENUM_CONVERSION = YES; 194 | CLANG_WARN_INFINITE_RECURSION = YES; 195 | CLANG_WARN_INT_CONVERSION = YES; 196 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 197 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 198 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 199 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 200 | CLANG_WARN_STRICT_PROTOTYPES = YES; 201 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 202 | CLANG_WARN_UNREACHABLE_CODE = YES; 203 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 204 | CODE_SIGN_IDENTITY = "-"; 205 | COPY_PHASE_STRIP = NO; 206 | CURRENT_PROJECT_VERSION = 1; 207 | DEBUG_INFORMATION_FORMAT = dwarf; 208 | ENABLE_STRICT_OBJC_MSGSEND = YES; 209 | ENABLE_TESTABILITY = YES; 210 | GCC_C_LANGUAGE_STANDARD = gnu99; 211 | GCC_DYNAMIC_NO_PIC = NO; 212 | GCC_NO_COMMON_BLOCKS = YES; 213 | GCC_OPTIMIZATION_LEVEL = 0; 214 | GCC_PREPROCESSOR_DEFINITIONS = ( 215 | "DEBUG=1", 216 | "$(inherited)", 217 | ); 218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 220 | GCC_WARN_UNDECLARED_SELECTOR = YES; 221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 222 | GCC_WARN_UNUSED_FUNCTION = YES; 223 | GCC_WARN_UNUSED_VARIABLE = YES; 224 | MACOSX_DEPLOYMENT_TARGET = 10.10; 225 | MTL_ENABLE_DEBUG_INFO = YES; 226 | ONLY_ACTIVE_ARCH = YES; 227 | SDKROOT = macosx; 228 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 229 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 230 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 231 | SWIFT_VERSION = 4.0; 232 | VERSIONING_SYSTEM = "apple-generic"; 233 | VERSION_INFO_PREFIX = ""; 234 | }; 235 | name = Debug; 236 | }; 237 | 3F9E47EB1EED5B59001D4FDD /* Release */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | CLANG_ANALYZER_NONNULL = YES; 242 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_MODULES = YES; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 248 | CLANG_WARN_BOOL_CONVERSION = YES; 249 | CLANG_WARN_COMMA = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 252 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 253 | CLANG_WARN_EMPTY_BODY = YES; 254 | CLANG_WARN_ENUM_CONVERSION = YES; 255 | CLANG_WARN_INFINITE_RECURSION = YES; 256 | CLANG_WARN_INT_CONVERSION = YES; 257 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 258 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 259 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 260 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 261 | CLANG_WARN_STRICT_PROTOTYPES = YES; 262 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 263 | CLANG_WARN_UNREACHABLE_CODE = YES; 264 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 265 | CODE_SIGN_IDENTITY = "-"; 266 | COPY_PHASE_STRIP = NO; 267 | CURRENT_PROJECT_VERSION = 1; 268 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 269 | ENABLE_NS_ASSERTIONS = NO; 270 | ENABLE_STRICT_OBJC_MSGSEND = YES; 271 | GCC_C_LANGUAGE_STANDARD = gnu99; 272 | GCC_NO_COMMON_BLOCKS = YES; 273 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 274 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 275 | GCC_WARN_UNDECLARED_SELECTOR = YES; 276 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 277 | GCC_WARN_UNUSED_FUNCTION = YES; 278 | GCC_WARN_UNUSED_VARIABLE = YES; 279 | MACOSX_DEPLOYMENT_TARGET = 10.10; 280 | MTL_ENABLE_DEBUG_INFO = NO; 281 | SDKROOT = macosx; 282 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 283 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 284 | SWIFT_VERSION = 4.0; 285 | VERSIONING_SYSTEM = "apple-generic"; 286 | VERSION_INFO_PREFIX = ""; 287 | }; 288 | name = Release; 289 | }; 290 | 3F9E47ED1EED5B59001D4FDD /* Debug */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | CLANG_ENABLE_MODULES = YES; 294 | CODE_SIGN_IDENTITY = ""; 295 | COMBINE_HIDPI_IMAGES = YES; 296 | DEFINES_MODULE = YES; 297 | DEVELOPMENT_TEAM = LGTF372X5G; 298 | DYLIB_COMPATIBILITY_VERSION = 1; 299 | DYLIB_CURRENT_VERSION = 1; 300 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 301 | FRAMEWORK_VERSION = A; 302 | INFOPLIST_FILE = "Supporting Files/Info.plist"; 303 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 304 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 305 | MACOSX_DEPLOYMENT_TARGET = 10.10; 306 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.USBDeviceSwift; 307 | PRODUCT_NAME = "$(TARGET_NAME)"; 308 | SKIP_INSTALL = YES; 309 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 310 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 311 | SWIFT_VERSION = 4.0; 312 | }; 313 | name = Debug; 314 | }; 315 | 3F9E47EE1EED5B59001D4FDD /* Release */ = { 316 | isa = XCBuildConfiguration; 317 | buildSettings = { 318 | CLANG_ENABLE_MODULES = YES; 319 | CODE_SIGN_IDENTITY = ""; 320 | COMBINE_HIDPI_IMAGES = YES; 321 | DEFINES_MODULE = YES; 322 | DEVELOPMENT_TEAM = LGTF372X5G; 323 | DYLIB_COMPATIBILITY_VERSION = 1; 324 | DYLIB_CURRENT_VERSION = 1; 325 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 326 | FRAMEWORK_VERSION = A; 327 | INFOPLIST_FILE = "Supporting Files/Info.plist"; 328 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 329 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 330 | MACOSX_DEPLOYMENT_TARGET = 10.10; 331 | PRODUCT_BUNDLE_IDENTIFIER = ah.com.USBDeviceSwift; 332 | PRODUCT_NAME = "$(TARGET_NAME)"; 333 | SKIP_INSTALL = YES; 334 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 335 | SWIFT_VERSION = 4.0; 336 | }; 337 | name = Release; 338 | }; 339 | /* End XCBuildConfiguration section */ 340 | 341 | /* Begin XCConfigurationList section */ 342 | 3F9E47DE1EED5B59001D4FDD /* Build configuration list for PBXProject "USBDeviceSwift" */ = { 343 | isa = XCConfigurationList; 344 | buildConfigurations = ( 345 | 3F9E47EA1EED5B59001D4FDD /* Debug */, 346 | 3F9E47EB1EED5B59001D4FDD /* Release */, 347 | ); 348 | defaultConfigurationIsVisible = 0; 349 | defaultConfigurationName = Release; 350 | }; 351 | 3F9E47EC1EED5B59001D4FDD /* Build configuration list for PBXNativeTarget "USBDeviceSwift" */ = { 352 | isa = XCConfigurationList; 353 | buildConfigurations = ( 354 | 3F9E47ED1EED5B59001D4FDD /* Debug */, 355 | 3F9E47EE1EED5B59001D4FDD /* Release */, 356 | ); 357 | defaultConfigurationIsVisible = 0; 358 | defaultConfigurationName = Release; 359 | }; 360 | /* End XCConfigurationList section */ 361 | }; 362 | rootObject = 3F9E47DB1EED5B59001D4FDD /* Project object */; 363 | } 364 | -------------------------------------------------------------------------------- /CleanFlightSerialExample/CleanFlightSerialExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | Default 530 | 531 | 532 | 533 | 534 | 535 | 536 | Left to Right 537 | 538 | 539 | 540 | 541 | 542 | 543 | Right to Left 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | Default 555 | 556 | 557 | 558 | 559 | 560 | 561 | Left to Right 562 | 563 | 564 | 565 | 566 | 567 | 568 | Right to Left 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | --------------------------------------------------------------------------------