From ac7f5c20eb9cb0f71bd402196cae768aba3e4f71 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 27 Feb 2016 07:26:15 -0600 Subject: [PATCH 001/116] Add MaxBasal record, and modernized objective c --- RileyLink.xcodeproj/project.pbxproj | 6 +++ RileyLink/AppDelegate.m | 12 ++--- RileyLink/CmdBase.h | 2 +- RileyLink/ConfigureViewController.m | 14 +++--- RileyLink/DeviceLinkMessage.m | 2 +- RileyLink/FindDeviceMessage.m | 2 +- RileyLink/HistoryPage.h | 6 +-- RileyLink/HistoryPage.m | 8 ++-- RileyLink/ISO8601DateFormatter.m | 4 +- RileyLink/Log.h | 2 +- RileyLink/Log.m | 6 +-- RileyLink/MainAppViewController.m | 12 ++--- RileyLink/MessageBase.h | 2 +- RileyLink/MessageBase.m | 10 ++--- RileyLink/MeterMessage.h | 2 +- RileyLink/MinimedPacket.h | 2 +- RileyLink/MinimedPacket.m | 20 ++++----- RileyLink/NSData+Conversion.m | 6 +-- RileyLink/NightScoutBolus.m | 2 +- RileyLink/NightScoutUploader.m | 44 +++++++++---------- RileyLink/NightscoutWebView.m | 12 ++--- RileyLink/PacketGeneratorViewController.m | 4 +- RileyLink/PacketTableViewCell.m | 8 ++-- RileyLink/PumpChatViewController.m | 4 +- RileyLink/PumpHistoryEvents/PHEBgReceived.h | 6 +-- RileyLink/PumpHistoryEvents/PHEBgReceived.m | 2 +- RileyLink/PumpHistoryEvents/PHECalBGForPH.h | 2 +- RileyLink/PumpHistoryEvents/PHECalBGForPH.m | 2 +- .../PumpHistoryEvents/PHEChangeMaxBasal.h | 13 ++++++ .../PumpHistoryEvents/PHEChangeMaxBasal.m | 22 ++++++++++ .../PumpHistoryEvents/PHEResultDailyTotal.m | 4 +- .../PumpHistoryEvents/PumpHistoryEventBase.h | 12 ++--- .../PumpHistoryEvents/PumpHistoryEventBase.m | 28 ++++++------ RileyLink/PumpOpsSynchronous.h | 6 +-- RileyLink/PumpOpsSynchronous.m | 32 +++++++------- RileyLink/PumpState.h | 2 +- RileyLink/PumpState.m | 2 +- RileyLink/PumpStatusMessage.m | 32 +++++++------- RileyLink/RileyLink-Info.plist | 2 +- RileyLink/RileyLinkBLEDevice.m | 6 +-- RileyLink/RileyLinkBLEManager.m | 4 +- RileyLink/RileyLinkDeviceViewController.m | 2 +- RileyLink/RileyLinkListTableViewController.m | 18 ++++---- RileyLink/RileyLinkTableViewCell.m | 2 +- RileyLink/SWRevealViewController.h | 12 ++--- RileyLink/SWRevealViewController.m | 42 +++++++++--------- .../TPKeyboardAvoidingCollectionView.h | 2 +- .../TPKeyboardAvoidingCollectionView.m | 8 ++-- .../TPKeyboardAvoidingScrollView.h | 2 +- .../TPKeyboardAvoidingScrollView.m | 6 +-- .../TPKeyboardAvoidingTableView.h | 2 +- .../TPKeyboardAvoidingTableView.m | 10 ++--- ...UIScrollView+TPKeyboardAvoidingAdditions.h | 4 +- ...UIScrollView+TPKeyboardAvoidingAdditions.m | 16 +++---- sync_version.rb | 10 ++--- 55 files changed, 273 insertions(+), 232 deletions(-) create mode 100644 RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.h create mode 100644 RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.m diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 640eb79b6..067dc6970 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 43C99C6F1B898B7100BC03D4 /* MenuHeaderTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C99C6E1B898B7100BC03D4 /* MenuHeaderTableViewCell.m */; }; 43EC9DCB1B786C6200DB0D18 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */; }; C10A62921C55F8E200E635EE /* UpdateRegisterCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = C10A62911C55F8E200E635EE /* UpdateRegisterCmd.m */; }; + C10D9B981C7D6F5200378342 /* PHEChangeMaxBasal.m in Sources */ = {isa = PBXBuildFile; fileRef = C10D9B971C7D6F5200378342 /* PHEChangeMaxBasal.m */; }; C10EAA9D1C5AE9A600B0838F /* GetVersionCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = C10EAA9C1C5AE9A600B0838F /* GetVersionCmd.m */; }; C10EAAA31C5B3A0800B0838F /* PumpOpsSynchronous.m in Sources */ = {isa = PBXBuildFile; fileRef = C10EAAA21C5B3A0800B0838F /* PumpOpsSynchronous.m */; }; C10EAAA61C5C507E00B0838F /* PumpOps.m in Sources */ = {isa = PBXBuildFile; fileRef = C10EAAA51C5C507E00B0838F /* PumpOps.m */; }; @@ -146,6 +147,8 @@ 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; C10A62901C55F8E200E635EE /* UpdateRegisterCmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateRegisterCmd.h; sourceTree = ""; }; C10A62911C55F8E200E635EE /* UpdateRegisterCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateRegisterCmd.m; sourceTree = ""; }; + C10D9B961C7D6F5200378342 /* PHEChangeMaxBasal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PHEChangeMaxBasal.h; sourceTree = ""; }; + C10D9B971C7D6F5200378342 /* PHEChangeMaxBasal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PHEChangeMaxBasal.m; sourceTree = ""; }; C10EAA9B1C5AE9A600B0838F /* GetVersionCmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetVersionCmd.h; sourceTree = ""; }; C10EAA9C1C5AE9A600B0838F /* GetVersionCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GetVersionCmd.m; sourceTree = ""; }; C10EAAA11C5B3A0800B0838F /* PumpOpsSynchronous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PumpOpsSynchronous.h; sourceTree = ""; }; @@ -657,6 +660,8 @@ C152C1A71C3A40760009B4B8 /* PHEChangeWatchdogMarriageProfile.m */, C152C1A91C3A40A80009B4B8 /* PHEDeleteOtherDeviceID.h */, C152C1AA1C3A40A80009B4B8 /* PHEDeleteOtherDeviceID.m */, + C10D9B961C7D6F5200378342 /* PHEChangeMaxBasal.h */, + C10D9B971C7D6F5200378342 /* PHEChangeMaxBasal.m */, ); path = PumpHistoryEvents; sourceTree = ""; @@ -976,6 +981,7 @@ C10EAAA31C5B3A0800B0838F /* PumpOpsSynchronous.m in Sources */, C139AC821BFD8CF800B0518F /* PHEAlarmSensor.m in Sources */, C139ACA81BFD8CF800B0518F /* PHEPrime.m in Sources */, + C10D9B981C7D6F5200378342 /* PHEChangeMaxBasal.m in Sources */, C139AC861BFD8CF800B0518F /* PHEBolusNormal.m in Sources */, C139AC9C1BFD8CF800B0518F /* PHEChangeSensorSetup2.m in Sources */, C139ACAB1BFD8CF800B0518F /* PHERewind.m in Sources */, diff --git a/RileyLink/AppDelegate.m b/RileyLink/AppDelegate.m index 265f999cf..844810594 100644 --- a/RileyLink/AppDelegate.m +++ b/RileyLink/AppDelegate.m @@ -28,7 +28,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSLog(@"Could not remove file: %@", path); } - self.pump = [[PumpState alloc] initWithPumpId:[[Config sharedInstance] pumpID]]; + self.pump = [[PumpState alloc] initWithPumpId:[Config sharedInstance].pumpID]; return YES; } @@ -75,10 +75,10 @@ - (NSManagedObjectContext *)managedObjectContext return _managedObjectContext; } - NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; + NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator; if (coordinator != nil) { _managedObjectContext = [[NSManagedObjectContext alloc] init]; - [_managedObjectContext setPersistentStoreCoordinator:coordinator]; + _managedObjectContext.persistentStoreCoordinator = coordinator; } return _managedObjectContext; } @@ -103,10 +103,10 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator return _persistentStoreCoordinator; } - NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"RileyLink.sqlite"]; + NSURL *storeURL = [self.applicationDocumentsDirectory URLByAppendingPathComponent:@"RileyLink.sqlite"]; NSError *error = nil; - _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; + _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { /* Replace this implementation with code to handle the error appropriately. @@ -142,7 +142,7 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator // Returns the URL to the application's Documents directory. - (NSURL *)applicationDocumentsDirectory { - return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; + return [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject; } diff --git a/RileyLink/CmdBase.h b/RileyLink/CmdBase.h index 15ebfda78..5a316abee 100644 --- a/RileyLink/CmdBase.h +++ b/RileyLink/CmdBase.h @@ -18,7 +18,7 @@ @interface CmdBase : NSObject -- (NSData*)data; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSData *data; @property (nonatomic, strong) NSData *response; diff --git a/RileyLink/ConfigureViewController.m b/RileyLink/ConfigureViewController.m index 76ee99931..e4741d727 100644 --- a/RileyLink/ConfigureViewController.m +++ b/RileyLink/ConfigureViewController.m @@ -30,7 +30,7 @@ - (void)viewDidLoad { [super viewDidLoad]; if (self.revealViewController != nil) { menuButton.target = self.revealViewController; - [menuButton setAction:@selector(revealToggle:)]; + menuButton.action = @selector(revealToggle:); [self.view addGestureRecognizer: self.revealViewController.panGestureRecognizer]; } @@ -85,15 +85,15 @@ - (void)viewDidAppear:(BOOL)animated { } - (void) loadValues { - nightscoutURL.text = [[Config sharedInstance] nightscoutURL]; - nightscoutAPISecret.text = [[Config sharedInstance] nightscoutAPISecret]; - pumpId.text = [[Config sharedInstance] pumpID]; + nightscoutURL.text = [Config sharedInstance].nightscoutURL; + nightscoutAPISecret.text = [Config sharedInstance].nightscoutAPISecret; + pumpId.text = [Config sharedInstance].pumpID; } - (void) saveValues { - [[Config sharedInstance] setNightscoutURL: nightscoutURL.text]; - [[Config sharedInstance] setNightscoutAPISecret: nightscoutAPISecret.text]; - [[Config sharedInstance] setPumpID:pumpId.text]; + [Config sharedInstance].nightscoutURL = nightscoutURL.text; + [Config sharedInstance].nightscoutAPISecret = nightscoutAPISecret.text; + [Config sharedInstance].pumpID = pumpId.text; } diff --git a/RileyLink/DeviceLinkMessage.m b/RileyLink/DeviceLinkMessage.m index 641d9bfb6..a8f82d9d0 100644 --- a/RileyLink/DeviceLinkMessage.m +++ b/RileyLink/DeviceLinkMessage.m @@ -21,7 +21,7 @@ - (NSInteger) sequence { } - (NSString*) deviceAddress { - return [[self.data hexadecimalString] substringWithRange:NSMakeRange(2, 6)]; + return [(self.data).hexadecimalString substringWithRange:NSMakeRange(2, 6)]; } @end diff --git a/RileyLink/FindDeviceMessage.m b/RileyLink/FindDeviceMessage.m index 41479bd9f..89a8aec68 100644 --- a/RileyLink/FindDeviceMessage.m +++ b/RileyLink/FindDeviceMessage.m @@ -21,7 +21,7 @@ - (NSInteger) sequence { } - (NSString*) deviceAddress { - return [[self.data hexadecimalString] substringWithRange:NSMakeRange(2, 6)]; + return [(self.data).hexadecimalString substringWithRange:NSMakeRange(2, 6)]; } @end diff --git a/RileyLink/HistoryPage.h b/RileyLink/HistoryPage.h index 33ff48531..1c384ae38 100644 --- a/RileyLink/HistoryPage.h +++ b/RileyLink/HistoryPage.h @@ -15,8 +15,8 @@ @property (nonatomic, nullable, readonly, strong) PumpModel *pumpModel; @property (nonatomic, nullable, readonly, strong) NSDictionary *registry; -- (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullable PumpModel *)model; -- (nonnull NSArray*) decode; -- (BOOL) isCRCValid; +- (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullable PumpModel *)model NS_DESIGNATED_INITIALIZER; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSArray * _Nonnull decode; +@property (NS_NONATOMIC_IOSONLY, getter=isCRCValid, readonly) BOOL CRCValid; @end diff --git a/RileyLink/HistoryPage.m b/RileyLink/HistoryPage.m index 3a2f80ffc..dd29644c5 100644 --- a/RileyLink/HistoryPage.m +++ b/RileyLink/HistoryPage.m @@ -33,12 +33,12 @@ - (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullab [NSException raise:@"Missing class method" format:@"%@ does not implement +eventTypeCode.", eventClass]; } NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; - [invocation setSelector:selector]; - [invocation setTarget:eventClass]; + invocation.selector = selector; + invocation.target = eventClass; [invocation invoke]; int returnValue; [invocation getReturnValue:&returnValue]; - NSNumber *eventCode = [NSNumber numberWithInt:returnValue]; + NSNumber *eventCode = @(returnValue); d[eventCode] = eventClass; } } @@ -85,7 +85,7 @@ - (BOOL) isCRCValid { } - (nonnull const unsigned char *) bytes { - return [_data bytes]; + return _data.bytes; } - (PumpHistoryEventBase*) matchEvent:(NSUInteger) offset { diff --git a/RileyLink/ISO8601DateFormatter.m b/RileyLink/ISO8601DateFormatter.m index c4790098e..785bcc6b0 100644 --- a/RileyLink/ISO8601DateFormatter.m +++ b/RileyLink/ISO8601DateFormatter.m @@ -241,7 +241,7 @@ - (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out if (strict) timeSep = ISO8601DefaultTimeSeparatorCharacter; NSAssert(timeSep != '\0', @"Time separator must not be NUL."); - BOOL isValidDate = ([string length] > 0U); + BOOL isValidDate = (string.length > 0U); NSTimeZone *timeZone = nil; const unichar *ch = (const unichar *)[string cStringUsingEncoding:NSUnicodeStringEncoding]; @@ -728,7 +728,7 @@ - (NSString *) replaceColonsInString:(NSString *)timeFormat withTimeSeparator:(u [timeFormatMutable replaceOccurrencesOfString:@":" withString:[NSString stringWithCharacters:&timeSep length:1U] options:NSBackwardsSearch | NSLiteralSearch - range:(NSRange){ 0UL, [timeFormat length] }]; + range:(NSRange){ 0UL, timeFormat.length }]; timeFormat = timeFormatMutable; } return timeFormat; diff --git a/RileyLink/Log.h b/RileyLink/Log.h index d02bdeb01..90b2d686c 100644 --- a/RileyLink/Log.h +++ b/RileyLink/Log.h @@ -9,7 +9,7 @@ #ifndef RILEYLINK_Log_h #define RILEYLINK_Log_h -#define LOG_TO_NS 0 +//#define LOG_TO_NS 1 #define NSLog(args...) _Log(@"DEBUG ", __FILE__,__LINE__,__PRETTY_FUNCTION__,args); @interface Log : NSObject diff --git a/RileyLink/Log.m b/RileyLink/Log.m index 641e47969..440dbc890 100644 --- a/RileyLink/Log.m +++ b/RileyLink/Log.m @@ -63,7 +63,7 @@ void append(NSString *msg){ NSString *path = [documentsDirectory stringByAppendingPathComponent:@"logfile.txt"]; // create if needed if (![[NSFileManager defaultManager] fileExistsAtPath:path]){ - fprintf(stderr,"Creating file at %s",[path UTF8String]); + fprintf(stderr,"Creating file at %s",path.UTF8String); [[NSData data] writeToFile:path atomically:YES]; } // append @@ -78,7 +78,7 @@ void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcNa static NSDateFormatter *dateFormat = nil; if (nil == dateFormat) { dateFormat = [[NSDateFormatter alloc] init]; // NOT NSDateFormatter *dateFormat = ... - [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"]; + dateFormat.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; } va_list ap; @@ -87,7 +87,7 @@ void _Log(NSString *prefix, const char *file, int lineNumber, const char *funcNa NSDate *time = [NSDate date]; NSString *msg = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%@: %@", [dateFormat stringFromDate:time], format] arguments:ap]; va_end (ap); - fprintf(stderr,"%s", [msg UTF8String]); + fprintf(stderr,"%s", msg.UTF8String); append(msg); } @end \ No newline at end of file diff --git a/RileyLink/MainAppViewController.m b/RileyLink/MainAppViewController.m index c2d996dd8..9b1af8428 100644 --- a/RileyLink/MainAppViewController.m +++ b/RileyLink/MainAppViewController.m @@ -38,10 +38,10 @@ - (void)viewDidLoad { [UIView setAnimationsEnabled:NO]; self.uploader = [[NightScoutUploader alloc] init]; - self.uploader.siteURL = [[Config sharedInstance] nightscoutURL]; - self.uploader.APISecret = [[Config sharedInstance] nightscoutAPISecret]; + self.uploader.siteURL = [Config sharedInstance].nightscoutURL; + self.uploader.APISecret = [Config sharedInstance].nightscoutAPISecret; - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; self.managedObjectContext = appDelegate.managedObjectContext; [self setupAutoConnect]; @@ -59,17 +59,17 @@ - (void)setupAutoConnect { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"RileyLinkRecord" inManagedObjectContext:self.managedObjectContext]; - [fetchRequest setEntity:entity]; + fetchRequest.entity = entity; NSError *error; NSMutableSet *autoConnectIds = [[NSMutableSet alloc] init]; NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; for (RileyLinkRecord *record in fetchedObjects) { NSLog(@"Loaded: %@ from db", record.name); - if ([record.autoConnect boolValue]) { + if ((record.autoConnect).boolValue) { [autoConnectIds addObject:record.peripheralId]; } } - [[RileyLinkBLEManager sharedManager] setAutoConnectIds:autoConnectIds]; + [RileyLinkBLEManager sharedManager].autoConnectIds = autoConnectIds; } diff --git a/RileyLink/MessageBase.h b/RileyLink/MessageBase.h index 8f54bf341..26b131c0e 100644 --- a/RileyLink/MessageBase.h +++ b/RileyLink/MessageBase.h @@ -18,7 +18,7 @@ - (NSInteger) getBits:(nullable NSString*)key; - (void) setBits:(nonnull NSString*)key toValue:(NSInteger)val; - (unsigned char) getBitAtIndex:(NSInteger)idx; -- (NSInteger)bitsOffset; +@property (NS_NONATOMIC_IOSONLY, readonly) NSInteger bitsOffset; @property (nonatomic, readonly) PacketType packetType; @property (nonatomic, readonly) MessageType messageType; diff --git a/RileyLink/MessageBase.m b/RileyLink/MessageBase.m index 56062e8e6..7c0ccc0c9 100644 --- a/RileyLink/MessageBase.m +++ b/RileyLink/MessageBase.m @@ -50,10 +50,10 @@ - (NSInteger)bitsOffset { } - (NSInteger) getBits:(NSString*)key { - NSArray *range = [self bitBlocks][key]; - NSInteger bitsNeeded = [[range lastObject] integerValue]; + NSArray *range = self.bitBlocks[key]; + NSInteger bitsNeeded = [range.lastObject integerValue]; // bitBlocks start at byte idx 5 - NSInteger offset = [[range firstObject] integerValue] + ([self bitsOffset]*8); + NSInteger offset = [range.firstObject integerValue] + ([self bitsOffset]*8); NSInteger rval = 0; while (bitsNeeded > 0) { rval = (rval << 1) + [self getBitAtIndex:offset++]; @@ -67,8 +67,8 @@ - (void) setBits:(NSString*)key toValue:(NSInteger)val { } - (unsigned char)byteAt:(NSInteger)index { - if (_data && index < [_data length]) { - return ((unsigned char*)[_data bytes])[index]; + if (_data && index < _data.length) { + return ((unsigned char*)_data.bytes)[index]; } else { return 0; } diff --git a/RileyLink/MeterMessage.h b/RileyLink/MeterMessage.h index 9936bf2f0..c368b1110 100644 --- a/RileyLink/MeterMessage.h +++ b/RileyLink/MeterMessage.h @@ -15,7 +15,7 @@ @property (nonatomic, readonly) NSInteger glucose; -- (BOOL) isAck; +@property (NS_NONATOMIC_IOSONLY, getter=isAck, readonly) BOOL ack; @end diff --git a/RileyLink/MinimedPacket.h b/RileyLink/MinimedPacket.h index febb418c9..c3e398e02 100644 --- a/RileyLink/MinimedPacket.h +++ b/RileyLink/MinimedPacket.h @@ -36,7 +36,7 @@ typedef NS_ENUM(unsigned char, MessageType) { MESSAGE_TYPE_READ_HISTORY = 0x80, }; -- ( MessageBase* _Nullable)toMessage; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) MessageBase * _Nullable toMessage; - (nonnull instancetype)initWithData:(nonnull NSData*)data NS_DESIGNATED_INITIALIZER; @property (nonatomic, getter=isValid, readonly) BOOL valid; diff --git a/RileyLink/MinimedPacket.m b/RileyLink/MinimedPacket.m index f2820e966..4b1b5ae70 100644 --- a/RileyLink/MinimedPacket.m +++ b/RileyLink/MinimedPacket.m @@ -37,7 +37,7 @@ - (instancetype)initWithData:(NSData*)data if (self) { _codingErrorCount = 0; if (data.length > 0) { - unsigned char rssiDec = ((const unsigned char*)[data bytes])[0]; + unsigned char rssiDec = ((const unsigned char*)data.bytes)[0]; unsigned char rssiOffset = 73; if (rssiDec >= 128) { self.rssi = (short)((short)( rssiDec - 256) / 2) - rssiOffset; @@ -46,7 +46,7 @@ - (instancetype)initWithData:(NSData*)data } } if (data.length > 1) { - self.packetNumber = ((const unsigned char*)[data bytes])[1]; + self.packetNumber = ((const unsigned char*)data.bytes)[1]; } if (data.length > 2) { @@ -61,7 +61,7 @@ - (BOOL) crcValid { if (_data.length < 2) { return NO; } - uint8_t packetCrc = ((uint8_t*)[_data bytes])[_data.length-1]; + uint8_t packetCrc = ((uint8_t*)_data.bytes)[_data.length-1]; uint8_t crc = [CRC8 compute:[_data subdataWithRange:NSMakeRange(0, _data.length-1)]]; return crc == packetCrc; } @@ -76,7 +76,7 @@ + (NSData*)encodeData:(NSData*)data { unsigned char crc = [CRC8 compute:data]; [dataPlusCrc appendBytes:&crc length:1]; char codes[16] = {21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28}; - const unsigned char *inBytes = [dataPlusCrc bytes]; + const unsigned char *inBytes = dataPlusCrc.bytes; unsigned int acc = 0x0; int bitcount = 0; for (int i=0; i < dataPlusCrc.length; i++) { @@ -122,10 +122,10 @@ - (NSData*)decodeRF:(NSData*) rawData { @14: @14, @28: @15}; NSMutableData *output = [NSMutableData data]; - const unsigned char *bytes = [rawData bytes]; + const unsigned char *bytes = rawData.bytes; int availBits = 0; unsigned int x = 0; - for (int i = 0; i < [rawData length]; i++) + for (int i = 0; i < rawData.length; i++) { x = (x << 8) + bytes[i]; availBits += 8; @@ -133,7 +133,7 @@ - (NSData*)decodeRF:(NSData*) rawData { NSNumber *hiNibble = codes[@(x >> (availBits - 6))]; NSNumber *loNibble = codes[@((x >> (availBits - 12)) & 0b111111)]; if (hiNibble && loNibble) { - unsigned char decoded = ([hiNibble integerValue] << 4) + [loNibble integerValue]; + unsigned char decoded = (hiNibble.integerValue << 4) + loNibble.integerValue; [output appendBytes:&decoded length:1]; } else { _codingErrorCount += 1; @@ -146,12 +146,12 @@ - (NSData*)decodeRF:(NSData*) rawData { } - (NSString*) hexadecimalString { - return [_data hexadecimalString]; + return _data.hexadecimalString; } - (unsigned char)byteAt:(NSInteger)index { - if (_data && index < [_data length]) { - return ((unsigned char*)[_data bytes])[index]; + if (_data && index < _data.length) { + return ((unsigned char*)_data.bytes)[index]; } else { return 0; } diff --git a/RileyLink/NSData+Conversion.m b/RileyLink/NSData+Conversion.m index f8c688975..b77eabe68 100644 --- a/RileyLink/NSData+Conversion.m +++ b/RileyLink/NSData+Conversion.m @@ -13,12 +13,12 @@ @implementation NSData (Conversion) - (NSString *)hexadecimalString { /* Returns hexadecimal string of NSData. Empty string if data is empty. */ - const unsigned char *dataBuffer = (const unsigned char *)[self bytes]; + const unsigned char *dataBuffer = (const unsigned char *)self.bytes; if (!dataBuffer) return [NSString string]; - NSUInteger dataLength = [self length]; + NSUInteger dataLength = self.length; NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; for (int i = 0; i < dataLength; ++i) @@ -32,7 +32,7 @@ + (NSData*)dataWithHexadecimalString: (NSString*)hexStr NSMutableData *data = [[NSMutableData alloc] init]; unsigned char whole_byte; char byte_chars[3] = {'\0','\0','\0'}; - for (int i = 0; i < ([hexStr length] / 2); i++) { + for (int i = 0; i < (hexStr.length / 2); i++) { byte_chars[0] = [hexStr characterAtIndex:i*2]; byte_chars[1] = [hexStr characterAtIndex:i*2+1]; whole_byte = strtol(byte_chars, NULL, 16); diff --git a/RileyLink/NightScoutBolus.m b/RileyLink/NightScoutBolus.m index 9420ea479..07e2a05af 100644 --- a/RileyLink/NightScoutBolus.m +++ b/RileyLink/NightScoutBolus.m @@ -31,7 +31,7 @@ - (instancetype)init state = [NSMutableDictionary dictionary]; previous = [NSMutableArray array]; dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss"; } return self; } diff --git a/RileyLink/NightScoutUploader.m b/RileyLink/NightScoutUploader.m index 902824194..fb641a8b2 100644 --- a/RileyLink/NightScoutUploader.m +++ b/RileyLink/NightScoutUploader.m @@ -132,19 +132,19 @@ - (void)testDecodeHistory { - (void)deviceConnected:(NSNotification *)note { - self.activeRileyLink = [note object]; + self.activeRileyLink = note.object; } - (void)deviceDisconnected:(NSNotification *)note { - if (self.activeRileyLink == [note object]) { + if (self.activeRileyLink == note.object) { self.activeRileyLink = nil; } } - (void)rileyLinkAdded:(NSNotification *)note { - RileyLinkBLEDevice *device = [note object]; + RileyLinkBLEDevice *device = note.object; [device enableIdleListeningOnChannel:0]; } @@ -152,7 +152,7 @@ - (void)timerTriggered:(id)sender { logMemUsage(); - if ([lastHistoryAttempt timeIntervalSinceNow] < (- 5 * 60) && !fetchHistoryScheduled) { + if (lastHistoryAttempt.timeIntervalSinceNow < (- 5 * 60) && !fetchHistoryScheduled) { NSLog(@"No fetchHistory for over five minutes. Triggering one"); [self fetchHistory:nil]; } @@ -180,7 +180,7 @@ - (void) fetchHistory:(id)sender { } if (self.activeRileyLink == nil) { - for (RileyLinkBLEDevice *device in [[RileyLinkBLEManager sharedManager] rileyLinkList]) { + for (RileyLinkBLEDevice *device in [RileyLinkBLEManager sharedManager].rileyLinkList) { if (device.state == RileyLinkStateConnected) { self.activeRileyLink = device; break; @@ -195,7 +195,7 @@ - (void) fetchHistory:(id)sender { NSLog(@"Using RileyLink \"%@\" to fetchHistory.", self.activeRileyLink.name); - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; PumpOps *pumpOps = [[PumpOps alloc] initWithPumpState:appDelegate.pump andDevice:self.activeRileyLink]; [pumpOps getHistoryPage:0 withHandler:^(NSDictionary * _Nonnull res) { @@ -312,7 +312,7 @@ - (NSString*)trendToDirection:(GlucoseTrend)trend { - (void)addPacket:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)device { - if (![packet isValid]) { + if (!packet.valid) { return; } @@ -320,9 +320,9 @@ - (void)addPacket:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)device [self storeRawPacket:packet fromDevice:device]; } - if ([packet packetType] == PacketTypeSentry && - [packet messageType] == MESSAGE_TYPE_PUMP_STATUS && - [packet.address isEqualToString:[[Config sharedInstance] pumpID]]) { + if (packet.packetType == PacketTypeSentry && + packet.messageType == MESSAGE_TYPE_PUMP_STATUS && + [packet.address isEqualToString:[Config sharedInstance].pumpID]) { // Make this RL the active one, for history dumping. self.activeRileyLink = device; [self handlePumpStatus:packet fromDevice:device withRSSI:packet.rssi]; @@ -334,7 +334,7 @@ - (void)addPacket:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)device // TODO: send ack. also, we can probably wait less than 25s if we ack; the 25s // above is mainly to avoid colliding with subsequent packets. - } else if ([packet packetType] == PacketTypeMeter) { + } else if (packet.packetType == PacketTypeMeter) { [self handleMeterMessage:packet]; } @@ -343,13 +343,13 @@ - (void)addPacket:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)device - (void) storeRawPacket:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)device { NSDate *now = [NSDate date]; - NSTimeInterval seconds = [now timeIntervalSince1970]; + NSTimeInterval seconds = now.timeIntervalSince1970; NSNumber *epochTime = @(seconds * 1000); NSDictionary *entry = @{@"date": epochTime, @"dateString": [self.dateFormatter stringFromDate:now], - @"rfpacket": [packet.data hexadecimalString], + @"rfpacket": (packet.data).hexadecimalString, @"device": device.deviceURI, @"rssi": @(packet.rssi), @"type": @"rfpacket" @@ -360,12 +360,12 @@ - (void) storeRawPacket:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)d - (void) handlePumpStatus:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice*)device withRSSI:(NSInteger)rssi { PumpStatusMessage *msg = [[PumpStatusMessage alloc] initWithData:packet.data]; - if ([packet.address isEqualToString:[[Config sharedInstance] pumpID]]) { + if ([packet.address isEqualToString:[Config sharedInstance].pumpID]) { NSDate *validTime = msg.sensorTime; NSInteger glucose = msg.glucose; - switch ([msg sensorStatus]) { + switch (msg.sensorStatus) { case SENSOR_STATUS_HIGH_BG: glucose = 401; break; @@ -384,7 +384,7 @@ - (void) handlePumpStatus:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice* break; } - NSNumber *epochTime = @([validTime timeIntervalSince1970] * 1000); + NSNumber *epochTime = @(validTime.timeIntervalSince1970 * 1000); NSMutableDictionary *status = [NSMutableDictionary dictionary]; @@ -394,7 +394,7 @@ - (void) handlePumpStatus:(MinimedPacket*)packet fromDevice:(RileyLinkBLEDevice* // TODO: use battery monitoring to post updates if we're not hearing from pump? UIDevice *uploaderDevice = [UIDevice currentDevice]; if (uploaderDevice.isBatteryMonitoringEnabled) { - NSNumber *batteryPct = @((int)([[UIDevice currentDevice] batteryLevel] * 100)); + NSNumber *batteryPct = @((int)([UIDevice currentDevice].batteryLevel * 100)); status[@"uploader"] = @{@"battery":batteryPct}; } @@ -449,7 +449,7 @@ - (void) handleMeterMessage:(MinimedPacket*)packet { } msg.dateReceived = [NSDate date]; - NSTimeInterval seconds = [msg.dateReceived timeIntervalSince1970]; + NSTimeInterval seconds = (msg.dateReceived).timeIntervalSince1970; NSNumber *epochTime = @(seconds * 1000); NSDictionary *entry = @{@"date": epochTime, @@ -477,7 +477,7 @@ - (void) flushAll { NSArray *logEntries = [Log popLogEntries]; if (logEntries.count > 0) { NSDate *date = [NSDate date]; - NSTimeInterval seconds = [date timeIntervalSince1970]; + NSTimeInterval seconds = date.timeIntervalSince1970; NSNumber *epochTime = @(seconds * 1000); NSDictionary *entry = @@ -565,13 +565,13 @@ - (void) reportJSON:(NSArray*)outgoingJSON toNightScoutEndpoint:(NSString*)endpo NSData *sendData = [NSJSONSerialization dataWithJSONObject:outgoingJSON options:NSJSONWritingPrettyPrinted error:&error]; //NSString *jsonPost = [[NSString alloc] initWithData:sendData encoding:NSUTF8StringEncoding]; //NSLog(@"Posting to %@, %@", [uploadURL absoluteString], jsonPost); - [request setHTTPMethod:@"POST"]; + request.HTTPMethod = @"POST"; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - [request setValue:[self.APISecret sha1] forHTTPHeaderField:@"api-secret"]; + [request setValue:(self.APISecret).sha1 forHTTPHeaderField:@"api-secret"]; - [request setHTTPBody: sendData]; + request.HTTPBody = sendData; [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:completionHandler] resume]; } diff --git a/RileyLink/NightscoutWebView.m b/RileyLink/NightscoutWebView.m index 68b523c0c..1eec8d397 100644 --- a/RileyLink/NightscoutWebView.m +++ b/RileyLink/NightscoutWebView.m @@ -26,16 +26,16 @@ - (void)viewDidLoad if (self.revealViewController != nil) { menuButton.target = self.revealViewController; - [menuButton setAction:@selector(revealToggle:)]; + menuButton.action = @selector(revealToggle:); [self.view addGestureRecognizer: self.revealViewController.panGestureRecognizer]; self.revealViewController.rearViewRevealWidth = 162; - if (![[Config sharedInstance] hasValidConfiguration]) { + if (![Config sharedInstance].hasValidConfiguration) { UINavigationController *configNav = [self.storyboard instantiateViewControllerWithIdentifier:@"configuration"]; - ConfigureViewController *configViewController = [configNav viewControllers][0]; + ConfigureViewController *configViewController = configNav.viewControllers[0]; [configViewController doInitialConfiguration]; - [self.revealViewController setFrontViewController:configNav]; + (self.revealViewController).frontViewController = configNav; } } @@ -43,7 +43,7 @@ - (void)viewDidLoad } - (void)loadPage { - NSURL *url = [NSURL URLWithString:[[Config sharedInstance] nightscoutURL]]; + NSURL *url = [NSURL URLWithString:[Config sharedInstance].nightscoutURL]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [_webView loadRequest:request]; } @@ -62,7 +62,7 @@ - (void)didReceiveMemoryWarning - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { [UIAlertView showWithTitle:@"Network Error" - message:[error localizedDescription] + message:error.localizedDescription cancelButtonTitle:@"OK" otherButtonTitles:@[@"Retry"] tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { diff --git a/RileyLink/PacketGeneratorViewController.m b/RileyLink/PacketGeneratorViewController.m index 064bece50..fbf958ade 100644 --- a/RileyLink/PacketGeneratorViewController.m +++ b/RileyLink/PacketGeneratorViewController.m @@ -40,7 +40,7 @@ - (void)viewDidLoad { } - (void)doneChangingChannel { - txChannel = [channelNumberTextField.text intValue]; + txChannel = (channelNumberTextField.text).intValue; [channelNumberTextField resignFirstResponder]; } @@ -67,7 +67,7 @@ - (void)sendTestPacket { if (encodeDataSwitch.on) { data = [MinimedPacket encodeData:data]; } - packetData.text = [data hexadecimalString]; + packetData.text = data.hexadecimalString; SendAndListenCmd *cmd = [[SendAndListenCmd alloc] init]; cmd.sendChannel = txChannel; cmd.repeatCount = 0; diff --git a/RileyLink/PacketTableViewCell.m b/RileyLink/PacketTableViewCell.m index 1747ab9a8..2939a1bc8 100644 --- a/RileyLink/PacketTableViewCell.m +++ b/RileyLink/PacketTableViewCell.m @@ -25,11 +25,11 @@ @implementation PacketTableViewCell + (void)initialize { dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setLocale:[NSLocale currentLocale]]; - [dateFormatter setDateStyle:NSDateFormatterShortStyle]; + dateFormatter.locale = [NSLocale currentLocale]; + dateFormatter.dateStyle = NSDateFormatterShortStyle; timeFormatter = [[NSDateFormatter alloc] init]; - [timeFormatter setLocale:[NSLocale currentLocale]]; - [timeFormatter setTimeStyle:NSDateFormatterShortStyle]; + timeFormatter.locale = [NSLocale currentLocale]; + timeFormatter.timeStyle = NSDateFormatterShortStyle; } - (void)awakeFromNib { diff --git a/RileyLink/PumpChatViewController.m b/RileyLink/PumpChatViewController.m index 0c5ed65e0..1ce3b6a04 100644 --- a/RileyLink/PumpChatViewController.m +++ b/RileyLink/PumpChatViewController.m @@ -35,9 +35,9 @@ @implementation PumpChatViewController - (void)viewDidLoad { [super viewDidLoad]; - pumpIdLabel.text = [NSString stringWithFormat:@"PumpID: %@", [[Config sharedInstance] pumpID]]; + pumpIdLabel.text = [NSString stringWithFormat:@"PumpID: %@", [Config sharedInstance].pumpID]; - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; _pumpOps = [[PumpOps alloc] initWithPumpState:appDelegate.pump andDevice:_device]; } diff --git a/RileyLink/PumpHistoryEvents/PHEBgReceived.h b/RileyLink/PumpHistoryEvents/PHEBgReceived.h index 7f6aca34a..b8a115918 100644 --- a/RileyLink/PumpHistoryEvents/PHEBgReceived.h +++ b/RileyLink/PumpHistoryEvents/PHEBgReceived.h @@ -7,10 +7,10 @@ @interface PHEBgReceived : PumpHistoryEventBase -- (int) bloodGlucose; +@property (NS_NONATOMIC_IOSONLY, readonly) int bloodGlucose; -- (nonnull NSString*) meterId; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString * _Nonnull meterId; -- (nonnull NSDateComponents*) timestamp; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSDateComponents * _Nonnull timestamp; @end diff --git a/RileyLink/PumpHistoryEvents/PHEBgReceived.m b/RileyLink/PumpHistoryEvents/PHEBgReceived.m index f0382b5e6..3be34a5bb 100644 --- a/RileyLink/PumpHistoryEvents/PHEBgReceived.m +++ b/RileyLink/PumpHistoryEvents/PHEBgReceived.m @@ -20,7 +20,7 @@ - (int) bloodGlucose { } - (NSString*) meterId { - return [[self.data subdataWithRange:NSMakeRange(7, 3)] hexadecimalString]; + return [self.data subdataWithRange:NSMakeRange(7, 3)].hexadecimalString; } - (NSDateComponents*) timestamp { diff --git a/RileyLink/PumpHistoryEvents/PHECalBGForPH.h b/RileyLink/PumpHistoryEvents/PHECalBGForPH.h index bd7367cbd..5e19f1a26 100644 --- a/RileyLink/PumpHistoryEvents/PHECalBGForPH.h +++ b/RileyLink/PumpHistoryEvents/PHECalBGForPH.h @@ -7,6 +7,6 @@ @interface PHECalBGForPH : PumpHistoryEventBase -- (int) amount; +@property (NS_NONATOMIC_IOSONLY, readonly) int amount; @end diff --git a/RileyLink/PumpHistoryEvents/PHECalBGForPH.m b/RileyLink/PumpHistoryEvents/PHECalBGForPH.m index 00613721b..8c1975859 100644 --- a/RileyLink/PumpHistoryEvents/PHECalBGForPH.m +++ b/RileyLink/PumpHistoryEvents/PHECalBGForPH.m @@ -21,7 +21,7 @@ - (int) length { - (NSDictionary*) asJSON { NSMutableDictionary *base = [[super asJSON] mutableCopy]; if ([self amount] > 0) { - base[@"amount"] = [NSNumber numberWithInt:[self amount]]; + base[@"amount"] = @([self amount]); } return base; } diff --git a/RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.h b/RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.h new file mode 100644 index 000000000..9bb47b3ae --- /dev/null +++ b/RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.h @@ -0,0 +1,13 @@ +// +// PHEChangeMaxBasal.h +// RileyLink +// +// Created by Pete Schwamb on 2/23/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +#import "PumpHistoryEventBase.h" + +@interface PHEChangeMaxBasal : PumpHistoryEventBase + +@end diff --git a/RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.m b/RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.m new file mode 100644 index 000000000..6b3d8cd6d --- /dev/null +++ b/RileyLink/PumpHistoryEvents/PHEChangeMaxBasal.m @@ -0,0 +1,22 @@ +// +// PHEChangeMaxBasal.m +// RileyLink +// +// Created by Pete Schwamb on 2/23/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +#import "PHEChangeMaxBasal.h" + +@implementation PHEChangeMaxBasal + ++ (int) eventTypeCode { + return 0x2c; +} + + +- (int) length { + return 7; +} + +@end diff --git a/RileyLink/PumpHistoryEvents/PHEResultDailyTotal.m b/RileyLink/PumpHistoryEvents/PHEResultDailyTotal.m index 6079e7369..b6166c34c 100644 --- a/RileyLink/PumpHistoryEvents/PHEResultDailyTotal.m +++ b/RileyLink/PumpHistoryEvents/PHEResultDailyTotal.m @@ -27,8 +27,8 @@ - (NSDateComponents*) timestamp { NSDateComponents *c = [self parseDate2Byte:5]; NSCalendar *cal = [NSCalendar currentCalendar]; - [cal setTimeZone:[NSTimeZone localTimeZone]]; - [cal setLocale:[NSLocale currentLocale]]; + cal.timeZone = [NSTimeZone localTimeZone]; + cal.locale = [NSLocale currentLocale]; NSDate *date = [cal dateFromComponents:c]; NSDateComponents *dayComponent = [[NSDateComponents alloc] init]; diff --git a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.h b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.h index a26b0afca..ae4f4e70f 100644 --- a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.h +++ b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.h @@ -14,17 +14,17 @@ @property (nonatomic, nonnull, readonly, strong) NSData *data; @property (nonatomic, nullable, readonly, strong) PumpModel *pumpModel; -- (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullable PumpModel *)model; +- (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullable PumpModel *)model NS_DESIGNATED_INITIALIZER; + (int) eventTypeCode; -- (int) length; +@property (NS_NONATOMIC_IOSONLY, readonly) int length; - (uint8_t)byteAt:(NSInteger)index; - (nonnull NSDateComponents*) parseDateComponents:(NSInteger)offset; - (nonnull NSDateComponents*) parseDate2Byte:(NSInteger)offset; -- (nullable NSDateComponents*) timestamp; -- (nonnull NSString*) timestampStr; -- (nonnull NSDictionary*) asJSON; -- (nonnull NSString*) typeName; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSDateComponents * _Nullable timestamp; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString * _Nonnull timestampStr; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSDictionary * _Nonnull asJSON; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString * _Nonnull typeName; @end diff --git a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m index 7cfef7997..c64e8daf5 100644 --- a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m +++ b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m @@ -48,8 +48,8 @@ + (int) eventTypeCode { } - (uint8_t)byteAt:(NSInteger)index { - if (_data && index < [_data length]) { - return ((uint8_t*)[_data bytes])[index]; + if (_data && index < _data.length) { + return ((uint8_t*)_data.bytes)[index]; } else { return 0; } @@ -57,20 +57,20 @@ - (uint8_t)byteAt:(NSInteger)index { - (NSDateComponents*) parseDateComponents:(NSInteger)offset { NSDateComponents *comps = [[NSDateComponents alloc] init]; - [comps setSecond:[self byteAt:offset] & 0x3f]; - [comps setMinute:[self byteAt:offset+1] & 0x3f]; - [comps setHour:[self byteAt:offset+2] & 0x1f]; - [comps setDay:[self byteAt:offset+3] & 0x1f]; - [comps setMonth:([self byteAt:offset] >>4 & 0xc) + ([self byteAt:offset+1] >> 6)]; - [comps setYear:2000 + ([self byteAt:offset+4] & 0b1111111)]; + comps.second = [self byteAt:offset] & 0x3f; + comps.minute = [self byteAt:offset+1] & 0x3f; + comps.hour = [self byteAt:offset+2] & 0x1f; + comps.day = [self byteAt:offset+3] & 0x1f; + comps.month = ([self byteAt:offset] >>4 & 0xc) + ([self byteAt:offset+1] >> 6); + comps.year = 2000 + ([self byteAt:offset+4] & 0b1111111); return comps; } - (NSDateComponents*) parseDate2Byte:(NSInteger)offset { NSDateComponents *comps = [[NSDateComponents alloc] init]; - [comps setDay:[self byteAt:offset] & 0x1f]; - [comps setMonth:(([self byteAt:offset] & 0xe0) >> 4) + (([self byteAt:offset+1] & 0x80) >> 7)]; - [comps setYear:2000 + ([self byteAt:offset+1] & 0b1111111)]; + comps.day = [self byteAt:offset] & 0x1f; + comps.month = (([self byteAt:offset] & 0xe0) >> 4) + (([self byteAt:offset+1] & 0x80) >> 7); + comps.year = 2000 + ([self byteAt:offset+1] & 0b1111111); return comps; } @@ -80,8 +80,8 @@ - (nullable NSDateComponents*) timestamp { - (NSString*) timestampStr { NSCalendar *cal = [NSCalendar currentCalendar]; - [cal setTimeZone:[NSTimeZone localTimeZone]]; - [cal setLocale:[NSLocale currentLocale]]; + cal.timeZone = [NSTimeZone localTimeZone]; + cal.locale = [NSLocale currentLocale]; NSDateComponents *c = [self timestamp]; if (c == nil) { return @""; @@ -106,7 +106,7 @@ - (NSString*) typeName { - (NSDictionary*) asJSON { return @{ @"_type": [self typeName], - @"_raw": [self.data hexadecimalString], + @"_raw": (self.data).hexadecimalString, @"timestamp": self.timestampStr, @"description": self.description }; diff --git a/RileyLink/PumpOpsSynchronous.h b/RileyLink/PumpOpsSynchronous.h index 6ef10235c..f9334deee 100644 --- a/RileyLink/PumpOpsSynchronous.h +++ b/RileyLink/PumpOpsSynchronous.h @@ -18,9 +18,9 @@ - (BOOL) wakeup:(uint8_t)duration; - (void) pressButton; -- (NSString* _Nullable) getPumpModel; -- (NSDictionary* _Nonnull) getBatteryVoltage; +@property (NS_NONATOMIC_IOSONLY, getter=getPumpModel, readonly, copy) NSString * _Nullable pumpModel; +@property (NS_NONATOMIC_IOSONLY, getter=getBatteryVoltage, readonly, copy) NSDictionary * _Nonnull batteryVoltage; - (NSDictionary* _Nonnull) getHistoryPage:(uint8_t)pageNum; -- (NSDictionary* _Nonnull) scanForPump; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSDictionary * _Nonnull scanForPump; @end diff --git a/RileyLink/PumpOpsSynchronous.m b/RileyLink/PumpOpsSynchronous.m index 319df6eb3..4e8b1b966 100644 --- a/RileyLink/PumpOpsSynchronous.m +++ b/RileyLink/PumpOpsSynchronous.m @@ -109,7 +109,7 @@ - (void) pressButton { if ([self wakeIfNeeded]) { - MinimedPacket *response = [self sendAndListen:[[self buttonPressMessage] data]]; + MinimedPacket *response = [self sendAndListen:[self buttonPressMessage].data]; if (response && response.messageType == MESSAGE_TYPE_ACK) { NSLog(@"Pump acknowledged button press (no args)!"); @@ -120,7 +120,7 @@ - (void) pressButton { NSString *args = @"0104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - response = [self sendAndListen:[[self buttonPressMessageWithArgs:args] data]]; + response = [self sendAndListen:[self buttonPressMessageWithArgs:args].data]; if (response && response.messageType == MESSAGE_TYPE_ACK) { NSLog(@"Pump acknowledged button press (with args)!"); @@ -142,12 +142,12 @@ - (MessageBase *)modelQueryMessage - (NSString*) getPumpModel { if ([self wakeIfNeeded]) { - MinimedPacket *response = [self sendAndListen:[[self modelQueryMessage] data]]; + MinimedPacket *response = [self sendAndListen:[self modelQueryMessage].data]; NSLog(@"*********** getPumpModel: %@", [response hexadecimalString]); if (response && response.messageType == MESSAGE_TYPE_GET_PUMP_MODEL) { - return [NSString stringWithCString:&[response.data bytes][7] + return [NSString stringWithCString:&(response.data).bytes[7] encoding:NSASCIIStringEncoding]; } } @@ -161,10 +161,10 @@ - (NSDictionary*) getBatteryVoltage { if ([self wakeIfNeeded]) { - MinimedPacket *response = [self sendAndListen:[[self batteryStatusMessage] data]]; + MinimedPacket *response = [self sendAndListen:[self batteryStatusMessage].data]; if (response && response.valid && response.messageType == MESSAGE_TYPE_GET_BATTERY) { - unsigned char *data = (unsigned char *)[response.data bytes] + 6; + unsigned char *data = (unsigned char *)(response.data).bytes + 6; NSInteger volts = (((int)data[1]) << 8) + data[2]; rvalStatus = data[0] ? @"Low" : @"Normal"; @@ -201,12 +201,12 @@ - (NSDictionary*) scanForPump { NSInteger totalSuccesses = 0; for (NSNumber *freq in frequencies) { - [self setBaseFrequency:[freq floatValue]]; + [self setBaseFrequency:freq.floatValue]; NSInteger successCount = 0; int avgRSSI = 0; int tries = 3; for (int i=0; i bestResult) { - bestResult = [result intValue]; + if (result.intValue > bestResult) { + bestResult = result.intValue; bestIndex = i; } } @@ -251,7 +251,7 @@ - (BOOL) wakeup:(uint8_t) durationMinutes { return YES; } - MinimedPacket *response = [self sendAndListen:[[self powerMessage] data] + MinimedPacket *response = [self sendAndListen:[self powerMessage].data timeoutMS:15000 repeat:200 msBetweenPackets:0 @@ -265,7 +265,7 @@ - (BOOL) wakeup:(uint8_t) durationMinutes { NSString *msg = [NSString stringWithFormat:@"0201%02x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", durationMinutes]; - response = [self sendAndListen:[[self powerMessageWithArgs:msg] data] + response = [self sendAndListen:[self powerMessageWithArgs:msg].data timeoutMS:STANDARD_PUMP_RESPONSE_WINDOW repeat:0 msBetweenPackets:0 @@ -325,7 +325,7 @@ - (NSDictionary*) getHistoryPage:(uint8_t)pageNum { } MinimedPacket *response; - response = [self sendAndListen:[[self msgType:MESSAGE_TYPE_READ_HISTORY withArgs:@"00"] data]]; + response = [self sendAndListen:[self msgType:MESSAGE_TYPE_READ_HISTORY withArgs:@"00"].data]; if (response && response.isValid && response.messageType == MESSAGE_TYPE_ACK) { rssiSum += response.rssi; @@ -339,7 +339,7 @@ - (NSDictionary*) getHistoryPage:(uint8_t)pageNum { NSString *dumpHistArgs = [NSString stringWithFormat:@"01%02x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", pageNum]; - response = [self sendAndListen:[[self msgType:MESSAGE_TYPE_READ_HISTORY withArgs:dumpHistArgs] data]]; + response = [self sendAndListen:[self msgType:MESSAGE_TYPE_READ_HISTORY withArgs:dumpHistArgs].data]; if (response && response.isValid && response.messageType == MESSAGE_TYPE_READ_HISTORY) { rssiSum += response.rssi; @@ -354,7 +354,7 @@ - (NSDictionary*) getHistoryPage:(uint8_t)pageNum { // Send 15 acks, and expect 15 more dumps for (int i=0; i<15; i++) { - response = [self sendAndListen:[[self msgType:MESSAGE_TYPE_ACK withArgs:@"00"] data]]; + response = [self sendAndListen:[self msgType:MESSAGE_TYPE_ACK withArgs:@"00"].data]; if (response && response.isValid && response.messageType == MESSAGE_TYPE_READ_HISTORY) { rssiSum += response.rssi; @@ -374,7 +374,7 @@ - (NSDictionary*) getHistoryPage:(uint8_t)pageNum { // Last ack packet doesn't need a response SendPacketCmd *cmd = [[SendPacketCmd alloc] init]; - cmd.packet = [MinimedPacket encodeData:[[self msgType:MESSAGE_TYPE_ACK withArgs:@"00"] data]]; + cmd.packet = [MinimedPacket encodeData:[self msgType:MESSAGE_TYPE_ACK withArgs:@"00"].data]; [_session doCmd:cmd withTimeoutMs:EXPECTED_MAX_BLE_LATENCY_MS]; return responseDict; } diff --git a/RileyLink/PumpState.h b/RileyLink/PumpState.h index 4b2865dfc..b21e5a11e 100644 --- a/RileyLink/PumpState.h +++ b/RileyLink/PumpState.h @@ -13,7 +13,7 @@ - (nonnull instancetype)initWithPumpId:(nonnull NSString *)pumpId NS_DESIGNATED_INITIALIZER; -- (BOOL) isAwake; +@property (NS_NONATOMIC_IOSONLY, getter=isAwake, readonly) BOOL awake; @property (strong, nonatomic, nonnull) NSString *pumpId; @property (strong, nonatomic, nonnull) NSDate *lastHistoryDump; diff --git a/RileyLink/PumpState.m b/RileyLink/PumpState.m index 838231e72..26e3c885d 100644 --- a/RileyLink/PumpState.m +++ b/RileyLink/PumpState.m @@ -31,7 +31,7 @@ - (instancetype)init NS_UNAVAILABLE } - (BOOL) isAwake { - return (_awakeUntil != nil && [_awakeUntil timeIntervalSinceNow] > 0); + return (_awakeUntil != nil && _awakeUntil.timeIntervalSinceNow > 0); } diff --git a/RileyLink/PumpStatusMessage.m b/RileyLink/PumpStatusMessage.m index 10fc9b6fa..ed3c24919 100644 --- a/RileyLink/PumpStatusMessage.m +++ b/RileyLink/PumpStatusMessage.m @@ -47,7 +47,7 @@ - (NSDate*) nextCal { NSInteger hour = [self getBits:@"next_cal_hour"]; NSInteger minute = [self getBits:@"next_cal_minute"]; - NSDate *pumpDate = [self pumpTime]; + NSDate *pumpDate = self.pumpTime; return [[NSCalendar currentCalendar] nextDateAfterDate:pumpDate matchingHour:hour minute:minute second:0 options:NSCalendarMatchNextTime]; } @@ -88,7 +88,7 @@ - (SensorStatus) sensorStatus { } - (NSString*) sensorStatusString { - switch ([self sensorStatus]) { + switch (self.sensorStatus) { case SENSOR_STATUS_MISSING: return @"Sensor Missing"; case SENSOR_STATUS_METER_BG_NOW: @@ -114,7 +114,7 @@ - (GlucoseTrend) trend { } - (NSInteger) glucose { - if ([self sensorStatus] == SENSOR_STATUS_OK) { + if (self.sensorStatus == SENSOR_STATUS_OK) { return ([self getBits:@"bg_h"] << 1) + [self getBits:@"bg_l"]; } else { return 0; @@ -122,7 +122,7 @@ - (NSInteger) glucose { } - (NSInteger) previousGlucose { - if ([self sensorStatus] == SENSOR_STATUS_OK) { + if (self.sensorStatus == SENSOR_STATUS_OK) { return ([self getBits:@"prev_bg_h"] << 1) + [self getBits:@"prev_bg_l"]; } else { return 0; @@ -140,12 +140,12 @@ - (double) insulinRemaining { - (NSDate*) pumpTime { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [[NSDateComponents alloc] init]; - [components setYear:[self getBits:@"pump_year"]+2000]; - [components setMonth:[self getBits:@"pump_month"]]; - [components setDay:[self getBits:@"pump_day"]]; - [components setHour:[self getBits:@"pump_hour"]]; - [components setMinute:[self getBits:@"pump_minute"]]; - [components setSecond:0]; + components.year = [self getBits:@"pump_year"]+2000; + components.month = [self getBits:@"pump_month"]; + components.day = [self getBits:@"pump_day"]; + components.hour = [self getBits:@"pump_hour"]; + components.minute = [self getBits:@"pump_minute"]; + components.second = 0; return [calendar dateFromComponents:components]; } @@ -153,12 +153,12 @@ - (NSDate*) pumpTime { - (NSDate*) sensorTime { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [[NSDateComponents alloc] init]; - [components setYear:[self getBits:@"sensor_year"]+2000]; - [components setMonth:[self getBits:@"sensor_month"]]; - [components setDay:[self getBits:@"sensor_day"]]; - [components setHour:[self getBits:@"sensor_hour"]]; - [components setMinute:[self getBits:@"sensor_minute"]]; - [components setSecond:0]; + components.year = [self getBits:@"sensor_year"]+2000; + components.month = [self getBits:@"sensor_month"]; + components.day = [self getBits:@"sensor_day"]; + components.hour = [self getBits:@"sensor_hour"]; + components.minute = [self getBits:@"sensor_minute"]; + components.second = 0; return [calendar dateFromComponents:components]; } diff --git a/RileyLink/RileyLink-Info.plist b/RileyLink/RileyLink-Info.plist index b88770f25..0365da5f6 100644 --- a/RileyLink/RileyLink-Info.plist +++ b/RileyLink/RileyLink-Info.plist @@ -23,7 +23,7 @@ CFBundleSignature ???? CFBundleVersion - 0.1.4 + 0.1.4.001 LSApplicationCategoryType LSRequiresIPhoneOS diff --git a/RileyLink/RileyLinkBLEDevice.m b/RileyLink/RileyLinkBLEDevice.m index 7773fadf3..b6a243b6f 100644 --- a/RileyLink/RileyLinkBLEDevice.m +++ b/RileyLink/RileyLinkBLEDevice.m @@ -299,13 +299,13 @@ - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(C haveResponseCount = YES; [self checkVersion]; } else { - const unsigned char responseCount = ((const unsigned char*)[characteristic.value bytes])[0]; + const unsigned char responseCount = ((const unsigned char*)(characteristic.value).bytes)[0]; NSLog(@"Updated response count: %d", responseCount); fetchingResponse = YES; [peripheral readValueForCharacteristic:dataCharacteristic]; } } else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:RILEYLINK_TIMER_TICK_UUID]]) { - const unsigned char timerTick = ((const unsigned char*)[characteristic.value bytes])[0]; + const unsigned char timerTick = ((const unsigned char*)(characteristic.value).bytes)[0]; NSLog(@"Updated timer tick: %d", timerTick); } } @@ -442,7 +442,7 @@ - (void) handleIdleListenerResponse:(NSData *)response { }; [[NSNotificationCenter defaultCenter] postNotificationName:RILEYLINK_EVENT_PACKET_RECEIVED object:self userInfo:attrs]; } else if (response.length > 0) { - uint8_t errorCode = ((uint8_t*)[response bytes])[0]; + uint8_t errorCode = ((uint8_t*)response.bytes)[0]; switch (errorCode) { case SubgRfspyErrorRxTimeout: NSLog(@"Idle rx timeout"); diff --git a/RileyLink/RileyLinkBLEManager.m b/RileyLink/RileyLinkBLEManager.m index 47eb39a31..2b28314bb 100644 --- a/RileyLink/RileyLinkBLEManager.m +++ b/RileyLink/RileyLinkBLEManager.m @@ -38,7 +38,7 @@ + (NSArray *)UUIDsFromUUIDStrings:(NSArray *)UUIDStrings return [NSArray arrayWithArray:UUIDs]; } -+ (instancetype)sharedManager { ++ (RileyLinkBLEManager*)sharedManager { static RileyLinkBLEManager *sharedMyRileyLink = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -143,7 +143,7 @@ - (void)disconnectPeripheral:(CBPeripheral *)peripheral } - (void)attemptReconnectForDisconnectedDevices { - for (RileyLinkBLEDevice *device in [self rileyLinkList]) { + for (RileyLinkBLEDevice *device in self.rileyLinkList) { CBPeripheral *peripheral = device.peripheral; if (peripheral.state == CBPeripheralStateDisconnected && [self.autoConnectIds containsObject:device.peripheralId]) { diff --git a/RileyLink/RileyLinkDeviceViewController.m b/RileyLink/RileyLinkDeviceViewController.m index 51a9dfce9..f6be32c2f 100644 --- a/RileyLink/RileyLinkDeviceViewController.m +++ b/RileyLink/RileyLinkDeviceViewController.m @@ -43,7 +43,7 @@ - (void)viewDidLoad { [self updateNameView]; - autoConnectSwitch.on = [self.rlRecord.autoConnect boolValue]; + autoConnectSwitch.on = (self.rlRecord.autoConnect).boolValue; } -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { diff --git a/RileyLink/RileyLinkListTableViewController.m b/RileyLink/RileyLinkListTableViewController.m index 3af888467..6089face7 100644 --- a/RileyLink/RileyLinkListTableViewController.m +++ b/RileyLink/RileyLinkListTableViewController.m @@ -28,7 +28,7 @@ @implementation RileyLinkListTableViewController - (void)viewDidLoad { [super viewDidLoad]; - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; self.managedObjectContext = appDelegate.managedObjectContext; [[NSNotificationCenter defaultCenter] addObserver:self @@ -46,7 +46,7 @@ - (void)viewDidLoad { if (self.revealViewController != nil) { menuButton.target = self.revealViewController; - [menuButton setAction:@selector(revealToggle:)]; + menuButton.action = @selector(revealToggle:); [self.view addGestureRecognizer: self.revealViewController.panGestureRecognizer]; } @@ -76,7 +76,7 @@ - (void)dealloc - (void)processVisibleDevices { devicesById = [NSMutableDictionary dictionary]; - for (RileyLinkBLEDevice *device in [[RileyLinkBLEManager sharedManager] rileyLinkList]) { + for (RileyLinkBLEDevice *device in [RileyLinkBLEManager sharedManager].rileyLinkList) { devicesById[device.peripheralId] = device; RileyLinkRecord *existingRecord = recordsById[device.peripheralId]; @@ -114,10 +114,10 @@ - (void)loadRecordsFromDB { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"firstSeenAt" ascending:YES]; - [fetchRequest setSortDescriptors:@[sortDescriptor1]]; + fetchRequest.sortDescriptors = @[sortDescriptor1]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"RileyLinkRecord" inManagedObjectContext:self.managedObjectContext]; - [fetchRequest setEntity:entity]; + fetchRequest.entity = entity; NSError *error; NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; for (RileyLinkRecord *record in fetchedObjects) { @@ -142,14 +142,14 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. - return [rileyLinkRecords count]; + return rileyLinkRecords.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { RileyLinkTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"rileylink" forIndexPath:indexPath]; RileyLinkRecord *record = rileyLinkRecords[indexPath.row]; cell.name = record.name; - cell.autoConnect = [record.autoConnect boolValue]; + cell.autoConnect = (record.autoConnect).boolValue; RileyLinkBLEDevice *device = devicesById[record.peripheralId]; if (device) { @@ -200,8 +200,8 @@ - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *) // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - RileyLinkDeviceViewController *controller = [segue destinationViewController]; - NSIndexPath *ip = [self.tableView indexPathForSelectedRow]; + RileyLinkDeviceViewController *controller = segue.destinationViewController; + NSIndexPath *ip = (self.tableView).indexPathForSelectedRow; RileyLinkRecord *record = rileyLinkRecords[ip.row]; controller.rlRecord = record; controller.rlDevice = devicesById[record.peripheralId]; diff --git a/RileyLink/RileyLinkTableViewCell.m b/RileyLink/RileyLinkTableViewCell.m index c214e6cd8..07af5e106 100644 --- a/RileyLink/RileyLinkTableViewCell.m +++ b/RileyLink/RileyLinkTableViewCell.m @@ -26,7 +26,7 @@ - (void)setName:(NSString *)name { - (void)setRSSI:(NSNumber *)RSSI { _RSSI = RSSI; - rssiLabel.text = [RSSI stringValue]; + rssiLabel.text = RSSI.stringValue; } - (void)setAutoConnect:(BOOL)autoConnect { diff --git a/RileyLink/SWRevealViewController.h b/RileyLink/SWRevealViewController.h index 345dfaa00..1ad3fc02a 100755 --- a/RileyLink/SWRevealViewController.h +++ b/RileyLink/SWRevealViewController.h @@ -187,7 +187,7 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType) /* Basic API */ // Object instance init and rear view setting -- (id)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController; +- (instancetype)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController NS_DESIGNATED_INITIALIZER; // Rear view controller, can be nil if not used @property (nonatomic) UIViewController *rearViewController; @@ -227,13 +227,13 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType) // By default, the panGestureRecognizer is added to the view containing the front controller view. To keep this default behavior // you still need to call this method, just don't add it to any of your views. The default setup allows you to dissable // user interactions on your controller views without affecting the recognizer. -- (UIPanGestureRecognizer*)panGestureRecognizer; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) UIPanGestureRecognizer *panGestureRecognizer; // The following method will provide a tapGestureRecognizer suitable to be added to any view on the frontController // for concealing the rear views. By default no tap recognizer is created or added to any view, however if you call this method after // the controller's view has been loaded the recognizer is added to the reveal controller's front container view. // Thus, you can disable user interactions on your frontViewController view without affecting the tap recognizer. -- (UITapGestureRecognizer*)tapGestureRecognizer; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) UITapGestureRecognizer *tapGestureRecognizer; /* The following properties are provided for further customization, they are set to default values on initialization, you do not generally have to set them */ @@ -318,14 +318,14 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType) #pragma mark - SWRevealViewControllerDelegate Protocol -typedef enum +typedef NS_ENUM(unsigned int, SWRevealControllerOperation) { SWRevealControllerOperationNone, SWRevealControllerOperationReplaceRearController, SWRevealControllerOperationReplaceFrontController, SWRevealControllerOperationReplaceRightController, -} SWRevealControllerOperation; +}; @protocol SWRevealViewControllerDelegate @@ -390,7 +390,7 @@ typedef enum // A category of UIViewController to let childViewControllers easily access their parent SWRevealViewController @interface UIViewController(SWRevealViewController) -- (SWRevealViewController*)revealViewController; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) SWRevealViewController *revealViewController; @end diff --git a/RileyLink/SWRevealViewController.m b/RileyLink/SWRevealViewController.m index aff2a163b..756b162ab 100755 --- a/RileyLink/SWRevealViewController.m +++ b/RileyLink/SWRevealViewController.m @@ -37,8 +37,8 @@ static CGFloat statusBarAdjustment( UIView* view ) { CGFloat adjustment = 0.0f; UIApplication *app = [UIApplication sharedApplication]; - CGRect viewFrame = [view convertRect:view.bounds toView:[app keyWindow]]; - CGRect statusBarFrame = [app statusBarFrame]; + CGRect viewFrame = [view convertRect:view.bounds toView:app.keyWindow]; + CGRect statusBarFrame = app.statusBarFrame; if ( CGRectIntersectsRect(viewFrame, statusBarFrame) ) adjustment = fminf(statusBarFrame.size.width, statusBarFrame.size.height); @@ -82,7 +82,7 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1 } -- (id)initWithFrame:(CGRect)frame controller:(SWRevealViewController*)controller +- (instancetype)initWithFrame:(CGRect)frame controller:(SWRevealViewController*)controller { self = [super initWithFrame:frame]; if ( self ) @@ -103,7 +103,7 @@ - (id)initWithFrame:(CGRect)frame controller:(SWRevealViewController*)controller - (void)reloadShadow { CALayer *frontViewLayer = _frontView.layer; - frontViewLayer.shadowColor = [_c.frontViewShadowColor CGColor]; + frontViewLayer.shadowColor = (_c.frontViewShadowColor).CGColor; frontViewLayer.shadowOpacity = _c.frontViewShadowOpacity; frontViewLayer.shadowOffset = _c.frontViewShadowOffset; frontViewLayer.shadowRadius = _c.frontViewShadowRadius; @@ -374,7 +374,7 @@ @implementation SWContextTransitionObject } -- (id)initWithRevealController:(SWRevealViewController*)revealVC containerView:(UIView*)view fromVC:(UIViewController*)fromVC +- (instancetype)initWithRevealController:(SWRevealViewController*)revealVC containerView:(UIView*)view fromVC:(UIViewController*)fromVC toVC:(UIViewController*)toVC completion:(void (^)(void))completion { self = [super init]; @@ -493,7 +493,7 @@ @implementation SWDefaultAnimationController } -- (id)initWithDuration:(NSTimeInterval)duration +- (instancetype)initWithDuration:(NSTimeInterval)duration { self = [super init]; if ( self ) @@ -609,7 +609,7 @@ @implementation SWRevealViewController #pragma mark - Init -- (id)initWithCoder:(NSCoder *)aDecoder +- (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if ( self ) @@ -620,13 +620,13 @@ - (id)initWithCoder:(NSCoder *)aDecoder } -- (id)init +- (instancetype)init { return [self initWithRearViewController:nil frontViewController:nil]; } -- (id)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController; +- (instancetype)initWithRearViewController:(UIViewController *)rearViewController frontViewController:(UIViewController *)frontViewController; { self = [super init]; if ( self ) @@ -708,16 +708,16 @@ - (void)loadView // On iOS7 the applicationFrame does not return the whole screen. This is possibly a bug. // As a workaround we use the screen bounds, this still works on iOS6, any zero based frame would work anyway! - CGRect frame = [[UIScreen mainScreen] bounds]; + CGRect frame = [UIScreen mainScreen].bounds; // create a custom content view for the controller _contentView = [[SWRevealView alloc] initWithFrame:frame controller:self]; // set the content view to resize along with its superview - [_contentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight]; + _contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; // set the content view to clip its bounds if requested - [_contentView setClipsToBounds:_clipsViewsToBounds]; + _contentView.clipsToBounds = _clipsViewsToBounds; // set our contentView to the controllers view self.view = _contentView; @@ -928,7 +928,7 @@ - (UITapGestureRecognizer*)tapGestureRecognizer - (void)setClipsViewsToBounds:(BOOL)clipsViewsToBounds { _clipsViewsToBounds = clipsViewsToBounds; - [_contentView setClipsToBounds:clipsViewsToBounds]; + _contentView.clipsToBounds = clipsViewsToBounds; } @@ -961,7 +961,7 @@ - (void)_restoreUserInteraction { // we use the stored userInteraction state just in case a developer decided // to have our view interaction disabled beforehand - [_contentView setUserInteractionEnabled:_userInteractionStore]; + _contentView.userInteractionEnabled = _userInteractionStore; [_contentView setDisableLayout:NO]; } @@ -1087,7 +1087,7 @@ - (void)_dequeue if ( _animationQueue.count > 0 ) { - void (^block)(void) = [_animationQueue lastObject]; + void (^block)(void) = _animationQueue.lastObject; block(); } } @@ -1719,7 +1719,7 @@ + (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)ide if (sb) { vc = (SWRevealViewController*)[sb instantiateViewControllerWithIdentifier:@"SWRevealViewController"]; - vc.restorationIdentifier = [identifierComponents lastObject]; + vc.restorationIdentifier = identifierComponents.lastObject; vc.restorationClass = [SWRevealViewController class]; } return vc; @@ -1791,11 +1791,11 @@ - (void)decodeRestorableStateWithCoder:(NSCoder *)coder _clipsViewsToBounds = [coder decodeBoolForKey:@"_clipsViewsToBounds"]; _extendsPointInsideHit = [coder decodeBoolForKey:@"_extendsPointInsideHit"]; - [self setRearViewController:[coder decodeObjectForKey:@"_rearViewController"]]; - [self setFrontViewController:[coder decodeObjectForKey:@"_frontViewController"]]; - [self setRightViewController:[coder decodeObjectForKey:@"_rightViewController"]]; + self.rearViewController = [coder decodeObjectForKey:@"_rearViewController"]; + self.frontViewController = [coder decodeObjectForKey:@"_frontViewController"]; + self.rightViewController = [coder decodeObjectForKey:@"_rightViewController"]; - [self setFrontViewPosition:[coder decodeIntForKey: @"_frontViewPosition"]]; + self.frontViewPosition = [coder decodeIntForKey: @"_frontViewPosition"]; [super decodeRestorableStateWithCoder:coder]; } @@ -1818,7 +1818,7 @@ - (SWRevealViewController*)revealViewController { UIViewController *parent = self; Class revealClass = [SWRevealViewController class]; - while ( nil != (parent = [parent parentViewController]) && ![parent isKindOfClass:revealClass] ) {} + while ( nil != (parent = parent.parentViewController) && ![parent isKindOfClass:revealClass] ) {} return (id)parent; } diff --git a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h index fbd8619ee..c7ab484ef 100644 --- a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h +++ b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h @@ -10,6 +10,6 @@ #import "UIScrollView+TPKeyboardAvoidingAdditions.h" @interface TPKeyboardAvoidingCollectionView : UICollectionView -- (BOOL)focusNextTextField; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL focusNextTextField; - (void)scrollToActiveTextField; @end diff --git a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m index 253b02255..01ef95688 100644 --- a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m +++ b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m @@ -22,13 +22,13 @@ - (void)setup { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; } --(id)initWithFrame:(CGRect)frame { +-(instancetype)initWithFrame:(CGRect)frame { if ( !(self = [super initWithFrame:frame]) ) return nil; [self setup]; return self; } -- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout { +- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout { if ( !(self = [super initWithFrame:frame collectionViewLayout:layout]) ) return nil; [self setup]; return self; @@ -46,7 +46,7 @@ -(void)dealloc { } -(void)setFrame:(CGRect)frame { - [super setFrame:frame]; + super.frame = frame; [self TPKeyboardAvoiding_updateContentInset]; } @@ -56,7 +56,7 @@ -(void)setContentSize:(CGSize)contentSize { // cause weird infinte scrolling and locking bug return; } - [super setContentSize:contentSize]; + super.contentSize = contentSize; [self TPKeyboardAvoiding_updateContentInset]; } diff --git a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h index 6947992cb..2a8e73f18 100755 --- a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h +++ b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h @@ -11,6 +11,6 @@ @interface TPKeyboardAvoidingScrollView : UIScrollView - (void)contentSizeToFit; -- (BOOL)focusNextTextField; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL focusNextTextField; - (void)scrollToActiveTextField; @end diff --git a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m index 81f753ac3..3391f532a 100644 --- a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m +++ b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m @@ -22,7 +22,7 @@ - (void)setup { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; } --(id)initWithFrame:(CGRect)frame { +-(instancetype)initWithFrame:(CGRect)frame { if ( !(self = [super initWithFrame:frame]) ) return nil; [self setup]; return self; @@ -40,12 +40,12 @@ -(void)dealloc { } -(void)setFrame:(CGRect)frame { - [super setFrame:frame]; + super.frame = frame; [self TPKeyboardAvoiding_updateContentInset]; } -(void)setContentSize:(CGSize)contentSize { - [super setContentSize:contentSize]; + super.contentSize = contentSize; [self TPKeyboardAvoiding_updateFromContentSizeChange]; } diff --git a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h index 7e05a0e1c..e63c8298d 100644 --- a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h +++ b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h @@ -10,6 +10,6 @@ #import "UIScrollView+TPKeyboardAvoidingAdditions.h" @interface TPKeyboardAvoidingTableView : UITableView -- (BOOL)focusNextTextField; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL focusNextTextField; - (void)scrollToActiveTextField; @end diff --git a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m index cc652de04..90c0df52f 100644 --- a/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m +++ b/RileyLink/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m @@ -24,13 +24,13 @@ - (void)setup { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; } --(id)initWithFrame:(CGRect)frame { +-(instancetype)initWithFrame:(CGRect)frame { if ( !(self = [super initWithFrame:frame]) ) return nil; [self setup]; return self; } --(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle { +-(instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle { if ( !(self = [super initWithFrame:frame style:withStyle]) ) return nil; [self setup]; return self; @@ -59,14 +59,14 @@ -(BOOL)hasAutomaticKeyboardAvoidingBehaviour { } -(void)setFrame:(CGRect)frame { - [super setFrame:frame]; + super.frame = frame; if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return; [self TPKeyboardAvoiding_updateContentInset]; } -(void)setContentSize:(CGSize)contentSize { if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) { - [super setContentSize:contentSize]; + super.contentSize = contentSize; return; } if (CGSizeEqualToSize(contentSize, self.contentSize)) { @@ -74,7 +74,7 @@ -(void)setContentSize:(CGSize)contentSize { // this cause table view to scroll to top on contentInset changes return; } - [super setContentSize:contentSize]; + super.contentSize = contentSize; [self TPKeyboardAvoiding_updateContentInset]; } diff --git a/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h b/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h index 80b9b1090..2e6f87b42 100644 --- a/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h +++ b/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h @@ -9,7 +9,7 @@ #import @interface UIScrollView (TPKeyboardAvoidingAdditions) -- (BOOL)TPKeyboardAvoiding_focusNextTextField; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL TPKeyboardAvoiding_focusNextTextField; - (void)TPKeyboardAvoiding_scrollToActiveTextField; - (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification; @@ -18,5 +18,5 @@ - (void)TPKeyboardAvoiding_updateFromContentSizeChange; - (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView*)view; - (UIView*)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView*)view; --(CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames; +@property (NS_NONATOMIC_IOSONLY, readonly) CGSize TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames; @end diff --git a/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m b/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m index df3b329c9..e3cfadb76 100644 --- a/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m +++ b/RileyLink/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m @@ -43,7 +43,7 @@ - (TPKeyboardAvoidingState*)keyboardAvoidingState { } - (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification { - CGRect keyboardRect = [self convertRect:[[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; + CGRect keyboardRect = [self convertRect:[notification.userInfo[_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; if (CGRectIsEmpty(keyboardRect)) { return; } @@ -79,8 +79,8 @@ - (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification { // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; - [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; + [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue]]; + [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]]; self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; @@ -97,7 +97,7 @@ - (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification { } - (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification { - CGRect keyboardRect = [self convertRect:[[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; + CGRect keyboardRect = [self convertRect:[notification.userInfo[_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; if (CGRectIsEmpty(keyboardRect)) { return; } @@ -113,8 +113,8 @@ - (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification { // Restore dimensions to prior size [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; - [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; + [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue]]; + [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]]; if ( [self isKindOfClass:[TPKeyboardAvoidingScrollView class]] ) { self.contentSize = state.priorContentSize; @@ -316,8 +316,8 @@ -(CGFloat)TPKeyboardAvoiding_idealOffsetForView:(UIView *)view withViewingAreaHe - (void)TPKeyboardAvoiding_initializeView:(UIView*)view { if ( [view isKindOfClass:[UITextField class]] && ((UITextField*)view).returnKeyType == UIReturnKeyDefault - && (![(UITextField*)view delegate] || [(UITextField*)view delegate] == (id)self) ) { - [(UITextField*)view setDelegate:(id)self]; + && (!((UITextField*)view).delegate || ((UITextField*)view).delegate == (id)self) ) { + ((UITextField*)view).delegate = (id)self; UIView *otherView = [self TPKeyboardAvoiding_findNextInputViewAfterView:view beneathView:self]; if ( otherView ) { diff --git a/sync_version.rb b/sync_version.rb index c21d39002..16256baf4 100755 --- a/sync_version.rb +++ b/sync_version.rb @@ -4,11 +4,11 @@ canonical_version = `defaults read #{plist_path} CFBundleShortVersionString`.chomp -bundle_version = `defaults read #{plist_path} CFBundleVersion`.chomp -if bundle_version != canonical_version - puts "Updating CFBundleVersion to #{canonical_version}" - `defaults write #{plist_path} CFBundleVersion -string "#{canonical_version}"` -end +#bundle_version = `defaults read #{plist_path} CFBundleVersion`.chomp +#if bundle_version != canonical_version +# puts "Updating CFBundleVersion to #{canonical_version}" +# `defaults write #{plist_path} CFBundleVersion -string "#{canonical_version}"` +#end podspec_text = File.open("RileyLink.podspec",:encoding => "UTF-8").read From 28cefb572bde89c911c9f5eb181ab60c9b2c4bde Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 27 Feb 2016 17:52:19 -0600 Subject: [PATCH 002/116] Brought over MinimedKit from @loudnate's naterade-ios project. --- MinimedKit/AlertType.swift | 23 + MinimedKit/Extensions/Int.swift | 24 ++ MinimedKit/Extensions/NSData.swift | 112 +++++ MinimedKit/Extensions/NSDateComponents.swift | 25 ++ MinimedKit/Info.plist | 26 ++ MinimedKit/MessageBody.swift | 36 ++ MinimedKit/MessageType.swift | 39 ++ MinimedKit/Messages/CarelinkMessageBody.swift | 53 +++ .../Messages/MySentryAckMessageBody.swift | 48 +++ .../MySentryAlertClearedMessageBody.swift | 48 +++ .../Messages/MySentryAlertMessageBody.swift | 59 +++ .../MySentryPumpStatusMessageBody.swift | 242 +++++++++++ .../Messages/PowerOnCarelinkMessageBody.swift | 24 ++ .../ReadSettingsCarelinkMessageBody.swift | 83 ++++ MinimedKit/Messages/UnknownMessageBody.swift | 28 ++ MinimedKit/MinimedKit.h | 19 + MinimedKit/PacketType.swift | 14 + MinimedKit/PumpMessage.swift | 54 +++ MinimedKitTests/Info.plist | 24 ++ MinimedKitTests/MinimedKitTests.swift | 23 + .../MySentryPumpStatusMessageBodyTests.swift | 219 ++++++++++ MinimedKitTests/NSDataTests.swift | 52 +++ ...ReadSettingsCarelinkMessageBodyTests.swift | 42 ++ RileyLink.xcodeproj/project.pbxproj | 401 ++++++++++++++++++ RileyLink/HistoryPage.m | 6 + RileyLink/LaunchScreen.xib | 6 +- RileyLink/MinimedPacket.m | 2 + .../PumpHistoryEvents/PumpHistoryEventBase.m | 6 + 28 files changed, 1735 insertions(+), 3 deletions(-) create mode 100644 MinimedKit/AlertType.swift create mode 100644 MinimedKit/Extensions/Int.swift create mode 100644 MinimedKit/Extensions/NSData.swift create mode 100644 MinimedKit/Extensions/NSDateComponents.swift create mode 100644 MinimedKit/Info.plist create mode 100644 MinimedKit/MessageBody.swift create mode 100644 MinimedKit/MessageType.swift create mode 100644 MinimedKit/Messages/CarelinkMessageBody.swift create mode 100644 MinimedKit/Messages/MySentryAckMessageBody.swift create mode 100644 MinimedKit/Messages/MySentryAlertClearedMessageBody.swift create mode 100644 MinimedKit/Messages/MySentryAlertMessageBody.swift create mode 100644 MinimedKit/Messages/MySentryPumpStatusMessageBody.swift create mode 100644 MinimedKit/Messages/PowerOnCarelinkMessageBody.swift create mode 100644 MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift create mode 100644 MinimedKit/Messages/UnknownMessageBody.swift create mode 100644 MinimedKit/MinimedKit.h create mode 100644 MinimedKit/PacketType.swift create mode 100644 MinimedKit/PumpMessage.swift create mode 100644 MinimedKitTests/Info.plist create mode 100644 MinimedKitTests/MinimedKitTests.swift create mode 100644 MinimedKitTests/MySentryPumpStatusMessageBodyTests.swift create mode 100644 MinimedKitTests/NSDataTests.swift create mode 100644 MinimedKitTests/ReadSettingsCarelinkMessageBodyTests.swift diff --git a/MinimedKit/AlertType.swift b/MinimedKit/AlertType.swift new file mode 100644 index 000000000..0142869ae --- /dev/null +++ b/MinimedKit/AlertType.swift @@ -0,0 +1,23 @@ +// +// AlertType.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/13/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +public enum AlertType: UInt8 { + case NoDelivery = 0x04 + case MaxHourlyBolus = 0x33 + case LowReservoir = 0x52 + case HighGlucose = 0x65 + case LowGlucose = 0x66 + case MeterBGNow = 0x68 + case MeterBGSoon = 0x69 + case CalibrationError = 0x6a + case SensorEnd = 0x6b + case WeakSignal = 0x70 + case LostSensor = 0x71 + case HighPredicted = 0x72 + case LowPredicted = 0x73 +} \ No newline at end of file diff --git a/MinimedKit/Extensions/Int.swift b/MinimedKit/Extensions/Int.swift new file mode 100644 index 000000000..3d1cdbd86 --- /dev/null +++ b/MinimedKit/Extensions/Int.swift @@ -0,0 +1,24 @@ +// +// Int.swift +// Naterade +// +// Created by Nathan Racklyeft on 12/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +extension Int { + init(bigEndianBytes bytes: [UInt8]) { + assert(bytes.count <= 4) + var result: UInt = 0 + + for idx in 0..<(bytes.count) { + let shiftAmount = UInt((bytes.count) - idx - 1) * 8 + result += UInt(bytes[idx]) << shiftAmount + } + + self.init(result) + } +} diff --git a/MinimedKit/Extensions/NSData.swift b/MinimedKit/Extensions/NSData.swift new file mode 100644 index 000000000..ac3075f3a --- /dev/null +++ b/MinimedKit/Extensions/NSData.swift @@ -0,0 +1,112 @@ +// +// NSData.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/2/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public extension NSData { + @nonobjc subscript(index: Int) -> Int8 { + let bytes: [Int8] = self[index...index] + + return bytes[0] + } + + @nonobjc subscript(index: Int) -> UInt8 { + let bytes: [UInt8] = self[index...index] + + return bytes[0] + } + + @nonobjc subscript(range: Range) -> UInt16 { + return self[range][0] + } + + @nonobjc subscript(range: Range) -> UInt32 { + return self[range][0] + } + + subscript(range: Range) -> [Int8] { + var dataArray = [Int8](count: range.count, repeatedValue: 0) + self.getBytes(&dataArray, range: NSRange(range)) + + return dataArray + } + + subscript(range: Range) -> [UInt8] { + var dataArray = [UInt8](count: range.count, repeatedValue: 0) + self.getBytes(&dataArray, range: NSRange(range)) + + return dataArray + } + + subscript(range: Range) -> [UInt16] { + var dataArray = [UInt16](count: range.count / 2, repeatedValue: 0) + self.getBytes(&dataArray, range: NSRange(range)) + + return dataArray + } + + subscript(range: Range) -> [UInt32] { + var dataArray = [UInt32](count: range.count / 4, repeatedValue: 0) + self.getBytes(&dataArray, range: NSRange(range)) + + return dataArray + } + + subscript(range: Range) -> NSData { + return subdataWithRange(NSRange(range)) + } + + public convenience init?(hexadecimalString: String) { + if let + chars = hexadecimalString.cStringUsingEncoding(NSUTF8StringEncoding), + mutableData = NSMutableData(capacity: chars.count / 2) + { + for i in 0..(start: UnsafePointer(bytes), count: length) + + let string = NSMutableString(capacity: length * 2) + + for byte in bytesCollection { + string.appendFormat("%02x", byte) + } + + return string as String + } +} diff --git a/MinimedKit/Extensions/NSDateComponents.swift b/MinimedKit/Extensions/NSDateComponents.swift new file mode 100644 index 000000000..9c88a6ea1 --- /dev/null +++ b/MinimedKit/Extensions/NSDateComponents.swift @@ -0,0 +1,25 @@ +// +// NSDateComponents.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/13/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +extension NSDateComponents { + convenience init(mySentryBytes: [UInt8]) { + self.init() + + hour = Int(mySentryBytes[0]) + minute = Int(mySentryBytes[1]) + second = Int(mySentryBytes[2]) + year = Int(mySentryBytes[3]) + 2000 + month = Int(mySentryBytes[4]) + day = Int(mySentryBytes[5]) + + calendar = NSCalendar.currentCalendar() + } +} \ No newline at end of file diff --git a/MinimedKit/Info.plist b/MinimedKit/Info.plist new file mode 100644 index 000000000..d3de8eefb --- /dev/null +++ b/MinimedKit/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/MinimedKit/MessageBody.swift b/MinimedKit/MessageBody.swift new file mode 100644 index 000000000..da6a6d5d8 --- /dev/null +++ b/MinimedKit/MessageBody.swift @@ -0,0 +1,36 @@ +// +// MessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/4/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public protocol MessageBody { + static var length: Int { + get + } + + init?(rxData: NSData) + + var txData: NSData { + get + } +} + + +extension MessageBody { + static var emptyBuffer: [UInt8] { + return [UInt8](count: self.length, repeatedValue: 0) + } +} + + +public protocol DictionaryRepresentable { + var dictionaryRepresentation: [String: AnyObject] { + get + } +} \ No newline at end of file diff --git a/MinimedKit/MessageType.swift b/MinimedKit/MessageType.swift new file mode 100644 index 000000000..d613ac434 --- /dev/null +++ b/MinimedKit/MessageType.swift @@ -0,0 +1,39 @@ +// +// MessageType.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/2/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +public enum MessageType: UInt8 { + case Alert = 0x01 + case AlertCleared = 0x02 + case DeviceTest = 0x03 + case PumpStatus = 0x04 + case PumpStatusAck = 0x06 + case PumpBackfill = 0x08 + case FindDevice = 0x09 + case DeviceLink = 0x0A + case PowerOn = 0x5d + case GetBattery = 0x72 + case GetPumpModel = 0x8d + case ReadSettings = 0xc0 + + var bodyType: MessageBody.Type { + switch self { + case .Alert: + return MySentryAlertMessageBody.self + case .AlertCleared: + return MySentryAlertClearedMessageBody.self + case .PumpStatus: + return MySentryPumpStatusMessageBody.self + case .PumpStatusAck: + return MySentryAckMessageBody.self + case .ReadSettings: + return ReadSettingsCarelinkMessageBody.self + default: + return UnknownMessageBody.self + } + } +} diff --git a/MinimedKit/Messages/CarelinkMessageBody.swift b/MinimedKit/Messages/CarelinkMessageBody.swift new file mode 100644 index 000000000..f123f0aec --- /dev/null +++ b/MinimedKit/Messages/CarelinkMessageBody.swift @@ -0,0 +1,53 @@ +// +// CarelinkMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 12/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public class CarelinkLongMessageBody: MessageBody { + public static var length: Int = 65 + + let rxData: NSData + + public required init?(rxData: NSData) { + let data: NSMutableData = rxData.mutableCopy() as! NSMutableData + + if data.length < self.dynamicType.length { + data.increaseLengthBy(self.dynamicType.length - data.length) + } + + self.rxData = data + } + + public var txData: NSData { + return rxData + } +} + + +public class CarelinkShortMessageBody: MessageBody { + public static var length: Int = 1 + + let data: NSData + + public convenience init() { + self.init(rxData: NSData(hexadecimalString: "00")!)! + } + + public required init?(rxData: NSData) { + self.data = rxData + + if rxData.length != self.dynamicType.length { + return nil + } + } + + public var txData: NSData { + return data + } +} \ No newline at end of file diff --git a/MinimedKit/Messages/MySentryAckMessageBody.swift b/MinimedKit/Messages/MySentryAckMessageBody.swift new file mode 100644 index 000000000..16a17047b --- /dev/null +++ b/MinimedKit/Messages/MySentryAckMessageBody.swift @@ -0,0 +1,48 @@ +// +// MySentryAckMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/4/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +/// Describes an ACK message sent by a MySentry device in response to pump status messages. +/// a2 350535 06 59 000695 00 04000000 e2 +public struct MySentryAckMessageBody: MessageBody { + public static let length = 9 + static var MessageCounter: UInt8 = 0 + + let mySentryID: [UInt8] + let responseMessageTypes: [MessageType] + + public init(mySentryID: [UInt8], responseMessageTypes: [MessageType]) { + assert(mySentryID.count == 3) + assert(responseMessageTypes.count <= 4) + + self.mySentryID = mySentryID + self.responseMessageTypes = responseMessageTypes + } + + public init?(rxData: NSData) { + if rxData.length == self.dynamicType.length { + mySentryID = rxData[1...3] + responseMessageTypes = rxData[5...8].flatMap({ MessageType(rawValue: $0) }) + } else { + return nil + } + } + + public var txData: NSData { + var buffer = self.dynamicType.emptyBuffer + + buffer[0] = self.dynamicType.MessageCounter++ + buffer.replaceRange(1...3, with: mySentryID) + + buffer.replaceRange(5..<5 + responseMessageTypes.count, with: responseMessageTypes.map({ $0.rawValue })) + + return NSData(bytes: &buffer, length: buffer.count) + } +} diff --git a/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift b/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift new file mode 100644 index 000000000..0c72a2c68 --- /dev/null +++ b/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift @@ -0,0 +1,48 @@ +// +// MySentryAlertClearedMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/6/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +/** +Describes message sent immediately from the pump to any paired MySentry devices after a user clears an alert + +See: [MinimedRF Class](https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/messages/alert_cleared.rb) + +``` +a2 594040 02 80 52 14 +``` +*/ +public struct MySentryAlertClearedMessageBody: MessageBody, DictionaryRepresentable { + public static let length = 2 + + public let alertType: AlertType? + + private let rxData: NSData + + public init?(rxData: NSData) { + if rxData.length == self.dynamicType.length { + self.rxData = rxData + + alertType = AlertType(rawValue: rxData[1]) + } else { + return nil + } + } + + public var txData: NSData { + return rxData + } + + public var dictionaryRepresentation: [String: AnyObject] { + return [ + "alertType": alertType != nil ? String(alertType!) : rxData.subdataWithRange(NSRange(1...1)).hexadecimalString, + "cleared": true + ] + } +} \ No newline at end of file diff --git a/MinimedKit/Messages/MySentryAlertMessageBody.swift b/MinimedKit/Messages/MySentryAlertMessageBody.swift new file mode 100644 index 000000000..66308545c --- /dev/null +++ b/MinimedKit/Messages/MySentryAlertMessageBody.swift @@ -0,0 +1,59 @@ +// +// MySentryAlertMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/6/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +/** +Describes an alert message sent immediately from the pump to any paired MySentry devices + +See: [MinimedRF Class](https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/messages/alert.rb) + +``` +a2 594040 01 7c 65 0727070f0906 0175 4c +``` +*/ +public struct MySentryAlertMessageBody: MessageBody, DictionaryRepresentable { + public static let length = 10 + + public let alertType: AlertType? + public let alertDate: NSDate + + private let rxData: NSData + + public init?(rxData: NSData) { + if rxData.length == self.dynamicType.length, let + alertDate = NSDateComponents(mySentryBytes: rxData[2...7]).date + { + self.rxData = rxData + + alertType = AlertType(rawValue: rxData[1]) + self.alertDate = alertDate + } else { + return nil + } + } + + public var txData: NSData { + return rxData + } + + public var dictionaryRepresentation: [String: AnyObject] { + let dateFormatter = NSDateFormatter() + + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") + + return [ + "alertDate": dateFormatter.stringFromDate(alertDate), + "alertType": alertType != nil ? String(alertType!) : rxData.subdataWithRange(NSRange(1...1)).hexadecimalString, + "byte89": rxData.subdataWithRange(NSRange(8...9)).hexadecimalString + ] + + } +} \ No newline at end of file diff --git a/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift b/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift new file mode 100644 index 000000000..93921d3dd --- /dev/null +++ b/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift @@ -0,0 +1,242 @@ +// +// MySentryPumpStatusMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/5/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public enum GlucoseTrend { + case Flat + case Up + case UpUp + case Down + case DownDown + + init?(byte: UInt8) { + switch byte & 0b1110 { + case 0b0000: + self = .Flat + case 0b0010: + self = .Up + case 0b0100: + self = .UpUp + case 0b0110: + self = .Down + case 0b1000: + self = .DownDown + default: + return nil + } + } +} + + +public enum SensorReading { + case Off + case MeterBGNow + case WeakSignal + case CalError + case Warmup + case Ended + case HighBG // Above 400 mg/dL + case Lost + case Unknown + case Active(glucose: Int) + + init(glucose: Int) { + switch glucose { + case 0: + self = .Off + case 2: + self = .MeterBGNow + case 4: + self = .WeakSignal + case 6: + self = .CalError + case 8: + self = .Warmup + case 10: + self = .Ended + case 14: + self = .HighBG + case 20: + self = .Lost + case 0...20: + self = .Unknown + default: + self = .Active(glucose: glucose) + } + } +} + + +/** +Describes a status message sent periodically from the pump to any paired MySentry devices + +See: [MinimedRF Class](https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/messages/pump_status.rb) +``` +-- ------ -- 00 01 020304050607 08 09 10 11 1213 14 15 16 17 18 19 20 21 2223 24 25 26 27 282930313233 3435 -- + se tr pump date 01 bh ph resv bt st sr nxcal iob bl sens date 0000 +a2 594040 04 c9 51 092c1e0f0904 01 32 33 00 037a 02 02 05 b0 18 30 13 2b 00d1 00 00 00 70 092b000f0904 0000 33 +a2 594040 04 fb 51 1205000f0906 01 05 05 02 0000 04 00 00 00 ff 00 ff ff 0040 00 00 00 71 1205000f0906 0000 2b +a2 594040 04 ff 50 1219000f0906 01 00 00 00 0000 04 00 00 00 00 00 00 00 005e 00 00 00 72 000000000000 0000 8b +a2 594040 04 01 50 1223000f0906 01 00 00 00 0000 04 00 00 00 00 00 00 00 0059 00 00 00 72 000000000000 0000 9f +a2 594040 04 2f 51 1727070f0905 01 84 85 00 00cd 01 01 05 b0 3e 0a 0a 1a 009d 03 00 00 71 1726000f0905 0000 d0 +a2 594040 04 9c 51 0003310f0905 01 39 37 00 025b 01 01 06 8d 26 22 08 15 0034 00 00 00 70 0003000f0905 0000 67 +a2 594040 04 87 51 0f18150f0907 01 03 71 00 045e 04 02 07 2c 04 44 ff ff 005e 02 00 00 73 0f16000f0907 0000 35 +``` +*/ +public struct MySentryPumpStatusMessageBody: MessageBody, DictionaryRepresentable { + private static let reservoirSignificantDigit = 0.1 + private static let iobSigificantDigit = 0.025 + public static let length = 36 + + public let pumpDate: NSDate + public let batteryRemainingPercent: Int + public let iob: Double + public let reservoirRemainingUnits: Double + public let reservoirRemainingPercent: Int + public let reservoirRemainingMinutes: Int + + public let glucoseTrend: GlucoseTrend + public let glucoseDate: NSDate? + public let glucose: SensorReading + public let previousGlucose: SensorReading + public let sensorAgeHours: Int + public let sensorRemainingHours: Int + public let nextSensorCalibration: NSDate? + + private let rxData: NSData + + public init?(rxData: NSData) { + if rxData.length == self.dynamicType.length, + let + trend = GlucoseTrend(byte: rxData[1]), + pumpDate = NSDateComponents(mySentryBytes: rxData[2...7]).date + { + self.rxData = rxData + + self.glucoseTrend = trend + self.pumpDate = pumpDate + + reservoirRemainingUnits = Double(Int(bigEndianBytes: rxData[12...13])) * self.dynamicType.reservoirSignificantDigit + + let reservoirRemainingPercent: UInt8 = rxData[15] + self.reservoirRemainingPercent = Int(round(Double(reservoirRemainingPercent) / 4.0 * 100)) + + reservoirRemainingMinutes = Int(bigEndianBytes: [rxData[16], rxData[17]]) + + iob = Double(Int(bigEndianBytes: rxData[22...23])) * self.dynamicType.iobSigificantDigit + + let batteryRemainingPercent: UInt8 = rxData[14] + self.batteryRemainingPercent = Int(round(Double(batteryRemainingPercent) / 4.0 * 100)) + + let glucoseValue = Int(bigEndianBytes: [rxData[9], rxData[24] << 7]) >> 7 + let previousGlucoseValue = Int(bigEndianBytes: [rxData[10], rxData[24] << 6]) >> 7 + + glucose = SensorReading(glucose: glucoseValue) + previousGlucose = SensorReading(glucose: previousGlucoseValue) + + switch glucose { + case .Off: + glucoseDate = nil + default: + glucoseDate = NSDateComponents(mySentryBytes: rxData[28...33]).date + } + + let sensorAgeHours: UInt8 = rxData[18] + self.sensorAgeHours = Int(sensorAgeHours) + + let sensorRemainingHours: UInt8 = rxData[19] + self.sensorRemainingHours = Int(sensorRemainingHours) + + let matchingHour: UInt8 = rxData[20] + nextSensorCalibration = NSCalendar.currentCalendar().nextDateAfterDate(pumpDate, + matchingHour: Int(matchingHour), + minute: Int(13), + second: 0, + options: [.MatchNextTime] + ) + } else { + return nil + } + } + + public var dictionaryRepresentation: [String: AnyObject] { + let dateFormatter = NSDateFormatter() + + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") + + var dict: [String: AnyObject] = [ + "glucoseTrend": String(glucoseTrend), + "pumpDate": dateFormatter.stringFromDate(pumpDate), + "reservoirRemaining": reservoirRemainingUnits, + "reservoirRemainingPercent": reservoirRemainingPercent, + "reservoirRemainingMinutes": reservoirRemainingMinutes, + "iob": iob + ] + + switch glucose { + case .Active(glucose: let glucose): + dict["glucose"] = glucose + default: + break + } + + if let glucoseDate = glucoseDate { + dict["glucoseDate"] = dateFormatter.stringFromDate(glucoseDate) + } + dict["sensorStatus"] = String(glucose) + + switch previousGlucose { + case .Active(glucose: let glucose): + dict["lastGlucose"] = glucose + default: + break + } + dict["lastSensorStatus"] = String(previousGlucose) + + dict["sensorAgeHours"] = sensorAgeHours + dict["sensorRemainingHours"] = sensorRemainingHours + if let nextSensorCalibration = nextSensorCalibration { + dict["nextSensorCalibration"] = dateFormatter.stringFromDate(nextSensorCalibration) + } + + dict["batteryRemainingPercent"] = batteryRemainingPercent + + dict["byte1"] = rxData.subdataWithRange(NSRange(1...1)).hexadecimalString + // {50} + let byte1: UInt8 = rxData[1] + dict["byte1High"] = String(format: "%02x", byte1 & 0b11110000) + // {1} + dict["byte1Low"] = Int(byte1 & 0b00000001) + // Observed values: 00, 01, 02, 03 + // These seem to correspond with carb/bolus activity + dict["byte11"] = rxData.subdataWithRange(NSRange(11...11)).hexadecimalString + // Current alarms? + // 25: {00,52,65} 4:49 AM - 4:59 AM + // 26: 00 + dict["byte2526"] = rxData.subdataWithRange(NSRange(25...26)).hexadecimalString + // 27: {73} + dict["byte27"] = rxData.subdataWithRange(NSRange(27...27)).hexadecimalString + + return dict + } + + public var txData: NSData { + return rxData + } +} + +extension MySentryPumpStatusMessageBody: Equatable { +} + +public func ==(lhs: MySentryPumpStatusMessageBody, rhs: MySentryPumpStatusMessageBody) -> Bool { + return lhs.pumpDate == rhs.pumpDate && lhs.glucoseDate == rhs.glucoseDate +} + diff --git a/MinimedKit/Messages/PowerOnCarelinkMessageBody.swift b/MinimedKit/Messages/PowerOnCarelinkMessageBody.swift new file mode 100644 index 000000000..12749c3b1 --- /dev/null +++ b/MinimedKit/Messages/PowerOnCarelinkMessageBody.swift @@ -0,0 +1,24 @@ +// +// PowerOnCarelinkMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 12/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public class PowerOnCarelinkMessageBody: CarelinkLongMessageBody { + + public convenience init(duration: NSTimeInterval) { + + let sequence = 2 + let on = 1 + let durationMinutes: Int = Int(ceil(duration / 60.0)) + + let data = NSData(hexadecimalString: String("%02x%02x%02x", sequence, on, durationMinutes))! + + self.init(rxData: data)! + } +} \ No newline at end of file diff --git a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift new file mode 100644 index 000000000..b178ad9f3 --- /dev/null +++ b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift @@ -0,0 +1,83 @@ +// +// ReadSettingsCarelinkMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 12/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public enum BasalProfile { + + case Standard + case ProfileA + case ProfileB + + init(rawValue: UInt8) { + switch rawValue { + case 1: + self = .ProfileA + case 2: + self = .ProfileB + default: + self = .Standard + } + } +} + + +/** + Describes the response to the Read Settings command from the pump + + See: [Decocare Class](https://github.com/bewest/decoding-carelink/blob/master/decocare/commands.py#L1223) + ``` + -- ------ -- 00 01 02 03 04 05 06 07 0809 10 11 12 13141516171819 20 21 2223 24 25 26 27 282930313233 343536 -- + a7 594040 c0 19 00 01 00 01 01 00 96 008c 00 00 00 00000064010400 14 00 1901 01 01 00 00 000000000000 000000 00000000000000000000000000000000000000000000000000000000 e9 + ``` + */ +public class ReadSettingsCarelinkMessageBody: CarelinkLongMessageBody { + private static let maxBolusSignificantDigit = 0.1 + private static let maxBasalSignificantDigit = 0.025 + + public let maxBasal: Double + public let maxBolus: Double + + public let insulinActionCurveHours: Int + + public let selectedBasalProfile: BasalProfile + + public required init?(rxData: NSData) { + guard rxData.length == self.dynamicType.length else { + maxBolus = 0 + maxBasal = 0 + selectedBasalProfile = .Standard + insulinActionCurveHours = 0 + + super.init(rxData: rxData) + return nil + } + + let maxBolusTicks: UInt8 = rxData[7] + maxBolus = Double(maxBolusTicks) * self.dynamicType.maxBolusSignificantDigit + + let maxBasalTicks: Int = Int(bigEndianBytes: rxData[8...9]) + maxBasal = Double(maxBasalTicks) * self.dynamicType.maxBasalSignificantDigit + + let rawSelectedBasalProfile: UInt8 = rxData[12] + selectedBasalProfile = BasalProfile(rawValue: rawSelectedBasalProfile) + + let rawInsulinActionCurveHours: UInt8 = rxData[18] + insulinActionCurveHours = Int(rawInsulinActionCurveHours) + + super.init(rxData: rxData) + } +} + + +extension ReadSettingsCarelinkMessageBody: DictionaryRepresentable { + public var dictionaryRepresentation: [String: AnyObject] { + return [:] + } +} diff --git a/MinimedKit/Messages/UnknownMessageBody.swift b/MinimedKit/Messages/UnknownMessageBody.swift new file mode 100644 index 000000000..7f163011f --- /dev/null +++ b/MinimedKit/Messages/UnknownMessageBody.swift @@ -0,0 +1,28 @@ +// +// UnknownMessageBody.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/16/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public struct UnknownMessageBody: MessageBody, DictionaryRepresentable { + public static var length = 0 + + let rxData: NSData + + public init?(rxData: NSData) { + self.rxData = rxData + } + + public var txData: NSData { + return rxData + } + + public var dictionaryRepresentation: [String: AnyObject] { + return ["rawData": rxData] + } +} \ No newline at end of file diff --git a/MinimedKit/MinimedKit.h b/MinimedKit/MinimedKit.h new file mode 100644 index 000000000..f6faf0f4c --- /dev/null +++ b/MinimedKit/MinimedKit.h @@ -0,0 +1,19 @@ +// +// MinimedKit.h +// MinimedKit +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +#import + +//! Project version number for MinimedKit. +FOUNDATION_EXPORT double MinimedKitVersionNumber; + +//! Project version string for MinimedKit. +FOUNDATION_EXPORT const unsigned char MinimedKitVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/MinimedKit/PacketType.swift b/MinimedKit/PacketType.swift new file mode 100644 index 000000000..c00b27003 --- /dev/null +++ b/MinimedKit/PacketType.swift @@ -0,0 +1,14 @@ +// +// PacketType.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/2/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +public enum PacketType: UInt8 { + case MySentry = 0xA2 + case Meter = 0xA5 + case Carelink = 0xA7 + case Sensor = 0xA8 +} diff --git a/MinimedKit/PumpMessage.swift b/MinimedKit/PumpMessage.swift new file mode 100644 index 000000000..3d9e3d617 --- /dev/null +++ b/MinimedKit/PumpMessage.swift @@ -0,0 +1,54 @@ +// +// PumpMessage.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/2/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public struct PumpMessage { + public let packetType: PacketType + public let address: NSData + public let messageType: MessageType + public let messageBody: MessageBody + + public init(packetType: PacketType, address: String, messageType: MessageType, messageBody: MessageBody) { + self.packetType = packetType + self.address = NSData(hexadecimalString: address)! + self.messageType = messageType + self.messageBody = messageBody + } + + public init?(rxData: NSData) { + if rxData.length >= 7, let + packetType = PacketType(rawValue: rxData[0]), + messageType = MessageType(rawValue: rxData[4]), + messageBody = messageType.bodyType.init(rxData: rxData.subdataWithRange(NSRange(5.. + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/MinimedKitTests/MinimedKitTests.swift b/MinimedKitTests/MinimedKitTests.swift new file mode 100644 index 000000000..2719dedb5 --- /dev/null +++ b/MinimedKitTests/MinimedKitTests.swift @@ -0,0 +1,23 @@ +// +// MinimedKitTests.swift +// MinimedKitTests +// +// Created by Nathan Racklyeft on 12/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import XCTest + +class MinimedKitTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + +} diff --git a/MinimedKitTests/MySentryPumpStatusMessageBodyTests.swift b/MinimedKitTests/MySentryPumpStatusMessageBodyTests.swift new file mode 100644 index 000000000..a38cffbe5 --- /dev/null +++ b/MinimedKitTests/MySentryPumpStatusMessageBodyTests.swift @@ -0,0 +1,219 @@ +// +// MySentryPumpStatusMessageBodyTests.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/6/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import XCTest +@testable import MinimedKit + +class MySentryPumpStatusMessageBodyTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testValidPumpStatusMessage() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a2594040042f511727070f09050184850000cd010105b03e0a0a1a009d030000711726000f09050000d0")!) + + if let message = message { + XCTAssertTrue(message.messageBody is MySentryPumpStatusMessageBody) + } else { + XCTFail("\(message) is nil") + } + } + + func testGlucoseTrendFlat() { + XCTAssertEqual(GlucoseTrend.Flat, GlucoseTrend(byte: 0b00000000)) + XCTAssertEqual(GlucoseTrend.Flat, GlucoseTrend(byte: 0b11110001)) + XCTAssertEqual(GlucoseTrend.Flat, GlucoseTrend(byte: 0b11110001)) + XCTAssertEqual(GlucoseTrend.Flat, GlucoseTrend(byte: 0b000)) + XCTAssertEqual(GlucoseTrend.Flat, GlucoseTrend(byte: 0x51)) + } + + func testMidnightSensor() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a2594040049c510003310f090501393700025b0101068d262208150034000000700003000f0905000067")!)! + + let body = message.messageBody as! MySentryPumpStatusMessageBody + + switch body.glucose { + case .Active(glucose: let glucose): + XCTAssertEqual(114, glucose) + default: + XCTFail("\(body.glucose) is not .Active") + } + + switch body.previousGlucose { + case .Active(glucose: let glucose): + XCTAssertEqual(110, glucose) + default: + XCTFail("\(body.previousGlucose) is not .Active") + } + + let dateComponents = NSDateComponents() + dateComponents.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) + dateComponents.year = 2015 + dateComponents.month = 9 + dateComponents.day = 5 + dateComponents.hour = 0 + dateComponents.minute = 3 + dateComponents.second = 49 + + XCTAssertEqual(dateComponents.date, body.pumpDate) + + dateComponents.second = 0 + + XCTAssertEqual(dateComponents.date, body.glucoseDate) + + XCTAssertEqual(GlucoseTrend.Flat, body.glucoseTrend) + } + + func testActiveSensor() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a2594040042f511727070f09050184850000cd010105b03e0a0a1a009d030000711726000f09050000d0")!)! + + let body = message.messageBody as! MySentryPumpStatusMessageBody + + switch body.glucose { + case .Active(glucose: let glucose): + XCTAssertEqual(265, glucose) + default: + XCTFail("\(body.glucose) is not .Active") + } + + switch body.previousGlucose { + case .Active(glucose: let glucose): + XCTAssertEqual(267, glucose) + default: + XCTFail("\(body.previousGlucose) is not .Active") + } + + let dateComponents = NSDateComponents() + dateComponents.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) + dateComponents.year = 2015 + dateComponents.month = 9 + dateComponents.day = 5 + dateComponents.hour = 23 + dateComponents.minute = 39 + dateComponents.second = 7 + + XCTAssertEqual(dateComponents.date, body.pumpDate) + + dateComponents.minute = 38 + dateComponents.second = 0 + + XCTAssertEqual(dateComponents.date, body.glucoseDate) + + XCTAssertEqual(GlucoseTrend.Flat, body.glucoseTrend) + } + + func testSensorEndEmptyReservoir() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a259404004fb511205000f090601050502000004000000ff00ffff0040000000711205000f090600002b")!)! + + let body = message.messageBody as! MySentryPumpStatusMessageBody + + switch body.glucose { + case .Ended: + break + default: + XCTFail("\(body.glucose) is not .Ended") + } + + switch body.previousGlucose { + case .Ended: + break + default: + XCTFail("\(body.previousGlucose) is not .Ended") + } + + let dateComponents = NSDateComponents() + dateComponents.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) + dateComponents.year = 2015 + dateComponents.month = 9 + dateComponents.day = 6 + dateComponents.hour = 18 + dateComponents.minute = 5 + dateComponents.second = 0 + + XCTAssertEqual(dateComponents.date, body.pumpDate) + XCTAssertEqual(dateComponents.date, body.glucoseDate) + + XCTAssertEqual(GlucoseTrend.Flat, body.glucoseTrend) + } + + func testSensorOffEmptyReservoir() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a259404004ff501219000f09060100000000000400000000000000005e0000007200000000000000008b")!)! + + let body = message.messageBody as! MySentryPumpStatusMessageBody + + switch body.glucose { + case .Off: + break + default: + XCTFail("\(body.glucose) is not .Off") + } + + switch body.previousGlucose { + case .Off: + break + default: + XCTFail("\(body.previousGlucose) is not .Off") + } + + let dateComponents = NSDateComponents() + dateComponents.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) + dateComponents.year = 2015 + dateComponents.month = 9 + dateComponents.day = 6 + dateComponents.hour = 18 + dateComponents.minute = 25 + dateComponents.second = 0 + + XCTAssertEqual(dateComponents.date, body.pumpDate) + XCTAssertNil(body.glucoseDate) + + XCTAssertEqual(GlucoseTrend.Flat, body.glucoseTrend) + } + + func testSensorOffEmptyReservoirSuspended() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a25940400401501223000f0906010000000000040000000000000000590000007200000000000000009f")!)! + + let body = message.messageBody as! MySentryPumpStatusMessageBody + + switch body.glucose { + case .Off: + break + default: + XCTFail("\(body.glucose) is not .Off") + } + + switch body.previousGlucose { + case .Off: + break + default: + XCTFail("\(body.previousGlucose) is not .Off") + } + + let dateComponents = NSDateComponents() + dateComponents.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) + dateComponents.year = 2015 + dateComponents.month = 9 + dateComponents.day = 6 + dateComponents.hour = 18 + dateComponents.minute = 35 + dateComponents.second = 0 + + XCTAssertEqual(dateComponents.date, body.pumpDate) + XCTAssertNil(body.glucoseDate) + + XCTAssertEqual(GlucoseTrend.Flat, body.glucoseTrend) + } + +} diff --git a/MinimedKitTests/NSDataTests.swift b/MinimedKitTests/NSDataTests.swift new file mode 100644 index 000000000..a2ada5554 --- /dev/null +++ b/MinimedKitTests/NSDataTests.swift @@ -0,0 +1,52 @@ +// +// NSDataTests.swift +// Naterade +// +// Created by Nathan Racklyeft on 9/5/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import XCTest +@testable import MinimedKit + +class NSDataTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testInitWithHexadecimalStringEmpty() { + let data = NSData(hexadecimalString: "") + XCTAssertEqual(0, data!.length) + } + + func testInitWithHexadecimalStringOdd() { + let data = NSData(hexadecimalString: "a") + XCTAssertNil(data) + } + + func testInitWithHexadecimalStringZeros() { + let data = NSData(hexadecimalString: "00") + XCTAssertEqual(1, data!.length) + + var bytes = [UInt8](count: 1, repeatedValue: 1) + data?.getBytes(&bytes, length: 1) + XCTAssertEqual(0, bytes[0]) + } + + func testInitWithHexadecimalStringShortData() { + let data = NSData(hexadecimalString: "a2594040") + + XCTAssertEqual(4, data!.length) + + var bytes = [UInt8](count: 4, repeatedValue: 0) + data?.getBytes(&bytes, length: 4) + XCTAssertEqual([0xa2, 0x59, 0x40, 0x40], bytes) + } +} diff --git a/MinimedKitTests/ReadSettingsCarelinkMessageBodyTests.swift b/MinimedKitTests/ReadSettingsCarelinkMessageBodyTests.swift new file mode 100644 index 000000000..37cd4a6c7 --- /dev/null +++ b/MinimedKitTests/ReadSettingsCarelinkMessageBodyTests.swift @@ -0,0 +1,42 @@ +// +// ReadSettingsCarelinkMessageBodyTests.swift +// Naterade +// +// Created by Nathan Racklyeft on 12/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import XCTest +@testable import MinimedKit + +class ReadSettingsCarelinkMessageBodyTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testValidSettings() { + let message = PumpMessage(rxData: NSData(hexadecimalString: "a7594040c01900010001010096008c00000000000064010400140019010101000000000000000000000000000000000000000000000000000000000000000000000000000000e9")!) + + if let message = message { + XCTAssertTrue(message.messageBody is ReadSettingsCarelinkMessageBody) + + if let body = message.messageBody as? ReadSettingsCarelinkMessageBody { + XCTAssertEqual(3.5, body.maxBasal) + XCTAssertEqual(15, body.maxBolus) + XCTAssertEqual(BasalProfile.Standard, body.selectedBasalProfile) + XCTAssertEqual(4, body.insulinActionCurveHours) + } + + } else { + XCTFail("Message is nil") + } + } + +} diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 067dc6970..20095f7d1 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -12,6 +12,10 @@ 43EC9DCB1B786C6200DB0D18 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */; }; C10A62921C55F8E200E635EE /* UpdateRegisterCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = C10A62911C55F8E200E635EE /* UpdateRegisterCmd.m */; }; C10D9B981C7D6F5200378342 /* PHEChangeMaxBasal.m in Sources */ = {isa = PBXBuildFile; fileRef = C10D9B971C7D6F5200378342 /* PHEChangeMaxBasal.m */; }; + C10D9BC41C8269D500378342 /* MinimedKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C10D9BC31C8269D500378342 /* MinimedKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C10D9BCB1C8269D500378342 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; + C10D9BD61C8269D500378342 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; + C10D9BD71C8269D500378342 /* MinimedKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C10EAA9D1C5AE9A600B0838F /* GetVersionCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = C10EAA9C1C5AE9A600B0838F /* GetVersionCmd.m */; }; C10EAAA31C5B3A0800B0838F /* PumpOpsSynchronous.m in Sources */ = {isa = PBXBuildFile; fileRef = C10EAAA21C5B3A0800B0838F /* PumpOpsSynchronous.m */; }; C10EAAA61C5C507E00B0838F /* PumpOps.m in Sources */ = {isa = PBXBuildFile; fileRef = C10EAAA51C5C507E00B0838F /* PumpOps.m */; }; @@ -122,6 +126,26 @@ C1E535EA1991E36700C2AC49 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535E91991E36700C2AC49 /* NSData+Conversion.m */; }; C1E535ED1991E49600C2AC49 /* RileyLinkBLEManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535EC1991E49600C2AC49 /* RileyLinkBLEManager.m */; }; C1E535F01991E6A200C2AC49 /* MinimedPacket.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535EF1991E6A200C2AC49 /* MinimedPacket.m */; }; + C1EAD6B31C826B6D006DBA60 /* AlertType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */; }; + C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */; }; + C1EAD6B51C826B6D006DBA60 /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B01C826B6D006DBA60 /* MessageType.swift */; }; + C1EAD6B61C826B6D006DBA60 /* PacketType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B11C826B6D006DBA60 /* PacketType.swift */; }; + C1EAD6B71C826B6D006DBA60 /* PumpMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */; }; + C1EAD6C51C826B92006DBA60 /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B91C826B92006DBA60 /* Int.swift */; }; + C1EAD6C61C826B92006DBA60 /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + C1EAD6C71C826B92006DBA60 /* NSDateComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BB1C826B92006DBA60 /* NSDateComponents.swift */; }; + C1EAD6C81C826B92006DBA60 /* CarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */; }; + C1EAD6C91C826B92006DBA60 /* MySentryAckMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BE1C826B92006DBA60 /* MySentryAckMessageBody.swift */; }; + C1EAD6CA1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BF1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift */; }; + C1EAD6CB1C826B92006DBA60 /* MySentryAlertMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6C01C826B92006DBA60 /* MySentryAlertMessageBody.swift */; }; + C1EAD6CC1C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6C11C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift */; }; + C1EAD6CD1C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6C21C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift */; }; + C1EAD6CE1C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6C31C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift */; }; + C1EAD6CF1C826B92006DBA60 /* UnknownMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6C41C826B92006DBA60 /* UnknownMessageBody.swift */; }; + C1EAD6D51C826C43006DBA60 /* MinimedKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D11C826C43006DBA60 /* MinimedKitTests.swift */; }; + C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D21C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift */; }; + C1EAD6D71C826C43006DBA60 /* NSDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */; }; + C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */; }; C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */; }; C1EF58881B3F93FE001C8C80 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58871B3F93FE001C8C80 /* Config.m */; }; C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF588A1B3F9748001C8C80 /* SWRevealViewController.m */; }; @@ -130,6 +154,27 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + C10D9BCC1C8269D500378342 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C10D9BC01C8269D500378342; + remoteInfo = MinimedKit; + }; + C10D9BCE1C8269D500378342 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C12EA236198B436800309FA4; + remoteInfo = RileyLink; + }; + C10D9BD41C8269D500378342 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C10D9BC01C8269D500378342; + remoteInfo = MinimedKit; + }; C12EA257198B436900309FA4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C12EA22F198B436800309FA4 /* Project object */; @@ -139,6 +184,20 @@ }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + C10D9BB81C82614F00378342 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + C10D9BD71C8269D500378342 /* MinimedKit.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 43737CDF1B7F06F100835F8D /* MySentryPairingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MySentryPairingViewController.h; sourceTree = ""; }; 43737CE01B7F06F100835F8D /* MySentryPairingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MySentryPairingViewController.m; sourceTree = ""; }; @@ -149,6 +208,11 @@ C10A62911C55F8E200E635EE /* UpdateRegisterCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateRegisterCmd.m; sourceTree = ""; }; C10D9B961C7D6F5200378342 /* PHEChangeMaxBasal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PHEChangeMaxBasal.h; sourceTree = ""; }; C10D9B971C7D6F5200378342 /* PHEChangeMaxBasal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PHEChangeMaxBasal.m; sourceTree = ""; }; + C10D9BC11C8269D500378342 /* MinimedKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MinimedKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C10D9BC31C8269D500378342 /* MinimedKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinimedKit.h; sourceTree = ""; }; + C10D9BC51C8269D500378342 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C10D9BCA1C8269D500378342 /* MinimedKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MinimedKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + C10D9BD31C8269D500378342 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C10EAA9B1C5AE9A600B0838F /* GetVersionCmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetVersionCmd.h; sourceTree = ""; }; C10EAA9C1C5AE9A600B0838F /* GetVersionCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GetVersionCmd.m; sourceTree = ""; }; C10EAAA11C5B3A0800B0838F /* PumpOpsSynchronous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PumpOpsSynchronous.h; sourceTree = ""; }; @@ -358,6 +422,26 @@ C1E535EC1991E49600C2AC49 /* RileyLinkBLEManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RileyLinkBLEManager.m; sourceTree = ""; }; C1E535EE1991E6A200C2AC49 /* MinimedPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MinimedPacket.h; sourceTree = ""; }; C1E535EF1991E6A200C2AC49 /* MinimedPacket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MinimedPacket.m; sourceTree = ""; }; + C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertType.swift; sourceTree = ""; }; + C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageBody.swift; sourceTree = ""; }; + C1EAD6B01C826B6D006DBA60 /* MessageType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageType.swift; sourceTree = ""; }; + C1EAD6B11C826B6D006DBA60 /* PacketType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketType.swift; sourceTree = ""; }; + C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpMessage.swift; sourceTree = ""; }; + C1EAD6B91C826B92006DBA60 /* Int.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Int.swift; sourceTree = ""; }; + C1EAD6BA1C826B92006DBA60 /* NSData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSData.swift; sourceTree = ""; }; + C1EAD6BB1C826B92006DBA60 /* NSDateComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDateComponents.swift; sourceTree = ""; }; + C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarelinkMessageBody.swift; sourceTree = ""; }; + C1EAD6BE1C826B92006DBA60 /* MySentryAckMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryAckMessageBody.swift; sourceTree = ""; }; + C1EAD6BF1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryAlertClearedMessageBody.swift; sourceTree = ""; }; + C1EAD6C01C826B92006DBA60 /* MySentryAlertMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryAlertMessageBody.swift; sourceTree = ""; }; + C1EAD6C11C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryPumpStatusMessageBody.swift; sourceTree = ""; }; + C1EAD6C21C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PowerOnCarelinkMessageBody.swift; sourceTree = ""; }; + C1EAD6C31C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadSettingsCarelinkMessageBody.swift; sourceTree = ""; }; + C1EAD6C41C826B92006DBA60 /* UnknownMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnknownMessageBody.swift; sourceTree = ""; }; + C1EAD6D11C826C43006DBA60 /* MinimedKitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedKitTests.swift; sourceTree = ""; }; + C1EAD6D21C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryPumpStatusMessageBodyTests.swift; sourceTree = ""; }; + C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDataTests.swift; sourceTree = ""; }; + C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadSettingsCarelinkMessageBodyTests.swift; sourceTree = ""; }; C1EF58831B3E5DA4001C8C80 /* ConfigureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureViewController.h; sourceTree = ""; }; C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureViewController.m; sourceTree = ""; }; C1EF58861B3F93FE001C8C80 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; @@ -371,6 +455,21 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + C10D9BBD1C8269D500378342 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C10D9BC71C8269D500378342 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C10D9BCB1C8269D500378342 /* MinimedKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C12EA234198B436800309FA4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -378,6 +477,7 @@ C12EA23D198B436800309FA4 /* CoreGraphics.framework in Frameworks */, C12EA23F198B436800309FA4 /* UIKit.framework in Frameworks */, C12EA23B198B436800309FA4 /* Foundation.framework in Frameworks */, + C10D9BD61C8269D500378342 /* MinimedKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -395,6 +495,34 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + C10D9BC21C8269D500378342 /* MinimedKit */ = { + isa = PBXGroup; + children = ( + C1EAD6B81C826B92006DBA60 /* Extensions */, + C1EAD6BC1C826B92006DBA60 /* Messages */, + C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */, + C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */, + C1EAD6B01C826B6D006DBA60 /* MessageType.swift */, + C1EAD6B11C826B6D006DBA60 /* PacketType.swift */, + C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */, + C10D9BC31C8269D500378342 /* MinimedKit.h */, + C10D9BC51C8269D500378342 /* Info.plist */, + ); + path = MinimedKit; + sourceTree = ""; + }; + C10D9BD01C8269D500378342 /* MinimedKitTests */ = { + isa = PBXGroup; + children = ( + C1EAD6D11C826C43006DBA60 /* MinimedKitTests.swift */, + C1EAD6D21C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift */, + C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */, + C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */, + C10D9BD31C8269D500378342 /* Info.plist */, + ); + path = MinimedKitTests; + sourceTree = ""; + }; C11F993A1BC405AA0013158C /* Pump */ = { isa = PBXGroup; children = ( @@ -463,6 +591,8 @@ isa = PBXGroup; children = ( C12EA240198B436800309FA4 /* RileyLink */, + C10D9BC21C8269D500378342 /* MinimedKit */, + C10D9BD01C8269D500378342 /* MinimedKitTests */, C12EA239198B436800309FA4 /* Frameworks */, C12EA238198B436800309FA4 /* Products */, ); @@ -473,6 +603,8 @@ children = ( C12EA237198B436800309FA4 /* RileyLink.app */, C12EA252198B436800309FA4 /* RileyLinkTests.xctest */, + C10D9BC11C8269D500378342 /* MinimedKit.framework */, + C10D9BCA1C8269D500378342 /* MinimedKitTests.xctest */, ); name = Products; sourceTree = ""; @@ -701,6 +833,31 @@ name = Categories; sourceTree = ""; }; + C1EAD6B81C826B92006DBA60 /* Extensions */ = { + isa = PBXGroup; + children = ( + C1EAD6B91C826B92006DBA60 /* Int.swift */, + C1EAD6BA1C826B92006DBA60 /* NSData.swift */, + C1EAD6BB1C826B92006DBA60 /* NSDateComponents.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + C1EAD6BC1C826B92006DBA60 /* Messages */ = { + isa = PBXGroup; + children = ( + C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */, + C1EAD6BE1C826B92006DBA60 /* MySentryAckMessageBody.swift */, + C1EAD6BF1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift */, + C1EAD6C01C826B92006DBA60 /* MySentryAlertMessageBody.swift */, + C1EAD6C11C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift */, + C1EAD6C21C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift */, + C1EAD6C31C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift */, + C1EAD6C41C826B92006DBA60 /* UnknownMessageBody.swift */, + ); + path = Messages; + sourceTree = ""; + }; C1EF58891B3F9730001C8C80 /* SWRevealViewController */ = { isa = PBXGroup; children = ( @@ -775,7 +932,55 @@ }; /* End PBXGroup section */ +/* Begin PBXHeadersBuildPhase section */ + C10D9BBE1C8269D500378342 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C10D9BC41C8269D500378342 /* MinimedKit.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + /* Begin PBXNativeTarget section */ + C10D9BC01C8269D500378342 /* MinimedKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = C10D9BD81C8269D600378342 /* Build configuration list for PBXNativeTarget "MinimedKit" */; + buildPhases = ( + C10D9BBC1C8269D500378342 /* Sources */, + C10D9BBD1C8269D500378342 /* Frameworks */, + C10D9BBE1C8269D500378342 /* Headers */, + C10D9BBF1C8269D500378342 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MinimedKit; + productName = MinimedKit; + productReference = C10D9BC11C8269D500378342 /* MinimedKit.framework */; + productType = "com.apple.product-type.framework"; + }; + C10D9BC91C8269D500378342 /* MinimedKitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = C10D9BDB1C8269D600378342 /* Build configuration list for PBXNativeTarget "MinimedKitTests" */; + buildPhases = ( + C10D9BC61C8269D500378342 /* Sources */, + C10D9BC71C8269D500378342 /* Frameworks */, + C10D9BC81C8269D500378342 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + C10D9BCD1C8269D500378342 /* PBXTargetDependency */, + C10D9BCF1C8269D500378342 /* PBXTargetDependency */, + ); + name = MinimedKitTests; + productName = MinimedKitTests; + productReference = C10D9BCA1C8269D500378342 /* MinimedKitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; C12EA236198B436800309FA4 /* RileyLink */ = { isa = PBXNativeTarget; buildConfigurationList = C12EA263198B436900309FA4 /* Build configuration list for PBXNativeTarget "RileyLink" */; @@ -784,10 +989,12 @@ C12EA233198B436800309FA4 /* Sources */, C12EA234198B436800309FA4 /* Frameworks */, C12EA235198B436800309FA4 /* Resources */, + C10D9BB81C82614F00378342 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( + C10D9BD51C8269D500378342 /* PBXTargetDependency */, ); name = RileyLink; productName = RileyLink; @@ -818,9 +1025,18 @@ C12EA22F198B436800309FA4 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 0720; LastUpgradeCheck = 0510; ORGANIZATIONNAME = "Pete Schwamb"; TargetAttributes = { + C10D9BC01C8269D500378342 = { + CreatedOnToolsVersion = 7.2.1; + DevelopmentTeam = UY678SP37Q; + }; + C10D9BC91C8269D500378342 = { + CreatedOnToolsVersion = 7.2.1; + TestTargetID = C12EA236198B436800309FA4; + }; C12EA236198B436800309FA4 = { DevelopmentTeam = UY678SP37Q; }; @@ -843,11 +1059,27 @@ targets = ( C12EA236198B436800309FA4 /* RileyLink */, C12EA251198B436800309FA4 /* RileyLinkTests */, + C10D9BC01C8269D500378342 /* MinimedKit */, + C10D9BC91C8269D500378342 /* MinimedKitTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + C10D9BBF1C8269D500378342 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C10D9BC81C8269D500378342 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; C12EA235198B436800309FA4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -886,6 +1118,40 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + C10D9BBC1C8269D500378342 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C1EAD6B51C826B6D006DBA60 /* MessageType.swift in Sources */, + C1EAD6B61C826B6D006DBA60 /* PacketType.swift in Sources */, + C1EAD6CA1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift in Sources */, + C1EAD6B31C826B6D006DBA60 /* AlertType.swift in Sources */, + C1EAD6CD1C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift in Sources */, + C1EAD6C81C826B92006DBA60 /* CarelinkMessageBody.swift in Sources */, + C1EAD6CF1C826B92006DBA60 /* UnknownMessageBody.swift in Sources */, + C1EAD6C91C826B92006DBA60 /* MySentryAckMessageBody.swift in Sources */, + C1EAD6CE1C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift in Sources */, + C1EAD6C51C826B92006DBA60 /* Int.swift in Sources */, + C1EAD6CB1C826B92006DBA60 /* MySentryAlertMessageBody.swift in Sources */, + C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */, + C1EAD6C61C826B92006DBA60 /* NSData.swift in Sources */, + C1EAD6CC1C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift in Sources */, + C1EAD6C71C826B92006DBA60 /* NSDateComponents.swift in Sources */, + C1EAD6B71C826B6D006DBA60 /* PumpMessage.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C10D9BC61C8269D500378342 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */, + C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */, + C1EAD6D71C826C43006DBA60 /* NSDataTests.swift in Sources */, + C1EAD6D51C826C43006DBA60 /* MinimedKitTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C12EA233198B436800309FA4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1011,6 +1277,21 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + C10D9BCD1C8269D500378342 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C10D9BC01C8269D500378342 /* MinimedKit */; + targetProxy = C10D9BCC1C8269D500378342 /* PBXContainerItemProxy */; + }; + C10D9BCF1C8269D500378342 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C12EA236198B436800309FA4 /* RileyLink */; + targetProxy = C10D9BCE1C8269D500378342 /* PBXContainerItemProxy */; + }; + C10D9BD51C8269D500378342 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C10D9BC01C8269D500378342 /* MinimedKit */; + targetProxy = C10D9BD41C8269D500378342 /* PBXContainerItemProxy */; + }; C12EA258198B436900309FA4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = C12EA236198B436800309FA4 /* RileyLink */; @@ -1038,6 +1319,104 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + C10D9BD91C8269D600378342 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = MinimedKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C10D9BDA1C8269D600378342 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = MinimedKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + C10D9BDC1C8269D600378342 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = MinimedKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; + }; + name = Debug; + }; + C10D9BDD1C8269D600378342 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = MinimedKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; + }; + name = Release; + }; C12EA261198B436900309FA4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1117,9 +1496,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RileyLink/RileyLink-Prefix.pch"; INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.rlapp; PRODUCT_NAME = RileyLink; PROVISIONING_PROFILE = ""; @@ -1133,9 +1514,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "RileyLink/RileyLink-Prefix.pch"; INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.rlapp; PRODUCT_NAME = RileyLink; PROVISIONING_PROFILE = ""; @@ -1187,6 +1570,24 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + C10D9BD81C8269D600378342 /* Build configuration list for PBXNativeTarget "MinimedKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C10D9BD91C8269D600378342 /* Debug */, + C10D9BDA1C8269D600378342 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C10D9BDB1C8269D600378342 /* Build configuration list for PBXNativeTarget "MinimedKitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C10D9BDC1C8269D600378342 /* Debug */, + C10D9BDD1C8269D600378342 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C12EA232198B436800309FA4 /* Build configuration list for PBXProject "RileyLink" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/RileyLink/HistoryPage.m b/RileyLink/HistoryPage.m index dd29644c5..4fa094bf5 100644 --- a/RileyLink/HistoryPage.m +++ b/RileyLink/HistoryPage.m @@ -47,6 +47,12 @@ - (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullab return self; } +- (instancetype)init NS_UNAVAILABLE +{ + return nil; +} + + - (NSArray*) decode { NSMutableArray *events = [NSMutableArray array]; NSUInteger offset = 0; diff --git a/RileyLink/LaunchScreen.xib b/RileyLink/LaunchScreen.xib index 34fa0ea68..402471489 100644 --- a/RileyLink/LaunchScreen.xib +++ b/RileyLink/LaunchScreen.xib @@ -1,8 +1,8 @@ - + - + @@ -20,7 +20,7 @@ - + diff --git a/RileyLink/MinimedPacket.m b/RileyLink/MinimedPacket.m index 4b1b5ae70..fe2a1d511 100644 --- a/RileyLink/MinimedPacket.m +++ b/RileyLink/MinimedPacket.m @@ -178,6 +178,8 @@ - (MessageBase*)toMessage { return [[DeviceLinkMessage alloc] initWithData:_data]; case MESSAGE_TYPE_FIND_DEVICE: return [[FindDeviceMessage alloc] initWithData:_data]; + default: + return nil; } } else if (self.packetType == PacketTypeMeter) { return [[MeterMessage alloc] initWithData:_data]; diff --git a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m index c64e8daf5..dab41fa2b 100644 --- a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m +++ b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m @@ -37,6 +37,12 @@ - (instancetype)initWithData:(NSData*)data andPumpModel:(PumpModel*)model return self; } +- (instancetype)init NS_UNAVAILABLE +{ + return nil; +} + + - (int) length { [NSException raise:@"Invalid Message" format:@"PumpHistoryEventBase does not implement length."]; return 0; From 87401d3fb542992e86e002dd339e6ce012e1c462 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 27 Feb 2016 18:33:35 -0800 Subject: [PATCH 003/116] Clean some build warnings and dependencies --- RileyLink/HistoryPage.m | 5 +++++ RileyLink/MinimedPacket.m | 2 ++ RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m | 5 +++++ RileyLink/PumpOpsSynchronous.h | 1 + RileyLink/PumpState.h | 1 - RileyLink/PumpState.m | 7 ------- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/RileyLink/HistoryPage.m b/RileyLink/HistoryPage.m index dd29644c5..3cde32ceb 100644 --- a/RileyLink/HistoryPage.m +++ b/RileyLink/HistoryPage.m @@ -15,6 +15,11 @@ @implementation HistoryPage +- (instancetype)init NS_UNAVAILABLE +{ + return nil; +} + - (nonnull instancetype)initWithData:(nonnull NSData *)data andPumpModel:(nullable PumpModel *)model { self = [super init]; diff --git a/RileyLink/MinimedPacket.m b/RileyLink/MinimedPacket.m index 4b1b5ae70..fe2a1d511 100644 --- a/RileyLink/MinimedPacket.m +++ b/RileyLink/MinimedPacket.m @@ -178,6 +178,8 @@ - (MessageBase*)toMessage { return [[DeviceLinkMessage alloc] initWithData:_data]; case MESSAGE_TYPE_FIND_DEVICE: return [[FindDeviceMessage alloc] initWithData:_data]; + default: + return nil; } } else if (self.packetType == PacketTypeMeter) { return [[MeterMessage alloc] initWithData:_data]; diff --git a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m index c64e8daf5..729f2be0c 100644 --- a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m +++ b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m @@ -18,6 +18,11 @@ @interface PumpHistoryEventBase () @implementation PumpHistoryEventBase +- (instancetype)init NS_UNAVAILABLE +{ + return nil; +} + - (instancetype)initWithData:(NSData*)data andPumpModel:(PumpModel*)model { self = [super init]; diff --git a/RileyLink/PumpOpsSynchronous.h b/RileyLink/PumpOpsSynchronous.h index f9334deee..785ccc946 100644 --- a/RileyLink/PumpOpsSynchronous.h +++ b/RileyLink/PumpOpsSynchronous.h @@ -8,6 +8,7 @@ #import #import "PumpState.h" +#import "RileyLinkBLEDevice.h" @interface PumpOpsSynchronous : NSObject diff --git a/RileyLink/PumpState.h b/RileyLink/PumpState.h index b21e5a11e..52413ac85 100644 --- a/RileyLink/PumpState.h +++ b/RileyLink/PumpState.h @@ -7,7 +7,6 @@ // #import -#import "RileyLinkBLEDevice.h" @interface PumpState : NSObject diff --git a/RileyLink/PumpState.m b/RileyLink/PumpState.m index 26e3c885d..de28284b4 100644 --- a/RileyLink/PumpState.m +++ b/RileyLink/PumpState.m @@ -7,13 +7,6 @@ // #import "PumpState.h" -#import "NSData+Conversion.h" -#import "SendPacketCmd.h" -#import "SendAndListenCmd.h" -#import "RileyLinkBLEDevice.h" -#import "MinimedPacket.h" -#import "MessageBase.h" -#import "UpdateRegisterCmd.h" @implementation PumpState From e4c7c54a6f3f6989c3cb222178c8eeb853083e3f Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 27 Feb 2016 18:51:18 -0800 Subject: [PATCH 004/116] Persist invoking idle through disconnects --- RileyLink/RileyLinkBLEDevice.h | 2 +- RileyLink/RileyLinkBLEDevice.m | 18 +++++++++++++++++- RileyLink/RileyLinkBLEManager.m | 11 ++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/RileyLink/RileyLinkBLEDevice.h b/RileyLink/RileyLinkBLEDevice.h index acdca409f..cb3631dd0 100644 --- a/RileyLink/RileyLinkBLEDevice.h +++ b/RileyLink/RileyLinkBLEDevice.h @@ -70,7 +70,7 @@ typedef NS_ENUM(NSUInteger, SubgRfspyError) { */ - (nonnull instancetype)initWithPeripheral:(nonnull CBPeripheral *)peripheral NS_DESIGNATED_INITIALIZER; -- (void) didDisconnect:(nullable NSError*)error; +- (void) connectionStateDidChange:(nullable NSError *)error; - (void) runSession:(void (^ _Nonnull)(RileyLinkCmdSession* _Nonnull))proc; - (void) setCustomName:(nonnull NSString*)customName; diff --git a/RileyLink/RileyLinkBLEDevice.m b/RileyLink/RileyLinkBLEDevice.m index b6a243b6f..0b7423d35 100644 --- a/RileyLink/RileyLinkBLEDevice.m +++ b/RileyLink/RileyLinkBLEDevice.m @@ -177,7 +177,22 @@ - (RileyLinkState) state { return rval; } -- (void) didDisconnect:(NSError*)error { +- (void)connectionStateDidChange:(NSError *)error +{ + switch (self.peripheral.state) { + case CBPeripheralStateConnected: + if (idleListeningEnabled) { + [self onIdle]; + } + break; + case CBPeripheralStateDisconnected: + runningIdle = NO; + runningSession = NO; + break; + case CBPeripheralStateConnecting: + case CBPeripheralStateDisconnecting: + break; + } } - (void)setCharacteristicsFromService:(CBService *)service { @@ -427,6 +442,7 @@ - (void) enableIdleListeningOnChannel:(uint8_t)channel { - (void) disableIdleListening { idleListeningEnabled = NO; + runningIdle = NO; } - (void) handleIdleListenerResponse:(NSData *)response { diff --git a/RileyLink/RileyLinkBLEManager.m b/RileyLink/RileyLinkBLEManager.m index 2b28314bb..9dea5d092 100644 --- a/RileyLink/RileyLinkBLEManager.m +++ b/RileyLink/RileyLinkBLEManager.m @@ -190,7 +190,10 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"Failed to connect to peripheral: %@", error); - + + RileyLinkBLEDevice *device = _devicesById[peripheral.identifier.UUIDString]; + [device connectionStateDidChange:error]; + [self attemptReconnectForDisconnectedDevices]; } @@ -201,7 +204,9 @@ - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPerip excludingAttributes:peripheral.services]]; RileyLinkBLEDevice *device = _devicesById[peripheral.identifier.UUIDString]; - + + [device connectionStateDidChange:nil]; + NSDictionary *attrs = @{@"peripheral": peripheral}; [[NSNotificationCenter defaultCenter] postNotificationName:RILEYLINK_EVENT_DEVICE_CONNECTED object:device userInfo:attrs]; @@ -217,7 +222,7 @@ - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPe attrs[@"peripheral"] = peripheral; RileyLinkBLEDevice *device = _devicesById[peripheral.identifier.UUIDString]; - [device didDisconnect:error]; + [device connectionStateDidChange:error]; if (error) { attrs[@"error"] = error; From 534c692bc886b36b5b3314a1de285fd718753598 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 27 Feb 2016 23:15:33 -0600 Subject: [PATCH 005/116] Add encode and decode for 4b6b, and crc8 --- MinimedKit/CRC8.swift | 26 ++++++++++++ MinimedKit/RFTools.swift | 66 +++++++++++++++++++++++++++++ MinimedKitTests/CRC8Tests.swift | 29 +++++++++++++ MinimedKitTests/RFToolsTests.swift | 56 ++++++++++++++++++++++++ RileyLink.xcodeproj/project.pbxproj | 20 ++++++++- 5 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 MinimedKit/CRC8.swift create mode 100644 MinimedKit/RFTools.swift create mode 100644 MinimedKitTests/CRC8Tests.swift create mode 100644 MinimedKitTests/RFToolsTests.swift diff --git a/MinimedKit/CRC8.swift b/MinimedKit/CRC8.swift new file mode 100644 index 000000000..f9a8fc656 --- /dev/null +++ b/MinimedKit/CRC8.swift @@ -0,0 +1,26 @@ +// +// CRC8.swift +// RileyLink +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + + +func computeCRC8(data: NSData) -> UInt8 { + let crcTable: [UInt8] = [0x0, 0x9B, 0xAD, 0x36, 0xC1, 0x5A, 0x6C, 0xF7, 0x19, 0x82, 0xB4, 0x2F, 0xD8, 0x43, 0x75, 0xEE, 0x32, 0xA9, 0x9F, 0x4, 0xF3, 0x68, 0x5E, 0xC5, 0x2B, 0xB0, 0x86, 0x1D, 0xEA, 0x71, 0x47, 0xDC, 0x64, 0xFF, 0xC9, 0x52, 0xA5, 0x3E, 0x8, 0x93, 0x7D, 0xE6, 0xD0, 0x4B, 0xBC, 0x27, 0x11, 0x8A, 0x56, 0xCD, 0xFB, 0x60, 0x97, 0xC, 0x3A, 0xA1, 0x4F, 0xD4, 0xE2, 0x79, 0x8E, 0x15, 0x23, 0xB8, 0xC8, 0x53, 0x65, 0xFE, 0x9, 0x92, 0xA4, 0x3F, 0xD1, 0x4A, 0x7C, 0xE7, 0x10, 0x8B, 0xBD, 0x26, 0xFA, 0x61, 0x57, 0xCC, 0x3B, 0xA0, 0x96, 0xD, 0xE3, 0x78, 0x4E, 0xD5, 0x22, 0xB9, 0x8F, 0x14, 0xAC, 0x37, 0x1, 0x9A, 0x6D, 0xF6, 0xC0, 0x5B, 0xB5, 0x2E, 0x18, 0x83, 0x74, 0xEF, 0xD9, 0x42, 0x9E, 0x5, 0x33, 0xA8, 0x5F, 0xC4, 0xF2, 0x69, 0x87, 0x1C, 0x2A, 0xB1, 0x46, 0xDD, 0xEB, 0x70, 0xB, 0x90, 0xA6, 0x3D, 0xCA, 0x51, 0x67, 0xFC, 0x12, 0x89, 0xBF, 0x24, 0xD3, 0x48, 0x7E, 0xE5, 0x39, 0xA2, 0x94, 0xF, 0xF8, 0x63, 0x55, 0xCE, 0x20, 0xBB, 0x8D, 0x16, 0xE1, 0x7A, 0x4C, 0xD7, 0x6F, 0xF4, 0xC2, 0x59, 0xAE, 0x35, 0x3, 0x98, 0x76, 0xED, 0xDB, 0x40, 0xB7, 0x2C, 0x1A, 0x81, 0x5D, 0xC6, 0xF0, 0x6B, 0x9C, 0x7, 0x31, 0xAA, 0x44, 0xDF, 0xE9, 0x72, 0x85, 0x1E, 0x28, 0xB3, 0xC3, 0x58, 0x6E, 0xF5, 0x2, 0x99, 0xAF, 0x34, 0xDA, 0x41, 0x77, 0xEC, 0x1B, 0x80, 0xB6, 0x2D, 0xF1, 0x6A, 0x5C, 0xC7, 0x30, 0xAB, 0x9D, 0x6, 0xE8, 0x73, 0x45, 0xDE, 0x29, 0xB2, 0x84, 0x1F, 0xA7, 0x3C, 0xA, 0x91, 0x66, 0xFD, 0xCB, 0x50, 0xBE, 0x25, 0x13, 0x88, 0x7F, 0xE4, 0xD2, 0x49, 0x95, 0xE, 0x38, 0xA3, 0x54, 0xCF, 0xF9, 0x62, 0x8C, 0x17, 0x21, 0xBA, 0x4D, 0xD6, 0xE0, 0x7B] + + var crc: UInt8 = 0 + + var pdata = UnsafePointer(data.bytes) + var nbytes = data.length + /* loop over the buffer data */ + while nbytes-- > 0 { + crc = crcTable[Int((crc ^ pdata.memory) & 0xff)]; + pdata++; + } + return crc; +} + diff --git a/MinimedKit/RFTools.swift b/MinimedKit/RFTools.swift new file mode 100644 index 000000000..fcbd3630b --- /dev/null +++ b/MinimedKit/RFTools.swift @@ -0,0 +1,66 @@ +// +// RFTools.swift +// RileyLink +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + +func decode4b6b(rawData: NSData) -> NSData? { + let codes:Dictionary = [21: 0, 49: 1, 50: 2, 35: 3, 52: 4, 37: 5, 38: 6, 22: 7, 26: 8, 25: 9, 42: 10, 11: 11, 44: 12, 13: 13, 14: 14, 28: 15] + var buffer = [UInt8]() + let bytes = UnsafeBufferPointer(start:UnsafePointer(rawData.bytes), count:rawData.length) + var availBits: UInt = 0 + var x: UInt = 0 + var hiNibble: UInt8? + var loNibble: UInt8? + for var i = 0; i < rawData.length; i++ { + x = (x << 8) + UInt(bytes[i]) + availBits += 8 + if availBits >= 12 { + hiNibble = codes[x >> (availBits - 6)] + loNibble = codes[(x >> (availBits - 12)) & 0b111111] + + if hiNibble != nil && loNibble != nil { + let decoded: UInt8 = UInt8((hiNibble! << 4) + loNibble!) + buffer.append(decoded) + } else { + return nil + } + availBits -= 12; + x = x & (0xffff >> (16-availBits)); + } + } + return NSData(bytes: &buffer, length: buffer.count) +} + +func encode4b6b(rawData: NSData) -> NSData { + var buffer = [UInt8]() + let codes: [UInt] = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] + let bytes = UnsafeBufferPointer(start:UnsafePointer(rawData.bytes), count:rawData.length) + var acc: UInt = 0x0 + var bitcount: UInt = 0 + for var i=0; i < rawData.length; i++ { + acc <<= 6; + acc |= codes[Int(bytes[i] >> 4)] + bitcount += 6; + + acc <<= 6; + acc |= codes[Int(bytes[i] & 0x0f)]; + bitcount += 6; + + while bitcount >= 8 { + buffer.append(UInt8(acc >> (bitcount-8)) & 0xff) + bitcount -= 8; + acc &= (0xffff >> (16-bitcount)); + } + } + if (bitcount > 0) { + acc <<= (8-bitcount); + buffer.append(UInt8(acc) & 0xff); + } + return NSData(bytes: &buffer, length: buffer.count) +} + diff --git a/MinimedKitTests/CRC8Tests.swift b/MinimedKitTests/CRC8Tests.swift new file mode 100644 index 000000000..1c4284905 --- /dev/null +++ b/MinimedKitTests/CRC8Tests.swift @@ -0,0 +1,29 @@ +// +// CRC8Tests.swift +// RileyLink +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import XCTest +@testable import MinimedKit + + +class CRC8Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testComputeCRC8() { + let input = NSData(hexadecimalString: "a259705504a24117043a0e080b003d3d00015b030105d817790a0f00000300008b1702000e080b0000")! + XCTAssertTrue(0x71 == computeCRC8(input)) + } +} diff --git a/MinimedKitTests/RFToolsTests.swift b/MinimedKitTests/RFToolsTests.swift new file mode 100644 index 000000000..20d33895d --- /dev/null +++ b/MinimedKitTests/RFToolsTests.swift @@ -0,0 +1,56 @@ +// +// RFToolsTests.swift +// RileyLink +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import XCTest +@testable import MinimedKit + +class RFToolsTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testDecode4b6b() { + let input = NSData(hexadecimalString: "ab2959595965574ab2d31c565748ea54e55a54b5558cd8cd55557194b56357156535ac5659956a55c55555556355555568bc5657255554e55a54b5555555b100")! + + let result = decode4b6b(input) + + if let result = result { + let expectedOutput = NSData(hexadecimalString: "a259705504a24117043a0e080b003d3d00015b030105d817790a0f00000300008b1702000e080b000071") + XCTAssertTrue(result == expectedOutput) + } else { + XCTFail("\(result) is nil") + } + } + + func testDecode4b6bWithBadData() { + let input = NSData(hexadecimalString: "0102030405")! + + let result = decode4b6b(input) + XCTAssertTrue(result == nil) + } + + + func testEncode4b6b() { + let input = NSData(hexadecimalString: "a259705504a24117043a0e080b003d3d00015b030105d817790a0f00000300008b1702000e080b000071")! + + let result = encode4b6b(input) + + NSLog("output = %@", result) + let expectedOutput = NSData(hexadecimalString: "ab2959595965574ab2d31c565748ea54e55a54b5558cd8cd55557194b56357156535ac5659956a55c55555556355555568bc5657255554e55a54b5555555b1") + XCTAssertTrue(result == expectedOutput) + } + + +} \ No newline at end of file diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 20095f7d1..f64525d02 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -146,6 +146,10 @@ C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D21C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift */; }; C1EAD6D71C826C43006DBA60 /* NSDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */; }; C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */; }; + C1EAD6DA1C829104006DBA60 /* RFTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6D91C829104006DBA60 /* RFTools.swift */; }; + C1EAD6DC1C82A4AB006DBA60 /* RFToolsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */; }; + C1EAD6DE1C82B78C006DBA60 /* CRC8.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */; }; + C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */; }; C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */; }; C1EF58881B3F93FE001C8C80 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58871B3F93FE001C8C80 /* Config.m */; }; C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF588A1B3F9748001C8C80 /* SWRevealViewController.m */; }; @@ -442,6 +446,10 @@ C1EAD6D21C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryPumpStatusMessageBodyTests.swift; sourceTree = ""; }; C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDataTests.swift; sourceTree = ""; }; C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadSettingsCarelinkMessageBodyTests.swift; sourceTree = ""; }; + C1EAD6D91C829104006DBA60 /* RFTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RFTools.swift; sourceTree = ""; }; + C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RFToolsTests.swift; sourceTree = ""; }; + C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC8.swift; sourceTree = ""; }; + C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC8Tests.swift; sourceTree = ""; }; C1EF58831B3E5DA4001C8C80 /* ConfigureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureViewController.h; sourceTree = ""; }; C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureViewController.m; sourceTree = ""; }; C1EF58861B3F93FE001C8C80 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; @@ -498,6 +506,8 @@ C10D9BC21C8269D500378342 /* MinimedKit */ = { isa = PBXGroup; children = ( + C10D9BC31C8269D500378342 /* MinimedKit.h */, + C10D9BC51C8269D500378342 /* Info.plist */, C1EAD6B81C826B92006DBA60 /* Extensions */, C1EAD6BC1C826B92006DBA60 /* Messages */, C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */, @@ -505,8 +515,8 @@ C1EAD6B01C826B6D006DBA60 /* MessageType.swift */, C1EAD6B11C826B6D006DBA60 /* PacketType.swift */, C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */, - C10D9BC31C8269D500378342 /* MinimedKit.h */, - C10D9BC51C8269D500378342 /* Info.plist */, + C1EAD6D91C829104006DBA60 /* RFTools.swift */, + C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */, ); path = MinimedKit; sourceTree = ""; @@ -519,6 +529,8 @@ C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */, C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */, C10D9BD31C8269D500378342 /* Info.plist */, + C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */, + C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */, ); path = MinimedKitTests; sourceTree = ""; @@ -1131,12 +1143,14 @@ C1EAD6CF1C826B92006DBA60 /* UnknownMessageBody.swift in Sources */, C1EAD6C91C826B92006DBA60 /* MySentryAckMessageBody.swift in Sources */, C1EAD6CE1C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift in Sources */, + C1EAD6DE1C82B78C006DBA60 /* CRC8.swift in Sources */, C1EAD6C51C826B92006DBA60 /* Int.swift in Sources */, C1EAD6CB1C826B92006DBA60 /* MySentryAlertMessageBody.swift in Sources */, C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */, C1EAD6C61C826B92006DBA60 /* NSData.swift in Sources */, C1EAD6CC1C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift in Sources */, C1EAD6C71C826B92006DBA60 /* NSDateComponents.swift in Sources */, + C1EAD6DA1C829104006DBA60 /* RFTools.swift in Sources */, C1EAD6B71C826B6D006DBA60 /* PumpMessage.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1148,6 +1162,8 @@ C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */, C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */, C1EAD6D71C826C43006DBA60 /* NSDataTests.swift in Sources */, + C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */, + C1EAD6DC1C82A4AB006DBA60 /* RFToolsTests.swift in Sources */, C1EAD6D51C826C43006DBA60 /* MinimedKitTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; From f9ae5e271679319a0eb9d2594de7d47bf6096d8c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 27 Feb 2016 23:26:15 -0600 Subject: [PATCH 006/116] crc16 --- MinimedKit/CRC16.swift | 25 +++++++++++++++++++++++++ MinimedKitTests/CRC16Tests.swift | 29 +++++++++++++++++++++++++++++ RileyLink.xcodeproj/project.pbxproj | 8 ++++++++ 3 files changed, 62 insertions(+) create mode 100644 MinimedKit/CRC16.swift create mode 100644 MinimedKitTests/CRC16Tests.swift diff --git a/MinimedKit/CRC16.swift b/MinimedKit/CRC16.swift new file mode 100644 index 000000000..596ae1f18 --- /dev/null +++ b/MinimedKit/CRC16.swift @@ -0,0 +1,25 @@ +// +// CRC16.swift +// RileyLink +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + +func computeCRC16(data: NSData) -> UInt16 { + + let crcTable: [UInt16] = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302, 37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907, 9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789, 59790, 63919, 35144, 39273, 43274, 47403, 23285, 19156, 31415, 27286, 6769, 2640, 14899, 10770, 56317, 52188, 64447, 60318, 39801, 35672, 47931, 43802, 27814, 31879, 19684, 23749, 11298, 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395, 36200, 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 61374, 57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679, 33721, 37784, 41979, 46042, 49981, 54044, 58239, 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 1153, 29798, 25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068, 55628, 51565, 63758, 59695, 39368, 35305, 47498, 43435, 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801, 6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955, 49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920] + + var crc: UInt16 = 0xffff + var pdata = UnsafePointer(data.bytes) + var nbytes = data.length + /* loop over the buffer data */ + while nbytes-- > 0 { + let idx = ((crc >> 8) ^ UInt16(pdata.memory)) & 0xff + crc = ((crc << 8) ^ crcTable[Int(idx)]) & 0xffff; + pdata++ + } + return crc; +} diff --git a/MinimedKitTests/CRC16Tests.swift b/MinimedKitTests/CRC16Tests.swift new file mode 100644 index 000000000..919ddf3af --- /dev/null +++ b/MinimedKitTests/CRC16Tests.swift @@ -0,0 +1,29 @@ +// +// CRC16Tests.swift +// RileyLink +// +// Created by Pete Schwamb on 2/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import XCTest +@testable import MinimedKit + + +class CRC16Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testComputeCRC16() { + let input = NSData(hexadecimalString: "5be409a20a1510325000784b502800a400002400a8965c0b404fc038cbd008d5d0010080008000240009a24a15107b0500800c1510180a000ade19a32c15105bde2ba30c1510325000b44b5024006c0000200070965c0b4c78c03482c040c8c001007000700020002ba34c15100a0c22932d75903f2122938d7510c527ad5b0006900f15101a5000b44b500000380000000038965c0e70a1c04c19d03423d04069d00100380038000c0006904f15107b060080101510200e005b0034ab1015100d5000784b500000280000000028965c113858c070f8c04c70d0347ad040c0d00100280028001c0034ab5015100ab005863175903f360586117510c527ad5bb01486111510005100784b50940000000038005c965c14281fc0386fc0700fd04c87d03491d040d7d001005c005c00380014865115105b002291121510285000784b500000840000000084965c145c48c02866c038b6c07056d04cced034d8d0010084008400480022915215107b0700801315102610002100038414151003000000360785341510064a097e009e54b5100c4a03a11415107b0704a11415102610007b0704a11415102610007b0710a1141510261000030003000306a11415100ae937a23475103f1d37a2347510c527ad5be91ea3141510165000784b502c00480000140060965c0e848cc05cd2c028f0c03840d001006000600014001ea35415107b0800801515102a13000a5621ba3515905b5623ba151510005100b455505800000000340024965c116053c084dfc05c25d02843d03893d0010024002400340023ba5515105b00188c161510005000b455500000000000000000965c142411c06061c084edc05c33d02851d038a1d00100180018004c00188c56151000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")! + XCTAssertTrue(0x803a == computeCRC16(input)) + } +} diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index f64525d02..f8e8deb5f 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -150,6 +150,8 @@ C1EAD6DC1C82A4AB006DBA60 /* RFToolsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */; }; C1EAD6DE1C82B78C006DBA60 /* CRC8.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */; }; C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */; }; + C1EAD6E21C82BA7A006DBA60 /* CRC16.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */; }; + C1EAD6E41C82BA87006DBA60 /* CRC16Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */; }; C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */; }; C1EF58881B3F93FE001C8C80 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58871B3F93FE001C8C80 /* Config.m */; }; C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF588A1B3F9748001C8C80 /* SWRevealViewController.m */; }; @@ -450,6 +452,8 @@ C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RFToolsTests.swift; sourceTree = ""; }; C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC8.swift; sourceTree = ""; }; C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC8Tests.swift; sourceTree = ""; }; + C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC16.swift; sourceTree = ""; }; + C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC16Tests.swift; sourceTree = ""; }; C1EF58831B3E5DA4001C8C80 /* ConfigureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureViewController.h; sourceTree = ""; }; C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureViewController.m; sourceTree = ""; }; C1EF58861B3F93FE001C8C80 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; @@ -517,6 +521,7 @@ C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */, C1EAD6D91C829104006DBA60 /* RFTools.swift */, C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */, + C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */, ); path = MinimedKit; sourceTree = ""; @@ -531,6 +536,7 @@ C10D9BD31C8269D500378342 /* Info.plist */, C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */, C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */, + C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */, ); path = MinimedKitTests; sourceTree = ""; @@ -1149,6 +1155,7 @@ C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */, C1EAD6C61C826B92006DBA60 /* NSData.swift in Sources */, C1EAD6CC1C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift in Sources */, + C1EAD6E21C82BA7A006DBA60 /* CRC16.swift in Sources */, C1EAD6C71C826B92006DBA60 /* NSDateComponents.swift in Sources */, C1EAD6DA1C829104006DBA60 /* RFTools.swift in Sources */, C1EAD6B71C826B6D006DBA60 /* PumpMessage.swift in Sources */, @@ -1161,6 +1168,7 @@ files = ( C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */, C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */, + C1EAD6E41C82BA87006DBA60 /* CRC16Tests.swift in Sources */, C1EAD6D71C826C43006DBA60 /* NSDataTests.swift in Sources */, C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */, C1EAD6DC1C82A4AB006DBA60 /* RFToolsTests.swift in Sources */, From 815fba44fe1e43af6b92135dbee6b0967dfba4a3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 00:31:06 -0600 Subject: [PATCH 007/116] Suggestions per @loudnate --- MinimedKit/CRC16.swift | 4 ++-- MinimedKit/CRC8.swift | 3 ++- MinimedKit/RFTools.swift | 31 ++++++++++++++----------------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/MinimedKit/CRC16.swift b/MinimedKit/CRC16.swift index 596ae1f18..302523dd9 100644 --- a/MinimedKit/CRC16.swift +++ b/MinimedKit/CRC16.swift @@ -8,9 +8,9 @@ import Foundation +private let crcTable: [UInt16] = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302, 37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907, 9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789, 59790, 63919, 35144, 39273, 43274, 47403, 23285, 19156, 31415, 27286, 6769, 2640, 14899, 10770, 56317, 52188, 64447, 60318, 39801, 35672, 47931, 43802, 27814, 31879, 19684, 23749, 11298, 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395, 36200, 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 61374, 57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679, 33721, 37784, 41979, 46042, 49981, 54044, 58239, 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 1153, 29798, 25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068, 55628, 51565, 63758, 59695, 39368, 35305, 47498, 43435, 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801, 6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955, 49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920] + func computeCRC16(data: NSData) -> UInt16 { - - let crcTable: [UInt16] = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302, 37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907, 9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789, 59790, 63919, 35144, 39273, 43274, 47403, 23285, 19156, 31415, 27286, 6769, 2640, 14899, 10770, 56317, 52188, 64447, 60318, 39801, 35672, 47931, 43802, 27814, 31879, 19684, 23749, 11298, 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395, 36200, 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 61374, 57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679, 33721, 37784, 41979, 46042, 49981, 54044, 58239, 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 1153, 29798, 25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068, 55628, 51565, 63758, 59695, 39368, 35305, 47498, 43435, 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801, 6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955, 49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920] var crc: UInt16 = 0xffff var pdata = UnsafePointer(data.bytes) diff --git a/MinimedKit/CRC8.swift b/MinimedKit/CRC8.swift index f9a8fc656..772903422 100644 --- a/MinimedKit/CRC8.swift +++ b/MinimedKit/CRC8.swift @@ -8,9 +8,10 @@ import Foundation +private let crcTable: [UInt8] = [0x0, 0x9B, 0xAD, 0x36, 0xC1, 0x5A, 0x6C, 0xF7, 0x19, 0x82, 0xB4, 0x2F, 0xD8, 0x43, 0x75, 0xEE, 0x32, 0xA9, 0x9F, 0x4, 0xF3, 0x68, 0x5E, 0xC5, 0x2B, 0xB0, 0x86, 0x1D, 0xEA, 0x71, 0x47, 0xDC, 0x64, 0xFF, 0xC9, 0x52, 0xA5, 0x3E, 0x8, 0x93, 0x7D, 0xE6, 0xD0, 0x4B, 0xBC, 0x27, 0x11, 0x8A, 0x56, 0xCD, 0xFB, 0x60, 0x97, 0xC, 0x3A, 0xA1, 0x4F, 0xD4, 0xE2, 0x79, 0x8E, 0x15, 0x23, 0xB8, 0xC8, 0x53, 0x65, 0xFE, 0x9, 0x92, 0xA4, 0x3F, 0xD1, 0x4A, 0x7C, 0xE7, 0x10, 0x8B, 0xBD, 0x26, 0xFA, 0x61, 0x57, 0xCC, 0x3B, 0xA0, 0x96, 0xD, 0xE3, 0x78, 0x4E, 0xD5, 0x22, 0xB9, 0x8F, 0x14, 0xAC, 0x37, 0x1, 0x9A, 0x6D, 0xF6, 0xC0, 0x5B, 0xB5, 0x2E, 0x18, 0x83, 0x74, 0xEF, 0xD9, 0x42, 0x9E, 0x5, 0x33, 0xA8, 0x5F, 0xC4, 0xF2, 0x69, 0x87, 0x1C, 0x2A, 0xB1, 0x46, 0xDD, 0xEB, 0x70, 0xB, 0x90, 0xA6, 0x3D, 0xCA, 0x51, 0x67, 0xFC, 0x12, 0x89, 0xBF, 0x24, 0xD3, 0x48, 0x7E, 0xE5, 0x39, 0xA2, 0x94, 0xF, 0xF8, 0x63, 0x55, 0xCE, 0x20, 0xBB, 0x8D, 0x16, 0xE1, 0x7A, 0x4C, 0xD7, 0x6F, 0xF4, 0xC2, 0x59, 0xAE, 0x35, 0x3, 0x98, 0x76, 0xED, 0xDB, 0x40, 0xB7, 0x2C, 0x1A, 0x81, 0x5D, 0xC6, 0xF0, 0x6B, 0x9C, 0x7, 0x31, 0xAA, 0x44, 0xDF, 0xE9, 0x72, 0x85, 0x1E, 0x28, 0xB3, 0xC3, 0x58, 0x6E, 0xF5, 0x2, 0x99, 0xAF, 0x34, 0xDA, 0x41, 0x77, 0xEC, 0x1B, 0x80, 0xB6, 0x2D, 0xF1, 0x6A, 0x5C, 0xC7, 0x30, 0xAB, 0x9D, 0x6, 0xE8, 0x73, 0x45, 0xDE, 0x29, 0xB2, 0x84, 0x1F, 0xA7, 0x3C, 0xA, 0x91, 0x66, 0xFD, 0xCB, 0x50, 0xBE, 0x25, 0x13, 0x88, 0x7F, 0xE4, 0xD2, 0x49, 0x95, 0xE, 0x38, 0xA3, 0x54, 0xCF, 0xF9, 0x62, 0x8C, 0x17, 0x21, 0xBA, 0x4D, 0xD6, 0xE0, 0x7B] + func computeCRC8(data: NSData) -> UInt8 { - let crcTable: [UInt8] = [0x0, 0x9B, 0xAD, 0x36, 0xC1, 0x5A, 0x6C, 0xF7, 0x19, 0x82, 0xB4, 0x2F, 0xD8, 0x43, 0x75, 0xEE, 0x32, 0xA9, 0x9F, 0x4, 0xF3, 0x68, 0x5E, 0xC5, 0x2B, 0xB0, 0x86, 0x1D, 0xEA, 0x71, 0x47, 0xDC, 0x64, 0xFF, 0xC9, 0x52, 0xA5, 0x3E, 0x8, 0x93, 0x7D, 0xE6, 0xD0, 0x4B, 0xBC, 0x27, 0x11, 0x8A, 0x56, 0xCD, 0xFB, 0x60, 0x97, 0xC, 0x3A, 0xA1, 0x4F, 0xD4, 0xE2, 0x79, 0x8E, 0x15, 0x23, 0xB8, 0xC8, 0x53, 0x65, 0xFE, 0x9, 0x92, 0xA4, 0x3F, 0xD1, 0x4A, 0x7C, 0xE7, 0x10, 0x8B, 0xBD, 0x26, 0xFA, 0x61, 0x57, 0xCC, 0x3B, 0xA0, 0x96, 0xD, 0xE3, 0x78, 0x4E, 0xD5, 0x22, 0xB9, 0x8F, 0x14, 0xAC, 0x37, 0x1, 0x9A, 0x6D, 0xF6, 0xC0, 0x5B, 0xB5, 0x2E, 0x18, 0x83, 0x74, 0xEF, 0xD9, 0x42, 0x9E, 0x5, 0x33, 0xA8, 0x5F, 0xC4, 0xF2, 0x69, 0x87, 0x1C, 0x2A, 0xB1, 0x46, 0xDD, 0xEB, 0x70, 0xB, 0x90, 0xA6, 0x3D, 0xCA, 0x51, 0x67, 0xFC, 0x12, 0x89, 0xBF, 0x24, 0xD3, 0x48, 0x7E, 0xE5, 0x39, 0xA2, 0x94, 0xF, 0xF8, 0x63, 0x55, 0xCE, 0x20, 0xBB, 0x8D, 0x16, 0xE1, 0x7A, 0x4C, 0xD7, 0x6F, 0xF4, 0xC2, 0x59, 0xAE, 0x35, 0x3, 0x98, 0x76, 0xED, 0xDB, 0x40, 0xB7, 0x2C, 0x1A, 0x81, 0x5D, 0xC6, 0xF0, 0x6B, 0x9C, 0x7, 0x31, 0xAA, 0x44, 0xDF, 0xE9, 0x72, 0x85, 0x1E, 0x28, 0xB3, 0xC3, 0x58, 0x6E, 0xF5, 0x2, 0x99, 0xAF, 0x34, 0xDA, 0x41, 0x77, 0xEC, 0x1B, 0x80, 0xB6, 0x2D, 0xF1, 0x6A, 0x5C, 0xC7, 0x30, 0xAB, 0x9D, 0x6, 0xE8, 0x73, 0x45, 0xDE, 0x29, 0xB2, 0x84, 0x1F, 0xA7, 0x3C, 0xA, 0x91, 0x66, 0xFD, 0xCB, 0x50, 0xBE, 0x25, 0x13, 0x88, 0x7F, 0xE4, 0xD2, 0x49, 0x95, 0xE, 0x38, 0xA3, 0x54, 0xCF, 0xF9, 0x62, 0x8C, 0x17, 0x21, 0xBA, 0x4D, 0xD6, 0xE0, 0x7B] var crc: UInt8 = 0 diff --git a/MinimedKit/RFTools.swift b/MinimedKit/RFTools.swift index fcbd3630b..b27f89642 100644 --- a/MinimedKit/RFTools.swift +++ b/MinimedKit/RFTools.swift @@ -11,24 +11,21 @@ import Foundation func decode4b6b(rawData: NSData) -> NSData? { let codes:Dictionary = [21: 0, 49: 1, 50: 2, 35: 3, 52: 4, 37: 5, 38: 6, 22: 7, 26: 8, 25: 9, 42: 10, 11: 11, 44: 12, 13: 13, 14: 14, 28: 15] var buffer = [UInt8]() - let bytes = UnsafeBufferPointer(start:UnsafePointer(rawData.bytes), count:rawData.length) + let bytes: [UInt8] = rawData[0..= 12 { - hiNibble = codes[x >> (availBits - 6)] - loNibble = codes[(x >> (availBits - 12)) & 0b111111] - - if hiNibble != nil && loNibble != nil { - let decoded: UInt8 = UInt8((hiNibble! << 4) + loNibble!) - buffer.append(decoded) - } else { + guard let + hiNibble = codes[x >> (availBits - 6)], + loNibble = codes[(x >> (availBits - 12)) & 0b111111] + else { return nil } + let decoded: UInt8 = UInt8((hiNibble << 4) + loNibble) + buffer.append(decoded) availBits -= 12; x = x & (0xffff >> (16-availBits)); } @@ -39,16 +36,16 @@ func decode4b6b(rawData: NSData) -> NSData? { func encode4b6b(rawData: NSData) -> NSData { var buffer = [UInt8]() let codes: [UInt] = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] - let bytes = UnsafeBufferPointer(start:UnsafePointer(rawData.bytes), count:rawData.length) + let bytes: [UInt8] = rawData[0..> 4)] + acc |= codes[Int(byte >> 4)] bitcount += 6; acc <<= 6; - acc |= codes[Int(bytes[i] & 0x0f)]; + acc |= codes[Int(byte & 0x0f)]; bitcount += 6; while bitcount >= 8 { @@ -57,7 +54,7 @@ func encode4b6b(rawData: NSData) -> NSData { acc &= (0xffff >> (16-bitcount)); } } - if (bitcount > 0) { + if bitcount > 0 { acc <<= (8-bitcount); buffer.append(UInt8(acc) & 0xff); } From 28ce86ba7d9e30f05bcb82f992f481b9434280a3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 00:34:00 -0600 Subject: [PATCH 008/116] more cleanup --- MinimedKit/RFTools.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MinimedKit/RFTools.swift b/MinimedKit/RFTools.swift index b27f89642..21ffeed6f 100644 --- a/MinimedKit/RFTools.swift +++ b/MinimedKit/RFTools.swift @@ -24,7 +24,7 @@ func decode4b6b(rawData: NSData) -> NSData? { else { return nil } - let decoded: UInt8 = UInt8((hiNibble << 4) + loNibble) + let decoded = UInt8((hiNibble << 4) + loNibble) buffer.append(decoded) availBits -= 12; x = x & (0xffff >> (16-availBits)); @@ -35,10 +35,10 @@ func decode4b6b(rawData: NSData) -> NSData? { func encode4b6b(rawData: NSData) -> NSData { var buffer = [UInt8]() - let codes: [UInt] = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] + let codes: [Int] = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] let bytes: [UInt8] = rawData[0..> 4)] From 8e5a8c950932ef0a303dad277ba5830859f1ae06 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 00:40:29 -0600 Subject: [PATCH 009/116] More cleanup --- MinimedKit/CRC16.swift | 4 ++-- MinimedKit/CRC8.swift | 6 +++--- MinimedKit/RFTools.swift | 38 ++++++++++++++++++++------------------ 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/MinimedKit/CRC16.swift b/MinimedKit/CRC16.swift index 302523dd9..d66d8dce0 100644 --- a/MinimedKit/CRC16.swift +++ b/MinimedKit/CRC16.swift @@ -18,8 +18,8 @@ func computeCRC16(data: NSData) -> UInt16 { /* loop over the buffer data */ while nbytes-- > 0 { let idx = ((crc >> 8) ^ UInt16(pdata.memory)) & 0xff - crc = ((crc << 8) ^ crcTable[Int(idx)]) & 0xffff; + crc = ((crc << 8) ^ crcTable[Int(idx)]) & 0xffff pdata++ } - return crc; + return crc } diff --git a/MinimedKit/CRC8.swift b/MinimedKit/CRC8.swift index 772903422..2bebbd775 100644 --- a/MinimedKit/CRC8.swift +++ b/MinimedKit/CRC8.swift @@ -19,9 +19,9 @@ func computeCRC8(data: NSData) -> UInt8 { var nbytes = data.length /* loop over the buffer data */ while nbytes-- > 0 { - crc = crcTable[Int((crc ^ pdata.memory) & 0xff)]; - pdata++; + crc = crcTable[Int((crc ^ pdata.memory) & 0xff)] + pdata++ } - return crc; + return crc } diff --git a/MinimedKit/RFTools.swift b/MinimedKit/RFTools.swift index 21ffeed6f..dabc85e7f 100644 --- a/MinimedKit/RFTools.swift +++ b/MinimedKit/RFTools.swift @@ -8,26 +8,29 @@ import Foundation +private let codesRev:Dictionary = [21: 0, 49: 1, 50: 2, 35: 3, 52: 4, 37: 5, 38: 6, 22: 7, 26: 8, 25: 9, 42: 10, 11: 11, 44: 12, 13: 13, 14: 14, 28: 15] + +private let codes = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] + func decode4b6b(rawData: NSData) -> NSData? { - let codes:Dictionary = [21: 0, 49: 1, 50: 2, 35: 3, 52: 4, 37: 5, 38: 6, 22: 7, 26: 8, 25: 9, 42: 10, 11: 11, 44: 12, 13: 13, 14: 14, 28: 15] var buffer = [UInt8]() let bytes: [UInt8] = rawData[0..= 12 { guard let - hiNibble = codes[x >> (availBits - 6)], - loNibble = codes[(x >> (availBits - 12)) & 0b111111] + hiNibble = codesRev[x >> (availBits - 6)], + loNibble = codesRev[(x >> (availBits - 12)) & 0b111111] else { return nil } let decoded = UInt8((hiNibble << 4) + loNibble) buffer.append(decoded) - availBits -= 12; - x = x & (0xffff >> (16-availBits)); + availBits -= 12 + x = x & (0xffff >> (16-availBits)) } } return NSData(bytes: &buffer, length: buffer.count) @@ -35,28 +38,27 @@ func decode4b6b(rawData: NSData) -> NSData? { func encode4b6b(rawData: NSData) -> NSData { var buffer = [UInt8]() - let codes: [Int] = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] let bytes: [UInt8] = rawData[0..> 4)] - bitcount += 6; + bitcount += 6 - acc <<= 6; - acc |= codes[Int(byte & 0x0f)]; - bitcount += 6; + acc <<= 6 + acc |= codes[Int(byte & 0x0f)] + bitcount += 6 while bitcount >= 8 { buffer.append(UInt8(acc >> (bitcount-8)) & 0xff) - bitcount -= 8; - acc &= (0xffff >> (16-bitcount)); + bitcount -= 8 + acc &= (0xffff >> (16-bitcount)) } } if bitcount > 0 { - acc <<= (8-bitcount); - buffer.append(UInt8(acc) & 0xff); + acc <<= (8-bitcount) + buffer.append(UInt8(acc) & 0xff) } return NSData(bytes: &buffer, length: buffer.count) } From c66f72fb94d3f71c6295668c97e93df504263825 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 21:16:00 -0600 Subject: [PATCH 010/116] wip --- MinimedKitTests/PumpMessageTests.swift | 25 +++ RileyLink.xcodeproj/project.pbxproj | 36 ++-- RileyLink/CRC16.h | 15 -- RileyLink/CRC16.m | 27 --- RileyLink/CRC8.h | 15 -- RileyLink/CRC8.m | 29 ---- RileyLink/MessageBase.h | 25 ++- RileyLink/MinimedPacket.h | 54 ------ RileyLink/MinimedPacket.m | 192 ---------------------- RileyLink/MySentryPairingViewController.m | 3 +- RileyLink/PacketGeneratorViewController.m | 14 +- RileyLink/PacketLogViewController.m | 13 +- RileyLink/PacketTableViewCell.h | 4 +- RileyLink/PacketTableViewCell.m | 5 +- RileyLink/PumpChatViewController.m | 1 - RileyLink/RFPacket.h | 21 +++ RileyLink/RFPacket.m | 42 +++++ RileyLink/RileyLinkBLEDevice.h | 2 - RileyLink/RileyLinkBLEDevice.m | 11 +- 19 files changed, 148 insertions(+), 386 deletions(-) create mode 100644 MinimedKitTests/PumpMessageTests.swift delete mode 100644 RileyLink/CRC16.h delete mode 100644 RileyLink/CRC16.m delete mode 100644 RileyLink/CRC8.h delete mode 100644 RileyLink/CRC8.m delete mode 100644 RileyLink/MinimedPacket.h delete mode 100644 RileyLink/MinimedPacket.m create mode 100644 RileyLink/RFPacket.h create mode 100644 RileyLink/RFPacket.m diff --git a/MinimedKitTests/PumpMessageTests.swift b/MinimedKitTests/PumpMessageTests.swift new file mode 100644 index 000000000..4ba4f2035 --- /dev/null +++ b/MinimedKitTests/PumpMessageTests.swift @@ -0,0 +1,25 @@ +// +// PumpMessageTests.swift +// RileyLink +// +// Created by Pete Schwamb on 2/28/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import XCTest +@testable import MinimedKit + + +class PumpMessageTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + +} diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index f8e8deb5f..4c9ad6af3 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -51,8 +51,6 @@ C12EA260198B436900309FA4 /* RileyLinkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C12EA25F198B436900309FA4 /* RileyLinkTests.m */; }; C12EA26A198B442100309FA4 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C12EA269198B442100309FA4 /* Storyboard.storyboard */; }; C12EA26D198B456D00309FA4 /* NightscoutWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12EA26C198B456D00309FA4 /* NightscoutWebView.m */; }; - C137A3901C08114600569851 /* CRC8.m in Sources */ = {isa = PBXBuildFile; fileRef = C137A38F1C08114600569851 /* CRC8.m */; }; - C137A3931C08142E00569851 /* CRC16.m in Sources */ = {isa = PBXBuildFile; fileRef = C137A3921C08142E00569851 /* CRC16.m */; }; C137A3961C08A35C00569851 /* NightScoutBolus.m in Sources */ = {isa = PBXBuildFile; fileRef = C137A3951C08A35C00569851 /* NightScoutBolus.m */; }; C137A39C1C08A48100569851 /* NightScoutPump.m in Sources */ = {isa = PBXBuildFile; fileRef = C137A39B1C08A48100569851 /* NightScoutPump.m */; }; C139AB911BFD6A9000B0518F /* PumpHistoryEventBase.m in Sources */ = {isa = PBXBuildFile; fileRef = C139AB901BFD6A9000B0518F /* PumpHistoryEventBase.m */; }; @@ -125,7 +123,6 @@ C1D2B6811C30AAE000DB4AEA /* SendPacketCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = C1D2B6801C30AAE000DB4AEA /* SendPacketCmd.m */; }; C1E535EA1991E36700C2AC49 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535E91991E36700C2AC49 /* NSData+Conversion.m */; }; C1E535ED1991E49600C2AC49 /* RileyLinkBLEManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535EC1991E49600C2AC49 /* RileyLinkBLEManager.m */; }; - C1E535F01991E6A200C2AC49 /* MinimedPacket.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535EF1991E6A200C2AC49 /* MinimedPacket.m */; }; C1EAD6B31C826B6D006DBA60 /* AlertType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */; }; C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */; }; C1EAD6B51C826B6D006DBA60 /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B01C826B6D006DBA60 /* MessageType.swift */; }; @@ -152,6 +149,8 @@ C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */; }; C1EAD6E21C82BA7A006DBA60 /* CRC16.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */; }; C1EAD6E41C82BA87006DBA60 /* CRC16Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */; }; + C1EAD6E61C83966D006DBA60 /* PumpMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E51C83966D006DBA60 /* PumpMessageTests.swift */; }; + C1EAD6E91C83E121006DBA60 /* RFPacket.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E81C83E121006DBA60 /* RFPacket.m */; }; C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */; }; C1EF58881B3F93FE001C8C80 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58871B3F93FE001C8C80 /* Config.m */; }; C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF588A1B3F9748001C8C80 /* SWRevealViewController.m */; }; @@ -278,10 +277,6 @@ C12EA269198B442100309FA4 /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; C12EA26B198B456D00309FA4 /* NightscoutWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NightscoutWebView.h; sourceTree = ""; }; C12EA26C198B456D00309FA4 /* NightscoutWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NightscoutWebView.m; sourceTree = ""; }; - C137A38E1C08114600569851 /* CRC8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRC8.h; sourceTree = ""; }; - C137A38F1C08114600569851 /* CRC8.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CRC8.m; sourceTree = ""; }; - C137A3911C08142E00569851 /* CRC16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRC16.h; sourceTree = ""; }; - C137A3921C08142E00569851 /* CRC16.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CRC16.m; sourceTree = ""; }; C137A3941C08A35C00569851 /* NightScoutBolus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NightScoutBolus.h; sourceTree = ""; }; C137A3951C08A35C00569851 /* NightScoutBolus.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.objc; path = NightScoutBolus.m; sourceTree = ""; }; C137A39A1C08A48100569851 /* NightScoutPump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NightScoutPump.h; sourceTree = ""; }; @@ -426,8 +421,6 @@ C1E535E91991E36700C2AC49 /* NSData+Conversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Conversion.m"; sourceTree = ""; }; C1E535EB1991E49600C2AC49 /* RileyLinkBLEManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RileyLinkBLEManager.h; sourceTree = ""; }; C1E535EC1991E49600C2AC49 /* RileyLinkBLEManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RileyLinkBLEManager.m; sourceTree = ""; }; - C1E535EE1991E6A200C2AC49 /* MinimedPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MinimedPacket.h; sourceTree = ""; }; - C1E535EF1991E6A200C2AC49 /* MinimedPacket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MinimedPacket.m; sourceTree = ""; }; C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertType.swift; sourceTree = ""; }; C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageBody.swift; sourceTree = ""; }; C1EAD6B01C826B6D006DBA60 /* MessageType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageType.swift; sourceTree = ""; }; @@ -454,6 +447,9 @@ C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC8Tests.swift; sourceTree = ""; }; C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC16.swift; sourceTree = ""; }; C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC16Tests.swift; sourceTree = ""; }; + C1EAD6E51C83966D006DBA60 /* PumpMessageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpMessageTests.swift; sourceTree = ""; }; + C1EAD6E71C83E121006DBA60 /* RFPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFPacket.h; sourceTree = ""; }; + C1EAD6E81C83E121006DBA60 /* RFPacket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RFPacket.m; sourceTree = ""; }; C1EF58831B3E5DA4001C8C80 /* ConfigureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureViewController.h; sourceTree = ""; }; C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureViewController.m; sourceTree = ""; }; C1EF58861B3F93FE001C8C80 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; @@ -537,6 +533,7 @@ C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */, C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */, C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */, + C1EAD6E51C83966D006DBA60 /* PumpMessageTests.swift */, ); path = MinimedKitTests; sourceTree = ""; @@ -592,19 +589,6 @@ path = TPKeyboardAvoiding; sourceTree = ""; }; - C12964E91B1581D200516761 /* MinimedRF */ = { - isa = PBXGroup; - children = ( - C1E535EE1991E6A200C2AC49 /* MinimedPacket.h */, - C1E535EF1991E6A200C2AC49 /* MinimedPacket.m */, - C137A38E1C08114600569851 /* CRC8.h */, - C137A38F1C08114600569851 /* CRC8.m */, - C137A3911C08142E00569851 /* CRC16.h */, - C137A3921C08142E00569851 /* CRC16.m */, - ); - name = MinimedRF; - sourceTree = ""; - }; C12EA22E198B436800309FA4 = { isa = PBXGroup; children = ( @@ -651,7 +635,6 @@ C1EF58981B3FA7D1001C8C80 /* RileyLink */, C1EF58891B3F9730001C8C80 /* SWRevealViewController */, C14B4EDF1B85A31F00776647 /* MinimedProtocol */, - C12964E91B1581D200516761 /* MinimedRF */, C1AA398B1AB67F6A00BC9E33 /* Categories */, C174F26919EB824D00398C72 /* ISO8601DateFormatter.h */, C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */, @@ -904,6 +887,8 @@ C10A62911C55F8E200E635EE /* UpdateRegisterCmd.m */, C10EAA9B1C5AE9A600B0838F /* GetVersionCmd.h */, C10EAA9C1C5AE9A600B0838F /* GetVersionCmd.m */, + C1EAD6E71C83E121006DBA60 /* RFPacket.h */, + C1EAD6E81C83E121006DBA60 /* RFPacket.m */, ); name = RileyLink; sourceTree = ""; @@ -1169,6 +1154,7 @@ C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */, C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */, C1EAD6E41C82BA87006DBA60 /* CRC16Tests.swift in Sources */, + C1EAD6E61C83966D006DBA60 /* PumpMessageTests.swift in Sources */, C1EAD6D71C826C43006DBA60 /* NSDataTests.swift in Sources */, C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */, C1EAD6DC1C82A4AB006DBA60 /* RFToolsTests.swift in Sources */, @@ -1217,7 +1203,7 @@ C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, C139AC991BFD8CF800B0518F /* PHEChangeParadigmLinkID.m in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, - C1E535F01991E6A200C2AC49 /* MinimedPacket.m in Sources */, + C1EAD6E91C83E121006DBA60 /* RFPacket.m in Sources */, C139ACBB1C00046D00B0518F /* PHEBolusWizardBolusEstimate.m in Sources */, C139ACA31BFD8CF800B0518F /* PHEDeleteAlarmClockTime.m in Sources */, C139AC961BFD8CF800B0518F /* PHEChangeCarbUnits.m in Sources */, @@ -1233,9 +1219,7 @@ C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, C139AC8F1BFD8CF800B0518F /* PHEChangeBGReminderEnable.m in Sources */, C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */, - C137A3931C08142E00569851 /* CRC16.m in Sources */, C139AC911BFD8CF800B0518F /* PHEChangeBolusReminderEnable.m in Sources */, - C137A3901C08114600569851 /* CRC8.m in Sources */, C12616571B6A6130001FAD87 /* PacketLogViewController.m in Sources */, C14AA33B1B1A2FB100299A55 /* MeterMessage.m in Sources */, C139AC941BFD8CF800B0518F /* PHEChangeBolusWizardSetup.m in Sources */, diff --git a/RileyLink/CRC16.h b/RileyLink/CRC16.h deleted file mode 100644 index 1f21b6875..000000000 --- a/RileyLink/CRC16.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// CRC16.h -// RileyLink -// -// Created by Pete Schwamb on 11/26/15. -// Copyright © 2015 Pete Schwamb. All rights reserved. -// - -#import - -@interface CRC16 : NSObject - -+ (uint16_t) compute:(NSData*)data; - -@end diff --git a/RileyLink/CRC16.m b/RileyLink/CRC16.m deleted file mode 100644 index 5277ffcbe..000000000 --- a/RileyLink/CRC16.m +++ /dev/null @@ -1,27 +0,0 @@ -// -// CRC16.m -// RileyLink -// -// Created by Pete Schwamb on 11/26/15. -// Copyright © 2015 Pete Schwamb. All rights reserved. -// - -#import "CRC16.h" - -@implementation CRC16 - -static const uint16_t crcTable[256] = { 0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302, 37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907, 9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789, 59790, 63919, 35144, 39273, 43274, 47403, 23285, 19156, 31415, 27286, 6769, 2640, 14899, 10770, 56317, 52188, 64447, 60318, 39801, 35672, 47931, 43802, 27814, 31879, 19684, 23749, 11298, 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395, 36200, 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 61374, 57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679, 33721, 37784, 41979, 46042, 49981, 54044, 58239, 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 1153, 29798, 25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068, 55628, 51565, 63758, 59695, 39368, 35305, 47498, 43435, 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801, 6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955, 49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920 }; - - -+ (uint16_t) compute:(NSData*)data { - uint16_t crc = 0xffff; - const uint8_t *pdata = data.bytes; - unsigned long nbytes = data.length; - /* loop over the buffer data */ - while (nbytes-- > 0) { - crc = ((crc << 8) ^ crcTable[((crc >> 8) ^ *pdata++) & 0xff]) & 0xffff; - } - return crc; -} - -@end diff --git a/RileyLink/CRC8.h b/RileyLink/CRC8.h deleted file mode 100644 index e28fbeab1..000000000 --- a/RileyLink/CRC8.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// CRC8.h -// RileyLink -// -// Created by Pete Schwamb on 11/26/15. -// Copyright © 2015 Pete Schwamb. All rights reserved. -// - -#import - -@interface CRC8 : NSObject - -+ (uint8_t) compute:(NSData*)data; - -@end diff --git a/RileyLink/CRC8.m b/RileyLink/CRC8.m deleted file mode 100644 index f7ab3ba99..000000000 --- a/RileyLink/CRC8.m +++ /dev/null @@ -1,29 +0,0 @@ -// -// CRC8.m -// RileyLink -// -// Created by Pete Schwamb on 11/26/15. -// Copyright © 2015 Pete Schwamb. All rights reserved. -// - -#import "CRC8.h" - -@implementation CRC8 - -static const unsigned char crcTable[256] = { 0x0, 0x9B, 0xAD, 0x36, 0xC1, 0x5A, 0x6C, 0xF7, 0x19, 0x82, 0xB4, 0x2F, 0xD8, 0x43, 0x75, 0xEE, 0x32, 0xA9, 0x9F, 0x4, 0xF3, 0x68, 0x5E, 0xC5, 0x2B, 0xB0, 0x86, 0x1D, 0xEA, 0x71, 0x47, 0xDC, 0x64, 0xFF, 0xC9, 0x52, 0xA5, 0x3E, 0x8, 0x93, 0x7D, 0xE6, 0xD0, 0x4B, 0xBC, 0x27, 0x11, 0x8A, 0x56, 0xCD, 0xFB, 0x60, 0x97, 0xC, 0x3A, 0xA1, 0x4F, 0xD4, 0xE2, 0x79, 0x8E, 0x15, 0x23, 0xB8, 0xC8, 0x53, 0x65, 0xFE, 0x9, 0x92, 0xA4, 0x3F, 0xD1, 0x4A, 0x7C, 0xE7, 0x10, 0x8B, 0xBD, 0x26, 0xFA, 0x61, 0x57, 0xCC, 0x3B, 0xA0, 0x96, 0xD, 0xE3, 0x78, 0x4E, 0xD5, 0x22, 0xB9, 0x8F, 0x14, 0xAC, 0x37, 0x1, 0x9A, 0x6D, 0xF6, 0xC0, 0x5B, 0xB5, 0x2E, 0x18, 0x83, 0x74, 0xEF, 0xD9, 0x42, 0x9E, 0x5, 0x33, 0xA8, 0x5F, 0xC4, 0xF2, 0x69, 0x87, 0x1C, 0x2A, 0xB1, 0x46, 0xDD, 0xEB, 0x70, 0xB, 0x90, 0xA6, 0x3D, 0xCA, 0x51, 0x67, 0xFC, 0x12, 0x89, 0xBF, 0x24, 0xD3, 0x48, 0x7E, 0xE5, 0x39, 0xA2, 0x94, 0xF, 0xF8, 0x63, 0x55, 0xCE, 0x20, 0xBB, 0x8D, 0x16, 0xE1, 0x7A, 0x4C, 0xD7, 0x6F, 0xF4, 0xC2, 0x59, 0xAE, 0x35, 0x3, 0x98, 0x76, 0xED, 0xDB, 0x40, 0xB7, 0x2C, 0x1A, 0x81, 0x5D, 0xC6, 0xF0, 0x6B, 0x9C, 0x7, 0x31, 0xAA, 0x44, 0xDF, 0xE9, 0x72, 0x85, 0x1E, 0x28, 0xB3, 0xC3, 0x58, 0x6E, 0xF5, 0x2, 0x99, 0xAF, 0x34, 0xDA, 0x41, 0x77, 0xEC, 0x1B, 0x80, 0xB6, 0x2D, 0xF1, 0x6A, 0x5C, 0xC7, 0x30, 0xAB, 0x9D, 0x6, 0xE8, 0x73, 0x45, 0xDE, 0x29, 0xB2, 0x84, 0x1F, 0xA7, 0x3C, 0xA, 0x91, 0x66, 0xFD, 0xCB, 0x50, 0xBE, 0x25, 0x13, 0x88, 0x7F, 0xE4, 0xD2, 0x49, 0x95, 0xE, 0x38, 0xA3, 0x54, 0xCF, 0xF9, 0x62, 0x8C, 0x17, 0x21, 0xBA, 0x4D, 0xD6, 0xE0, 0x7B }; - - -+ (uint8_t) compute:(NSData*)data { - uint8_t crc = 0; - const uint8_t *pdata = data.bytes; - unsigned long nbytes = data.length; - /* loop over the buffer data */ - while (nbytes-- > 0) { - crc = crcTable[(crc ^ *pdata++) & 0xff]; - } - return crc; -} - - - -@end diff --git a/RileyLink/MessageBase.h b/RileyLink/MessageBase.h index 26b131c0e..8983d55b1 100644 --- a/RileyLink/MessageBase.h +++ b/RileyLink/MessageBase.h @@ -7,10 +7,33 @@ // #import -#import "MinimedPacket.h" @interface MessageBase : NSObject +typedef NS_ENUM(unsigned char, PacketType) { + PacketTypeSentry = 0xa2, + PacketTypeMeter = 0xa5, + PacketTypeCarelink = 0xa7, + PacketTypeSensor = 0xa8 +}; + +typedef NS_ENUM(unsigned char, MessageType) { + MESSAGE_TYPE_ALERT = 0x01, + MESSAGE_TYPE_ALERT_CLEARED = 0x02, + MESSAGE_TYPE_DEVICE_TEST = 0x03, + MESSAGE_TYPE_PUMP_STATUS = 0x04, + MESSAGE_TYPE_ACK = 0x06, + MESSAGE_TYPE_PUMP_BACKFILL = 0x08, + MESSAGE_TYPE_FIND_DEVICE = 0x09, + MESSAGE_TYPE_DEVICE_LINK = 0x0a, + MESSAGE_TYPE_PUMP_DUMP = 0x0a, + MESSAGE_TYPE_POWER = 0x5d, + MESSAGE_TYPE_BUTTON_PRESS = 0x5b, + MESSAGE_TYPE_GET_PUMP_MODEL = 0x8d, + MESSAGE_TYPE_GET_BATTERY = 0x72, + MESSAGE_TYPE_READ_HISTORY = 0x80, +}; + @property (nonatomic, nonnull, readonly, strong) NSData *data; - (nonnull instancetype)initWithData:(nonnull NSData*)data NS_DESIGNATED_INITIALIZER; diff --git a/RileyLink/MinimedPacket.h b/RileyLink/MinimedPacket.h deleted file mode 100644 index c3e398e02..000000000 --- a/RileyLink/MinimedPacket.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// MinimedPacket.h -// GlucoseLink -// -// Created by Pete Schwamb on 8/5/14. -// Copyright (c) 2014 Pete Schwamb. All rights reserved. -// - -#import - -@class MessageBase; - -@interface MinimedPacket : NSObject - -typedef NS_ENUM(unsigned char, PacketType) { - PacketTypeSentry = 0xa2, - PacketTypeMeter = 0xa5, - PacketTypeCarelink = 0xa7, - PacketTypeSensor = 0xa8 -}; - -typedef NS_ENUM(unsigned char, MessageType) { - MESSAGE_TYPE_ALERT = 0x01, - MESSAGE_TYPE_ALERT_CLEARED = 0x02, - MESSAGE_TYPE_DEVICE_TEST = 0x03, - MESSAGE_TYPE_PUMP_STATUS = 0x04, - MESSAGE_TYPE_ACK = 0x06, - MESSAGE_TYPE_PUMP_BACKFILL = 0x08, - MESSAGE_TYPE_FIND_DEVICE = 0x09, - MESSAGE_TYPE_DEVICE_LINK = 0x0a, - MESSAGE_TYPE_PUMP_DUMP = 0x0a, - MESSAGE_TYPE_POWER = 0x5d, - MESSAGE_TYPE_BUTTON_PRESS = 0x5b, - MESSAGE_TYPE_GET_PUMP_MODEL = 0x8d, - MESSAGE_TYPE_GET_BATTERY = 0x72, - MESSAGE_TYPE_READ_HISTORY = 0x80, -}; - -@property (NS_NONATOMIC_IOSONLY, readonly, strong) MessageBase * _Nullable toMessage; - -- (nonnull instancetype)initWithData:(nonnull NSData*)data NS_DESIGNATED_INITIALIZER; -@property (nonatomic, getter=isValid, readonly) BOOL valid; -@property (nonatomic, nullable, readonly, copy) NSString *hexadecimalString; -@property (nonatomic, readonly) PacketType packetType; -@property (nonatomic, readonly) MessageType messageType; -@property (nonatomic, nonnull, readonly, copy) NSString *address; -+ (nonnull NSData*)encodeData:(nonnull NSData*)data; - -@property (nonatomic, nullable, strong) NSData *data; -@property (nonatomic, nullable, strong) NSDate *capturedAt; -@property (nonatomic, assign) int rssi; -@property (nonatomic, assign) int packetNumber; - -@end diff --git a/RileyLink/MinimedPacket.m b/RileyLink/MinimedPacket.m deleted file mode 100644 index fe2a1d511..000000000 --- a/RileyLink/MinimedPacket.m +++ /dev/null @@ -1,192 +0,0 @@ -// -// MinimedPacket.m -// GlucoseLink -// -// Created by Pete Schwamb on 8/5/14. -// Copyright (c) 2014 Pete Schwamb. All rights reserved. -// - -#import "MinimedPacket.h" -#import "NSData+Conversion.h" -#import "CRC8.h" -#import "PumpStatusMessage.h" -#import "DeviceLinkMessage.h" -#import "FindDeviceMessage.h" -#import "MeterMessage.h" - - -@interface MinimedPacket () - -@property (nonatomic, assign) NSInteger codingErrorCount; - -@end - -@implementation MinimedPacket - -+ (void)initialize { -} - -- (instancetype)init NS_UNAVAILABLE -{ - return nil; -} - -- (instancetype)initWithData:(NSData*)data -{ - self = [super init]; - if (self) { - _codingErrorCount = 0; - if (data.length > 0) { - unsigned char rssiDec = ((const unsigned char*)data.bytes)[0]; - unsigned char rssiOffset = 73; - if (rssiDec >= 128) { - self.rssi = (short)((short)( rssiDec - 256) / 2) - rssiOffset; - } else { - self.rssi = (rssiDec / 2) - rssiOffset; - } - } - if (data.length > 1) { - self.packetNumber = ((const unsigned char*)data.bytes)[1]; - } - - if (data.length > 2) { - _data = [self decodeRF:[data subdataWithRange:NSMakeRange(2, data.length - 2)]]; - } - } - return self; -} - - -- (BOOL) crcValid { - if (_data.length < 2) { - return NO; - } - uint8_t packetCrc = ((uint8_t*)_data.bytes)[_data.length-1]; - uint8_t crc = [CRC8 compute:[_data subdataWithRange:NSMakeRange(0, _data.length-1)]]; - return crc == packetCrc; -} - -- (BOOL) isValid { - return _data.length > 0 && [self crcValid]; -} - -+ (NSData*)encodeData:(NSData*)data { - NSMutableData *outData = [NSMutableData data]; - NSMutableData *dataPlusCrc = [data mutableCopy]; - unsigned char crc = [CRC8 compute:data]; - [dataPlusCrc appendBytes:&crc length:1]; - char codes[16] = {21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28}; - const unsigned char *inBytes = dataPlusCrc.bytes; - unsigned int acc = 0x0; - int bitcount = 0; - for (int i=0; i < dataPlusCrc.length; i++) { - acc <<= 6; - acc |= codes[inBytes[i] >> 4]; - bitcount += 6; - - acc <<= 6; - acc |= codes[inBytes[i] & 0x0f]; - bitcount += 6; - - while (bitcount >= 8) { - unsigned char outByte = acc >> (bitcount-8) & 0xff; - [outData appendBytes:&outByte length:1]; - bitcount -= 8; - acc &= (0xffff >> (16-bitcount)); - } - } - if (bitcount > 0) { - acc <<= (8-bitcount); - unsigned char outByte = acc & 0xff; - [outData appendBytes:&outByte length:1]; - } - return outData; -} - -- (NSData*)decodeRF:(NSData*) rawData { - // Converted from ruby using: CODE_SYMBOLS.each{|k,v| puts "@#{Integer("0b"+k)}: @#{Integer("0x"+v)},"};nil - NSDictionary *codes = @{@21: @0, - @49: @1, - @50: @2, - @35: @3, - @52: @4, - @37: @5, - @38: @6, - @22: @7, - @26: @8, - @25: @9, - @42: @10, - @11: @11, - @44: @12, - @13: @13, - @14: @14, - @28: @15}; - NSMutableData *output = [NSMutableData data]; - const unsigned char *bytes = rawData.bytes; - int availBits = 0; - unsigned int x = 0; - for (int i = 0; i < rawData.length; i++) - { - x = (x << 8) + bytes[i]; - availBits += 8; - if (availBits >= 12) { - NSNumber *hiNibble = codes[@(x >> (availBits - 6))]; - NSNumber *loNibble = codes[@((x >> (availBits - 12)) & 0b111111)]; - if (hiNibble && loNibble) { - unsigned char decoded = (hiNibble.integerValue << 4) + loNibble.integerValue; - [output appendBytes:&decoded length:1]; - } else { - _codingErrorCount += 1; - } - availBits -= 12; - x = x & (0xffff >> (16-availBits)); - } - } - return output; -} - -- (NSString*) hexadecimalString { - return _data.hexadecimalString; -} - -- (unsigned char)byteAt:(NSInteger)index { - if (_data && index < _data.length) { - return ((unsigned char*)_data.bytes)[index]; - } else { - return 0; - } -} - -- (PacketType) packetType { - return [self byteAt:0]; -} - -- (MessageType) messageType { - return [self byteAt:4]; -} - -- (NSString*) address { - return [NSString stringWithFormat:@"%02x%02x%02x", [self byteAt:1], [self byteAt:2], [self byteAt:3]]; -} - -- (MessageBase*)toMessage { - if (self.packetType == PacketTypeSentry) { - switch (self.messageType) { - case MESSAGE_TYPE_PUMP_STATUS: - return [[PumpStatusMessage alloc] initWithData:_data]; - case MESSAGE_TYPE_DEVICE_LINK: - return [[DeviceLinkMessage alloc] initWithData:_data]; - case MESSAGE_TYPE_FIND_DEVICE: - return [[FindDeviceMessage alloc] initWithData:_data]; - default: - return nil; - } - } else if (self.packetType == PacketTypeMeter) { - return [[MeterMessage alloc] initWithData:_data]; - } - return nil; -} - - - -@end diff --git a/RileyLink/MySentryPairingViewController.m b/RileyLink/MySentryPairingViewController.m index f647cdf8e..a7ce0b3be 100644 --- a/RileyLink/MySentryPairingViewController.m +++ b/RileyLink/MySentryPairingViewController.m @@ -8,7 +8,6 @@ #import "MySentryPairingViewController.h" #import "Config.h" -#import "MinimedPacket.h" #import "NSData+Conversion.h" #import "RileyLinkBLEManager.h" #import "GetPacketCmd.h" @@ -69,6 +68,8 @@ - (void)listenForPairing { cmd.listenChannel = 2; cmd.timeoutMS = 30000; + + // TODO: Upgrade to new api // [self.device doCmd:cmd withCompletionHandler:^(CmdBase * _Nonnull cmd) { // if (cmd.response) { diff --git a/RileyLink/PacketGeneratorViewController.m b/RileyLink/PacketGeneratorViewController.m index fbf958ade..a6b0d4f6b 100644 --- a/RileyLink/PacketGeneratorViewController.m +++ b/RileyLink/PacketGeneratorViewController.m @@ -7,7 +7,6 @@ // #import "PacketGeneratorViewController.h" -#import "MinimedPacket.h" #import "NSData+Conversion.h" #import "SendAndListenCmd.h" @@ -64,16 +63,19 @@ - (void)incrementPacketNum { - (void)sendTestPacket { NSString *packetStr = [@"614C05E077" stringByAppendingFormat:@"%02x", testPacketNum]; NSData *data = [NSData dataWithHexadecimalString:packetStr]; - if (encodeDataSwitch.on) { - data = [MinimedPacket encodeData:data]; - } +// if (encodeDataSwitch.on) { +// data = [MinimedPacket encodeData:data]; +// } packetData.text = data.hexadecimalString; SendAndListenCmd *cmd = [[SendAndListenCmd alloc] init]; cmd.sendChannel = txChannel; cmd.repeatCount = 0; cmd.msBetweenPackets = 0; - // TODO: Upgrade to new api - //[_device doCmd:cmd withCompletionHandler:nil]; + cmd.timeoutMS = 1000; + + [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { + [session doCmd:cmd withTimeoutMs:1000]; + }]; } - (IBAction)sendPacketButtonPressed:(id)sender { diff --git a/RileyLink/PacketLogViewController.m b/RileyLink/PacketLogViewController.m index e4c761159..246d119c4 100644 --- a/RileyLink/PacketLogViewController.m +++ b/RileyLink/PacketLogViewController.m @@ -8,10 +8,11 @@ #import "PacketLogViewController.h" #import "PacketTableViewCell.h" -#import "MinimedPacket.h" +#import "RFPacket.h" #import "RileyLinkBLEManager.h" @interface PacketLogViewController () { + NSMutableArray *packets; } @end @@ -21,6 +22,8 @@ @implementation PacketLogViewController - (void)viewDidLoad { [super viewDidLoad]; + packets = [NSMutableArray array]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(packetReceived:) name:RILEYLINK_EVENT_PACKET_RECEIVED @@ -51,16 +54,16 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. - return self.device.packets.count; + return packets.count; } -- (MinimedPacket *)packetForIndex:(NSInteger) idx { - return self.device.packets[self.device.packets.count - idx - 1]; +- (RFPacket *)packetForIndex:(NSInteger) idx { + return packets[packets.count - idx - 1]; } - (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { PacketTableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:@"packet" forIndexPath:indexPath]; - MinimedPacket *packet = [self packetForIndex:indexPath.row]; + RFPacket *packet = [self packetForIndex:indexPath.row]; cell.packet = packet; return cell; } diff --git a/RileyLink/PacketTableViewCell.h b/RileyLink/PacketTableViewCell.h index d5b717cb1..3b35129ff 100644 --- a/RileyLink/PacketTableViewCell.h +++ b/RileyLink/PacketTableViewCell.h @@ -7,10 +7,10 @@ // #import -#import "MinimedPacket.h" +#import "RFPacket.h" @interface PacketTableViewCell : UITableViewCell -@property (nonatomic, strong) MinimedPacket *packet; +@property (nonatomic, strong) RFPacket *packet; @end diff --git a/RileyLink/PacketTableViewCell.m b/RileyLink/PacketTableViewCell.m index 2939a1bc8..c11f9310b 100644 --- a/RileyLink/PacketTableViewCell.m +++ b/RileyLink/PacketTableViewCell.m @@ -7,6 +7,7 @@ // #import "PacketTableViewCell.h" +#import "MinimedKit.h" static NSDateFormatter *dateFormatter; static NSDateFormatter *timeFormatter; @@ -36,10 +37,10 @@ - (void)awakeFromNib { // Initialization code } -- (void)setPacket:(MinimedPacket *)packet { +- (void)setPacket:(RFPacket *)packet { _packet = packet; - rawDataLabel.text = packet.hexadecimalString; + rawDataLabel.text = packet.data.hexadecimalString; dateLabel.text = [dateFormatter stringFromDate:packet.capturedAt]; timeLabel.text = [timeFormatter stringFromDate:packet.capturedAt]; rssiLabel.text = [NSString stringWithFormat:@"%d", packet.rssi]; diff --git a/RileyLink/PumpChatViewController.m b/RileyLink/PumpChatViewController.m index 1ce3b6a04..aa24a034e 100644 --- a/RileyLink/PumpChatViewController.m +++ b/RileyLink/PumpChatViewController.m @@ -8,7 +8,6 @@ #import "PumpChatViewController.h" #import "MessageBase.h" -#import "MinimedPacket.h" #import "NSData+Conversion.h" #import "Config.h" #import "RileyLinkBLEManager.h" diff --git a/RileyLink/RFPacket.h b/RileyLink/RFPacket.h new file mode 100644 index 000000000..07d1f6f38 --- /dev/null +++ b/RileyLink/RFPacket.h @@ -0,0 +1,21 @@ +// +// RFPacket.h +// RileyLink +// +// Created by Pete Schwamb on 2/28/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +#import + +@interface RFPacket : NSObject + +- (nonnull instancetype)initWithData:(nonnull NSData*)data NS_DESIGNATED_INITIALIZER; + +@property (nonatomic, nullable, strong) NSData *data; +@property (nonatomic, nullable, strong) NSDate *capturedAt; +@property (nonatomic, assign) int rssi; +@property (nonatomic, assign) int packetNumber; + + +@end diff --git a/RileyLink/RFPacket.m b/RileyLink/RFPacket.m new file mode 100644 index 000000000..b9900ea8a --- /dev/null +++ b/RileyLink/RFPacket.m @@ -0,0 +1,42 @@ +// +// RFPacket.m +// RileyLink +// +// Created by Pete Schwamb on 2/28/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +#import "RFPacket.h" + +@implementation RFPacket + +- (instancetype)init NS_UNAVAILABLE +{ + return nil; +} + +- (instancetype)initWithData:(NSData*)data +{ + self = [super init]; + if (self) { + if (data.length > 0) { + unsigned char rssiDec = ((const unsigned char*)[data bytes])[0]; + unsigned char rssiOffset = 73; + if (rssiDec >= 128) { + self.rssi = (short)((short)( rssiDec - 256) / 2) - rssiOffset; + } else { + self.rssi = (rssiDec / 2) - rssiOffset; + } + } + if (data.length > 1) { + self.packetNumber = ((const unsigned char*)[data bytes])[1]; + } + + if (data.length > 2) { + _data = [data subdataWithRange:NSMakeRange(2, data.length - 2)]; + } + } + return self; +} + +@end diff --git a/RileyLink/RileyLinkBLEDevice.h b/RileyLink/RileyLinkBLEDevice.h index acdca409f..5991d09ee 100644 --- a/RileyLink/RileyLinkBLEDevice.h +++ b/RileyLink/RileyLinkBLEDevice.h @@ -55,8 +55,6 @@ typedef NS_ENUM(NSUInteger, SubgRfspyError) { @property (nonatomic, nonnull, readonly) NSString * peripheralId; @property (nonatomic, nonnull, readonly, retain) CBPeripheral * peripheral; -@property (nonatomic, nonnull, readonly, copy) NSArray *packets; - @property (nonatomic, readonly) RileyLinkState state; @property (nonatomic, readonly, copy, nonnull) NSString * deviceURI; diff --git a/RileyLink/RileyLinkBLEDevice.m b/RileyLink/RileyLinkBLEDevice.m index b6a243b6f..8bddc71b2 100644 --- a/RileyLink/RileyLinkBLEDevice.m +++ b/RileyLink/RileyLinkBLEDevice.m @@ -6,13 +6,13 @@ // Copyright (c) 2015 Pete Schwamb. All rights reserved. // -#import "MinimedPacket.h" #import "RileyLinkBLEDevice.h" #import "RileyLinkBLEManager.h" #import "NSData+Conversion.h" #import "SendAndListenCmd.h" #import "GetPacketCmd.h" #import "GetVersionCmd.h" +#import "RFPacket.h" #import "UIAlertView+Blocks.h" @@ -93,10 +93,6 @@ - (NSString *)peripheralId return self.peripheral.identifier.UUIDString; } -- (NSArray*) packets { - return [NSArray arrayWithArray:incomingPackets]; -} - - (void) runSession:(void (^ _Nonnull)(RileyLinkCmdSession* _Nonnull))proc { dispatch_group_enter(idleDetectDispatchGroup); RileyLinkCmdSession *session = [[RileyLinkCmdSession alloc] init]; @@ -432,10 +428,9 @@ - (void) disableIdleListening { - (void) handleIdleListenerResponse:(NSData *)response { if (response.length > 3) { // This is a response to our idle listen command - MinimedPacket *packet = [[MinimedPacket alloc] initWithData:response]; + RFPacket *packet = [[RFPacket alloc] initWithData:response]; packet.capturedAt = [NSDate date]; - [incomingPackets addObject:packet]; - NSLog(@"Read packet (%d): %@", packet.rssi, packet.data.hexadecimalString); + NSLog(@"Read packet (%d): %d bytes", packet.rssi, packet.data.length); NSDictionary *attrs = @{ @"packet": packet, @"peripheral": self.peripheral, From 0fc48d695fc896fc61cff5dd06177506868ad992 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 22:11:42 -0600 Subject: [PATCH 011/116] Update mysentry pairing to new rileylink session management --- RileyLink/MySentryPairingViewController.m | 44 ++++++++++++----------- RileyLink/PacketGeneratorViewController.m | 9 ++--- RileyLink/RileyLinkBLEDevice.m | 6 ++-- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/RileyLink/MySentryPairingViewController.m b/RileyLink/MySentryPairingViewController.m index f647cdf8e..2d6785eff 100644 --- a/RileyLink/MySentryPairingViewController.m +++ b/RileyLink/MySentryPairingViewController.m @@ -66,16 +66,18 @@ - (void)listenForPairing { return; } GetPacketCmd *cmd = [[GetPacketCmd alloc] init]; - cmd.listenChannel = 2; + cmd.listenChannel = 0; cmd.timeoutMS = 30000; - // TODO: Upgrade to new api -// [self.device doCmd:cmd withCompletionHandler:^(CmdBase * _Nonnull cmd) { -// if (cmd.response) { -// MinimedPacket *rxPacket = [[MinimedPacket alloc] initWithData:cmd.response]; -// [self packetReceived:rxPacket]; -// } -// }]; + [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { + NSData *response = [session doCmd:cmd withTimeoutMs:31000]; + if (response) { + dispatch_async(dispatch_get_main_queue(),^{ + MinimedPacket *rxPacket = [[MinimedPacket alloc] initWithData:cmd.response]; + [self packetReceived:rxPacket]; + }); + } + }]; } - (void)handleResponse:(NSData*)response { @@ -235,18 +237,21 @@ - (CmdBase *)makeCommandForAckAndListen:(uint8_t)sequence forMessageType:(uint8_ SendAndListenCmd *send = [[SendAndListenCmd alloc] init]; send.sendChannel = 0; send.timeoutMS = 180; - send.listenChannel = 2; + send.listenChannel = 0; send.packet = [MinimedPacket encodeData:data]; return send; } - (void)runCommand:(CmdBase*) cmd { - // TODO: Upgrade to new api -// [self.device doCmd:cmd withCompletionHandler:^(CmdBase * _Nonnull cmd) { -// if (cmd.response) { -// [self handleResponse:cmd.response]; -// } -// }]; + NSLog(@"*************************************************************************** runCommand ***********************"); + [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { + NSData *response = [session doCmd:cmd withTimeoutMs:31000]; + if (response) { + dispatch_async(dispatch_get_main_queue(),^{ + [self handleResponse:response]; + }); + } + }]; } - (void)handleFindDevice:(FindDeviceMessage *)msg @@ -257,8 +262,7 @@ - (void)handleFindDevice:(FindDeviceMessage *)msg CmdBase *cmd = [self makeCommandForAckAndListen:msg.sequence forMessageType:(uint8_t)msg.messageType]; - [self performSelector:@selector(runCommand:) withObject:cmd afterDelay:1]; - //[self runCommand:cmd]; + [self runCommand:cmd]; } - (void)handleDeviceLink:(DeviceLinkMessage *)msg @@ -268,8 +272,7 @@ - (void)handleDeviceLink:(DeviceLinkMessage *)msg } CmdBase *cmd = [self makeCommandForAckAndListen:msg.sequence forMessageType:(uint8_t)msg.messageType]; - [self performSelector:@selector(runCommand:) withObject:cmd afterDelay:1]; - //[self runCommand:cmd]; + [self runCommand:cmd]; } - (void)handlePumpStatus:(PumpStatusMessage *)msg { @@ -277,8 +280,7 @@ - (void)handlePumpStatus:(PumpStatusMessage *)msg { self.state = PairingStateComplete; } CmdBase *cmd = [self makeCommandForAckAndListen:0 forMessageType:(uint8_t)msg.messageType]; - [self performSelector:@selector(runCommand:) withObject:cmd afterDelay:1]; - //[self runCommand:cmd]; + [self runCommand:cmd]; } - (void)closeKeyboard:(id)sender diff --git a/RileyLink/PacketGeneratorViewController.m b/RileyLink/PacketGeneratorViewController.m index fbf958ade..55627896e 100644 --- a/RileyLink/PacketGeneratorViewController.m +++ b/RileyLink/PacketGeneratorViewController.m @@ -9,7 +9,7 @@ #import "PacketGeneratorViewController.h" #import "MinimedPacket.h" #import "NSData+Conversion.h" -#import "SendAndListenCmd.h" +#import "SendPacketCmd.h" @interface PacketGeneratorViewController () { int testPacketNum; @@ -68,12 +68,13 @@ - (void)sendTestPacket { data = [MinimedPacket encodeData:data]; } packetData.text = data.hexadecimalString; - SendAndListenCmd *cmd = [[SendAndListenCmd alloc] init]; + SendPacketCmd *cmd = [[SendPacketCmd alloc] init]; cmd.sendChannel = txChannel; cmd.repeatCount = 0; cmd.msBetweenPackets = 0; - // TODO: Upgrade to new api - //[_device doCmd:cmd withCompletionHandler:nil]; + [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { + [session doCmd:cmd withTimeoutMs:1000]; + }]; } - (IBAction)sendPacketButtonPressed:(id)sender { diff --git a/RileyLink/RileyLinkBLEDevice.m b/RileyLink/RileyLinkBLEDevice.m index 0b7423d35..a6ac075d1 100644 --- a/RileyLink/RileyLinkBLEDevice.m +++ b/RileyLink/RileyLinkBLEDevice.m @@ -101,19 +101,19 @@ - (void) runSession:(void (^ _Nonnull)(RileyLinkCmdSession* _Nonnull))proc { dispatch_group_enter(idleDetectDispatchGroup); RileyLinkCmdSession *session = [[RileyLinkCmdSession alloc] init]; session.device = self; - runningSession = YES; dispatch_async(_serialDispatchQueue, ^{ + runningSession = YES; NSLog(@"Running dispatched RL comms task"); proc(session); NSLog(@"Finished running dispatched RL comms task"); + runningSession = NO; dispatch_group_leave(idleDetectDispatchGroup); }); dispatch_group_notify(idleDetectDispatchGroup, dispatch_get_main_queue(), ^{ NSLog(@"idleDetectDispatchGroup empty"); - runningSession = NO; - if (!runningIdle) { + if (!runningIdle && !runningSession) { [self onIdle]; } }); From 20dbe0464948e1d35d483704c79c5d9103eb07b8 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 22:23:34 -0600 Subject: [PATCH 012/116] wip --- RileyLink/MySentryPairingViewController.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/RileyLink/MySentryPairingViewController.m b/RileyLink/MySentryPairingViewController.m index a25026af4..88099b631 100644 --- a/RileyLink/MySentryPairingViewController.m +++ b/RileyLink/MySentryPairingViewController.m @@ -15,6 +15,7 @@ #import "DeviceLinkMessage.h" #import "FindDeviceMessage.h" #import "PumpStatusMessage.h" +#import "RFPacket.h" typedef NS_ENUM(NSUInteger, PairingState) { PairingStateComplete, @@ -72,7 +73,7 @@ - (void)listenForPairing { NSData *response = [session doCmd:cmd withTimeoutMs:31000]; if (response) { dispatch_async(dispatch_get_main_queue(),^{ - MinimedPacket *rxPacket = [[MinimedPacket alloc] initWithData:cmd.response]; + RFPacket *rxPacket = [[RFPacket alloc] initWithData:cmd.response]; [self packetReceived:rxPacket]; }); } @@ -81,7 +82,7 @@ - (void)listenForPairing { - (void)handleResponse:(NSData*)response { if (response) { - MinimedPacket *rxPacket = [[MinimedPacket alloc] initWithData:response]; + RFPacket *rxPacket = [[RFPacket alloc] initWithData:response]; [self packetReceived:rxPacket]; } } @@ -195,7 +196,7 @@ - (BOOL)textFieldShouldReturn:(UITextField *)textField { #pragma mark - Actions -- (void)packetReceived:(MinimedPacket *)packet { +- (void)packetReceived:(RFPacket *)packet { BOOL handled = NO; From b030b70f2b9b97f5db6eda1c5b50421761f6d5b4 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 22:34:43 -0600 Subject: [PATCH 013/116] Fix continual retry --- RileyLink/MySentryPairingViewController.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RileyLink/MySentryPairingViewController.m b/RileyLink/MySentryPairingViewController.m index 2d6785eff..4836e4ecc 100644 --- a/RileyLink/MySentryPairingViewController.m +++ b/RileyLink/MySentryPairingViewController.m @@ -218,7 +218,7 @@ - (void)packetReceived:(MinimedPacket *)packet { handled = YES; } } - if (!handled) { + if (!handled && PairingStateStarted == self.state) { // Other random packet; ignore and start listening again. [self performSelector:@selector(listenForPairing) withObject:nil afterDelay:0]; } @@ -243,7 +243,6 @@ - (CmdBase *)makeCommandForAckAndListen:(uint8_t)sequence forMessageType:(uint8_ } - (void)runCommand:(CmdBase*) cmd { - NSLog(@"*************************************************************************** runCommand ***********************"); [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { NSData *response = [session doCmd:cmd withTimeoutMs:31000]; if (response) { From 8a7dfad071798c91f99a1a8df2a7d88e76f31d7a Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 28 Feb 2016 22:42:54 -0600 Subject: [PATCH 014/116] Keep listening until get mysentry packet --- RileyLink/MySentryPairingViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RileyLink/MySentryPairingViewController.m b/RileyLink/MySentryPairingViewController.m index 4836e4ecc..e850e9fc4 100644 --- a/RileyLink/MySentryPairingViewController.m +++ b/RileyLink/MySentryPairingViewController.m @@ -218,7 +218,7 @@ - (void)packetReceived:(MinimedPacket *)packet { handled = YES; } } - if (!handled && PairingStateStarted == self.state) { + if (!handled && PairingStateComplete != self.state) { // Other random packet; ignore and start listening again. [self performSelector:@selector(listenForPairing) withObject:nil afterDelay:0]; } From a950e694ea9b5a2d1704693d1fef5c263db88e98 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 3 Mar 2016 08:48:27 -0600 Subject: [PATCH 015/116] mysentry pairing code ported to swift; not fully working yet --- MinimedKit/HistoryPageTemp.swift | 27 ++ MinimedKit/MessageType.swift | 4 + .../Messages/DeviceLinkMessageBody.swift | 42 +++ .../Messages/FindDeviceMessageBody.swift | 42 +++ MinimedKit/PumpMessage.swift | 1 - MinimedKit/RFTools.swift | 4 +- RileyLink.xcodeproj/project.pbxproj | 31 +- RileyLink/HistoryPage.m | 16 +- RileyLink/MySentryPairViewController.swift | 287 +++++++++++++++++ RileyLink/MySentryPairingViewController.h | 16 - RileyLink/MySentryPairingViewController.m | 297 ------------------ RileyLink/NightScoutUploader.h | 1 - .../PumpHistoryEvents/PumpHistoryEventBase.m | 6 - RileyLink/PumpOpsSynchronous.m | 1 - RileyLink/RileyLink-Bridging-Header.h | 9 + RileyLink/Storyboard.storyboard | 16 +- 16 files changed, 449 insertions(+), 351 deletions(-) create mode 100644 MinimedKit/HistoryPageTemp.swift create mode 100644 MinimedKit/Messages/DeviceLinkMessageBody.swift create mode 100644 MinimedKit/Messages/FindDeviceMessageBody.swift create mode 100644 RileyLink/MySentryPairViewController.swift delete mode 100644 RileyLink/MySentryPairingViewController.h delete mode 100644 RileyLink/MySentryPairingViewController.m create mode 100644 RileyLink/RileyLink-Bridging-Header.h diff --git a/MinimedKit/HistoryPageTemp.swift b/MinimedKit/HistoryPageTemp.swift new file mode 100644 index 000000000..839660170 --- /dev/null +++ b/MinimedKit/HistoryPageTemp.swift @@ -0,0 +1,27 @@ +// +// HistoryPage.swift +// RileyLink +// +// Created by Pete Schwamb on 3/3/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + +@objc public class HistoryPageTemp : NSObject { + + var pageData: NSData! + + @objc public init?(pageData: NSData) { + self.pageData = pageData + } + + @objc public func crcOK() -> Bool { + //uint16_t packetCRC = bytes[_data.length-1] + (bytes[_data.length-2] << 8); + //return packetCRC == [CRC16 compute:[_data subdataWithRange:NSMakeRange(0, _data.length-2)]]; + let lowByte: UInt8 = pageData[pageData.length - 1] + let hiByte: UInt8 = pageData[pageData.length - 2] + let packetCRC: UInt16 = (UInt16(hiByte) << 16) + UInt16(lowByte) + return packetCRC == computeCRC16(pageData) + } +} \ No newline at end of file diff --git a/MinimedKit/MessageType.swift b/MinimedKit/MessageType.swift index d613ac434..a0314a0d3 100644 --- a/MinimedKit/MessageType.swift +++ b/MinimedKit/MessageType.swift @@ -32,6 +32,10 @@ public enum MessageType: UInt8 { return MySentryAckMessageBody.self case .ReadSettings: return ReadSettingsCarelinkMessageBody.self + case .FindDevice: + return FindDeviceMessageBody.self + case .DeviceLink: + return DeviceLinkMessageBody.self default: return UnknownMessageBody.self } diff --git a/MinimedKit/Messages/DeviceLinkMessageBody.swift b/MinimedKit/Messages/DeviceLinkMessageBody.swift new file mode 100644 index 000000000..548b9545e --- /dev/null +++ b/MinimedKit/Messages/DeviceLinkMessageBody.swift @@ -0,0 +1,42 @@ +// +// DeviceLinkMessageBody.swift +// RileyLink +// +// Created by Pete Schwamb on 2/29/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + +public struct DeviceLinkMessageBody: MessageBody { + + public static let length = 8 + + public let pumpID: [UInt8] + public let sequence: UInt8 + let rxData: NSData + + + public init?(rxData: NSData) { + self.rxData = rxData + + if rxData.length == self.dynamicType.length { + pumpID = rxData[1...3] + sequence = rxData[0] & 0b1111111 + } else { + return nil + } + } + + public var txData: NSData { + return rxData + } + + public var dictionaryRepresentation: [String: AnyObject] { + return [ + "sequence": Int(sequence), + "pumpId": NSData(bytes: pumpID, length: 3).hexadecimalString, + ] + } + +} diff --git a/MinimedKit/Messages/FindDeviceMessageBody.swift b/MinimedKit/Messages/FindDeviceMessageBody.swift new file mode 100644 index 000000000..eb386c50f --- /dev/null +++ b/MinimedKit/Messages/FindDeviceMessageBody.swift @@ -0,0 +1,42 @@ +// +// FindDeviceMessageBody.swift +// RileyLink +// +// Created by Pete Schwamb on 2/29/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + +public struct FindDeviceMessageBody: MessageBody { + + public static let length = 8 + + let pumpID: [UInt8] + public let sequence: UInt8 + let rxData: NSData + + + public init?(rxData: NSData) { + self.rxData = rxData + + if rxData.length == self.dynamicType.length { + pumpID = rxData[1...3] + sequence = rxData[0] & 0b1111111 + } else { + return nil + } + } + + public var txData: NSData { + return rxData + } + + public var dictionaryRepresentation: [String: AnyObject] { + return [ + "sequence": Int(sequence), + "pumpId": NSData(bytes: pumpID, length: 3).hexadecimalString, + ] + } + +} diff --git a/MinimedKit/PumpMessage.swift b/MinimedKit/PumpMessage.swift index 3d9e3d617..ef22b4321 100644 --- a/MinimedKit/PumpMessage.swift +++ b/MinimedKit/PumpMessage.swift @@ -8,7 +8,6 @@ import Foundation - public struct PumpMessage { public let packetType: PacketType public let address: NSData diff --git a/MinimedKit/RFTools.swift b/MinimedKit/RFTools.swift index dabc85e7f..6ae54555f 100644 --- a/MinimedKit/RFTools.swift +++ b/MinimedKit/RFTools.swift @@ -12,7 +12,7 @@ private let codesRev:Dictionary = [21: 0, 49: 1, 50: 2, 35: 3, 52: 4 private let codes = [21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28] -func decode4b6b(rawData: NSData) -> NSData? { +public func decode4b6b(rawData: NSData) -> NSData? { var buffer = [UInt8]() let bytes: [UInt8] = rawData[0.. NSData? { return NSData(bytes: &buffer, length: buffer.count) } -func encode4b6b(rawData: NSData) -> NSData { +public func encode4b6b(rawData: NSData) -> NSData { var buffer = [UInt8]() let bytes: [UInt8] = rawData[0.. Bool { + let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString:string) + + if newString.characters.count > 6 { + return false + } else if newString.characters.count == 6 { + textField.text = newString + textField.resignFirstResponder() + return false + } else if .Ready == self.state { + state = .NeedsConfig + } + + return true + } + + func textFieldShouldReturn(textField: UITextField) -> Bool { + return true + } + + // MARK: - Other + + func listenForPairing() { + if wasDismissed { + return + } + + let cmd = GetPacketCmd() + cmd.listenChannel = 0; + cmd.timeoutMS = 30000; + runCommand(cmd) + } + + func handleResponse(response: NSData) { + let rxPacket = RFPacket.init(data: response) + packetReceived(rxPacket) + } + + func setState(state: PairingState) { + if (state == self.state) { + return + } + + self.state = state; + + switch state { + case .NeedsConfig: + startButton.enabled = false + startButton.hidden = true + instructionLabel.text = NSLocalizedString( + "Enter a 6-digit numeric value to identify your MySentry.", + comment: "Device ID instruction") + instructionLabel.hidden = false + case .Ready: + startButton.enabled = true + startButton.hidden = false + progressView.progress = 0 + + instructionLabel.hidden = true + case .Started: + startButton.enabled = false + startButton.hidden = true + deviceIDTextField.enabled = false + progressView.setProgress(1.0 / 4.0, animated:true) + + instructionLabel.text = NSLocalizedString( + "On your pump, go to the Find Device screen and select \"Find Device\"." + + "\n" + + "\nMain Menu >" + + "\nUtilities >" + + "\nConnect Devices >" + + "\nOther Devices >" + + "\nOn >" + + "\nFind Device", + comment: "Pump find device instruction") + instructionLabel.hidden = false + case .ReceivedFindPacket: + progressView.setProgress(2.0 / 4.0, animated:true) + + instructionLabel.text = NSLocalizedString( + "Pairing in process, please wait.", + comment: "Pairing waiting instruction") + case .ReceivedLinkPacket: + progressView.setProgress(3.0 / 4.0, animated:true) + instructionLabel.text = NSLocalizedString( + "Pump accepted pairing. " + + "Waiting for MySentry update from pump. " + + "This could take up to five minutes...", + comment: "Pairing waiting instruction") + case .Complete: + progressView.setProgress(4.0 / 4.0, animated:true) + + instructionLabel.text = NSLocalizedString( + "Congratulations! Pairing is complete.", + comment: "Pairing waiting instruction") + } + } + + // MARK: - Actions + + func packetReceived(packet: RFPacket) { + + var handled = false + + if let data = packet.data, msg = PumpMessage.init(rxData: data) { + if msg.packetType == PacketType.MySentry && + msg.address == Config.sharedInstance().pumpID { + switch (msg.messageType) { + case MessageType.FindDevice: + handleFindDevice(msg.messageBody as! FindDeviceMessageBody) + handled = true + case MessageType.DeviceLink: + handleDeviceLink(msg.messageBody as! DeviceLinkMessageBody) + handled = true + case MessageType.PumpStatus: + handlePumpStatus(msg.messageBody as! MySentryPumpStatusMessageBody) + handled = true + default: + NSLog("Unexpected packet received: " + String(msg.messageType)) + } + } + } + if (!handled && .Complete != self.state) { + // Other random packet; ignore and start listening again. + performSelector(Selector("listenForPairing"), withObject:nil, afterDelay:0) + } + } + + func makeCommandForAckAndListen(sequence: UInt8, messageType: MessageType) -> CmdBase { + let replyString = String(format: "%02x%@%02x%02x%@00%02x000000", + PacketType.MySentry.rawValue, + Config.sharedInstance().pumpID, + MessageType.PumpStatusAck.rawValue, + sequence, + self.deviceIDTextField.text!, + messageType.rawValue) + let data = NSData.init(hexadecimalString: replyString) + let send = SendAndListenCmd() + send.sendChannel = 0; + send.timeoutMS = 180; + send.listenChannel = 0; + send.packet = encode4b6b(data!) + return send; + } + + func runCommand(cmd: CmdBase) { + device.runSession { + (session: RileyLinkCmdSession) -> Void in + let response = session.doCmd(cmd, withTimeoutMs: 31000) + dispatch_async(dispatch_get_main_queue(), { () -> Void in + let rxPacket = RFPacket.init(data: response) + self.packetReceived(rxPacket) + }) + } + } + + func handleFindDevice(msg: FindDeviceMessageBody) { + if .Started == self.state { + self.state = .ReceivedFindPacket + } + + let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.FindDevice) + runCommand(cmd) + } + + func handleDeviceLink(msg: DeviceLinkMessageBody) + { + if .ReceivedFindPacket == self.state { + self.state = .ReceivedLinkPacket + } + + let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.DeviceLink) + runCommand(cmd) + } + + func handlePumpStatus(msg: MySentryPumpStatusMessageBody) { + if .ReceivedLinkPacket == self.state { + self.state = .Complete; + } + let cmd = makeCommandForAckAndListen(0, messageType: MessageType.PumpStatus) + runCommand(cmd) + } +// +// - (void)closeKeyboard:(id)sender +// { +// [self.view endEditing:YES]; +// } +// +// - (IBAction)startPairing:(id)sender { +// if (PairingStateReady == self.state) { +// self.state = PairingStateStarted; +// [self listenForPairing]; +// } +// } +// +// + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/RileyLink/MySentryPairingViewController.h b/RileyLink/MySentryPairingViewController.h deleted file mode 100644 index 4bac23184..000000000 --- a/RileyLink/MySentryPairingViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// MySentryPairingViewController.h -// RileyLink -// -// Created by Nathan Racklyeft on 8/14/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import -#import "RileyLinkBLEDevice.h" - -@interface MySentryPairingViewController : UIViewController - -@property (nonatomic, strong) RileyLinkBLEDevice *device; - -@end diff --git a/RileyLink/MySentryPairingViewController.m b/RileyLink/MySentryPairingViewController.m deleted file mode 100644 index 6eaad75e2..000000000 --- a/RileyLink/MySentryPairingViewController.m +++ /dev/null @@ -1,297 +0,0 @@ -// -// MySentryPairingViewController.m -// RileyLink -// -// Created by Nathan Racklyeft on 8/14/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import "MySentryPairingViewController.h" -#import "Config.h" -#import "NSData+Conversion.h" -#import "RileyLinkBLEManager.h" -#import "GetPacketCmd.h" -#import "SendAndListenCmd.h" -#import "DeviceLinkMessage.h" -#import "FindDeviceMessage.h" -#import "PumpStatusMessage.h" -#import "RFPacket.h" - -typedef NS_ENUM(NSUInteger, PairingState) { - PairingStateComplete, - PairingStateNeedsConfig, - PairingStateReady, - PairingStateStarted, - PairingStateReceivedFindPacket, - PairingStateReceivedLinkPacket -}; - - -@interface MySentryPairingViewController () { - BOOL wasDismissed; -} - -@property (weak, nonatomic) IBOutlet UILabel *instructionLabel; -@property (weak, nonatomic) IBOutlet UITextField *deviceIDTextField; -@property (weak, nonatomic) IBOutlet UIButton *startButton; -@property (weak, nonatomic) IBOutlet UIProgressView *progressView; -@property (strong, nonatomic) UITapGestureRecognizer *flailGestureRecognizer; - -@property (nonatomic) PairingState state; -@property (nonatomic) unsigned char sendCounter; - -@end - -@implementation MySentryPairingViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.sendCounter = 0; - self.state = PairingStateNeedsConfig; - - self.deviceIDTextField.text = [self.device.peripheral.identifier.UUIDString substringToIndex:6]; - self.deviceIDTextField.delegate = self; - [self.view addGestureRecognizer:self.flailGestureRecognizer]; - - [self textFieldDidEndEditing:self.deviceIDTextField]; -} - -- (void)viewDidDisappear:(BOOL)animated { - wasDismissed = YES; -} - -- (void)listenForPairing { - if (wasDismissed) { - return; - } - GetPacketCmd *cmd = [[GetPacketCmd alloc] init]; - cmd.listenChannel = 0; - cmd.timeoutMS = 30000; - - [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { - NSData *response = [session doCmd:cmd withTimeoutMs:31000]; - if (response) { - dispatch_async(dispatch_get_main_queue(),^{ - RFPacket *rxPacket = [[RFPacket alloc] initWithData:cmd.response]; - [self packetReceived:rxPacket]; - }); - } - }]; -} - -- (void)handleResponse:(NSData*)response { - if (response) { - RFPacket *rxPacket = [[RFPacket alloc] initWithData:response]; - [self packetReceived:rxPacket]; - } -} - -- (UITapGestureRecognizer *)flailGestureRecognizer -{ - if (!_flailGestureRecognizer) { - _flailGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)]; - _flailGestureRecognizer.cancelsTouchesInView = NO; - _flailGestureRecognizer.enabled = NO; - } - return _flailGestureRecognizer; -} - -- (void)setState:(PairingState)state { - if (state == _state) { - return; - } - - _state = state; - - switch (state) { - case PairingStateNeedsConfig: - self.startButton.enabled = NO; - self.startButton.hidden = YES; - self.instructionLabel.text = NSLocalizedString(@"Enter a 6-digit numeric value to identify your MySentry.", - @"Device ID instruction"); - self.instructionLabel.hidden = NO; - break; - case PairingStateReady: - self.startButton.enabled = YES; - self.startButton.hidden = NO; - self.progressView.progress = 0; - - self.instructionLabel.hidden = YES; - break; - case PairingStateStarted: - self.startButton.enabled = NO; - self.startButton.hidden = YES; - self.deviceIDTextField.enabled = NO; - [self.progressView setProgress:1.0 / 4.0 animated:YES]; - - self.instructionLabel.text = NSLocalizedString(@"On your pump, go to the Find Device screen and select \"Find Device\"." - @"\n" - @"\nMain Menu >" - @"\nUtilities >" - @"\nConnect Devices >" - @"\nOther Devices >" - @"\nOn >" - @"\nFind Device", - @"Pump find device instruction"); - self.instructionLabel.hidden = NO; - break; - case PairingStateReceivedFindPacket: - [self.progressView setProgress:2.0 / 4.0 animated:YES]; - - self.instructionLabel.text = NSLocalizedString(@"Pairing in process, please wait.", - @"Pairing waiting instruction"); - break; - case PairingStateReceivedLinkPacket: - [self.progressView setProgress:3.0 / 4.0 animated:YES]; - self.instructionLabel.text = NSLocalizedString(@"Pump accepted pairing. " - @"Waiting for MySentry update from pump. " - @"This could take up to five minutes...", - @"Pairing waiting instruction"); - break; - case PairingStateComplete: - [self.progressView setProgress:4.0 / 4.0 animated:YES]; - - self.instructionLabel.text = NSLocalizedString(@"Congratulations! Pairing is complete.", - @"Pairing waiting instruction"); - break; - } -} - -#pragma mark - UITextFieldDelegate - -- (void)textFieldDidBeginEditing:(UITextField *)textField { - self.flailGestureRecognizer.enabled = YES; -} - -- (void)textFieldDidEndEditing:(UITextField *)textField { - self.flailGestureRecognizer.enabled = NO; - - if (textField.text.length == 6) { - self.state = PairingStateReady; - } else if (PairingStateReady == self.state) { - self.state = PairingStateNeedsConfig; - } -} - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; - - if (newString.length > 6) { - return NO; - } else if (newString.length == 6) { - textField.text = newString; - [textField resignFirstResponder]; - return NO; - } else if (PairingStateReady == self.state) { - self.state = PairingStateNeedsConfig; - } - - return YES; -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - return YES; -} - -#pragma mark - Actions - -- (void)packetReceived:(RFPacket *)packet { - - BOOL handled = NO; - - if (packet && - PacketTypeSentry == packet.packetType && - [packet.address isEqualToString:[Config sharedInstance].pumpID]) - { - MessageBase *msg = [packet toMessage]; - if ([msg class] == [FindDeviceMessage class]) { - [self handleFindDevice:(FindDeviceMessage*)msg]; - handled = YES; - } - else if ([msg class] == [DeviceLinkMessage class]) { - [self handleDeviceLink:(DeviceLinkMessage*)msg]; - handled = YES; - } - else if ([msg class] == [PumpStatusMessage class]) { - [self handlePumpStatus:(PumpStatusMessage*)msg]; - handled = YES; - } - } - if (!handled && PairingStateComplete != self.state) { - // Other random packet; ignore and start listening again. - [self performSelector:@selector(listenForPairing) withObject:nil afterDelay:0]; - } -} - -- (CmdBase *)makeCommandForAckAndListen:(uint8_t)sequence forMessageType:(uint8_t)messageType { - NSString *replyString = [NSString stringWithFormat:@"%02x%@%02x%02x%@00%02x000000", - PacketTypeSentry, - [Config sharedInstance].pumpID, - MESSAGE_TYPE_ACK, - sequence, - self.deviceIDTextField.text, - messageType - ]; - NSData *data = [NSData dataWithHexadecimalString:replyString]; - SendAndListenCmd *send = [[SendAndListenCmd alloc] init]; - send.sendChannel = 0; - send.timeoutMS = 180; - send.listenChannel = 0; - send.packet = [MinimedPacket encodeData:data]; - return send; -} - -- (void)runCommand:(CmdBase*) cmd { - [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { - NSData *response = [session doCmd:cmd withTimeoutMs:31000]; - if (response) { - dispatch_async(dispatch_get_main_queue(),^{ - [self handleResponse:response]; - }); - } - }]; -} - -- (void)handleFindDevice:(FindDeviceMessage *)msg -{ - if (PairingStateStarted == self.state) { - self.state = PairingStateReceivedFindPacket; - } - - CmdBase *cmd = [self makeCommandForAckAndListen:msg.sequence forMessageType:(uint8_t)msg.messageType]; - - [self runCommand:cmd]; -} - -- (void)handleDeviceLink:(DeviceLinkMessage *)msg -{ - if (PairingStateReceivedFindPacket == self.state) { - self.state = PairingStateReceivedLinkPacket; - } - - CmdBase *cmd = [self makeCommandForAckAndListen:msg.sequence forMessageType:(uint8_t)msg.messageType]; - [self runCommand:cmd]; -} - -- (void)handlePumpStatus:(PumpStatusMessage *)msg { - if (PairingStateReceivedLinkPacket == self.state) { - self.state = PairingStateComplete; - } - CmdBase *cmd = [self makeCommandForAckAndListen:0 forMessageType:(uint8_t)msg.messageType]; - [self runCommand:cmd]; -} - -- (void)closeKeyboard:(id)sender -{ - [self.view endEditing:YES]; -} - -- (IBAction)startPairing:(id)sender { - if (PairingStateReady == self.state) { - self.state = PairingStateStarted; - [self listenForPairing]; - } -} - -@end diff --git a/RileyLink/NightScoutUploader.h b/RileyLink/NightScoutUploader.h index 247430611..210c8917d 100644 --- a/RileyLink/NightScoutUploader.h +++ b/RileyLink/NightScoutUploader.h @@ -7,7 +7,6 @@ // #import -#import "MinimedPacket.h" @interface NightScoutUploader : NSObject diff --git a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m index 8cd8bc896..729f2be0c 100644 --- a/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m +++ b/RileyLink/PumpHistoryEvents/PumpHistoryEventBase.m @@ -42,12 +42,6 @@ - (instancetype)initWithData:(NSData*)data andPumpModel:(PumpModel*)model return self; } -- (instancetype)init NS_UNAVAILABLE -{ - return nil; -} - - - (int) length { [NSException raise:@"Invalid Message" format:@"PumpHistoryEventBase does not implement length."]; return 0; diff --git a/RileyLink/PumpOpsSynchronous.m b/RileyLink/PumpOpsSynchronous.m index 4e8b1b966..d864aa5ca 100644 --- a/RileyLink/PumpOpsSynchronous.m +++ b/RileyLink/PumpOpsSynchronous.m @@ -10,7 +10,6 @@ #import "NSData+Conversion.h" #import "SendPacketCmd.h" #import "SendAndListenCmd.h" -#import "MinimedPacket.h" #import "MessageBase.h" #import "UpdateRegisterCmd.h" diff --git a/RileyLink/RileyLink-Bridging-Header.h b/RileyLink/RileyLink-Bridging-Header.h new file mode 100644 index 000000000..58d50eb5c --- /dev/null +++ b/RileyLink/RileyLink-Bridging-Header.h @@ -0,0 +1,9 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "RFPacket.h" +#import "RileyLinkBLEDevice.h" +#import "Config.h" +#import "SendAndListenCmd.h" +#import "GetPacketCmd.h" diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 6ef05eff5..379006294 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -1,8 +1,8 @@ - + - + @@ -226,7 +226,7 @@ -