/*
|
* Copyright Cypress Semiconductor Corporation, 2014-2015 All rights reserved.
|
*
|
* This software, associated documentation and materials ("Software") is
|
* owned by Cypress Semiconductor Corporation ("Cypress") and is
|
* protected by and subject to worldwide patent protection (UnitedStates and foreign), United States copyright laws and international
|
* treaty provisions. Therefore, unless otherwise specified in a separate license agreement between you and Cypress, this Software
|
* must be treated like any other copyrighted material. Reproduction,
|
* modification, translation, compilation, or representation of this
|
* Software in any other form (e.g., paper, magnetic, optical, silicon)
|
* is prohibited without Cypress's express written permission.
|
*
|
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY
|
* KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
* NONINFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
* FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes
|
* to the Software without notice. Cypress does not assume any liability
|
* arising out of the application or use of Software or any product or
|
* circuit described in the Software. Cypress does not authorize its
|
* products for use as critical components in any products where a
|
* malfunction or failure may reasonably be expected to result in
|
* significant injury or death ("High Risk Product"). By including
|
* Cypress's product in a High Risk Product, the manufacturer of such
|
* system or application assumes all risk of such use and in doing so
|
* indemnifies Cypress against all liability.
|
*
|
* Use of this Software may be limited by and subject to the applicable
|
* Cypress software license agreement.
|
*
|
*
|
*/
|
|
#import "ThermometerModel.h"
|
#import "CBMoralManager.h"
|
|
/*!
|
* @class ThermometerModel
|
*
|
* @discussion Class to handle the thermometer service related operations
|
*
|
*/
|
|
|
@interface ThermometerModel () <cbCharacteristicManagerDelegate>
|
{
|
void (^cbCharacteristicHandler)(BOOL success, NSError *error);
|
void (^cbCharacteristicDiscoverHandler)(BOOL success, NSError *error);
|
CBCharacteristic *RSCCharacter;
|
|
}
|
|
@end
|
|
@implementation ThermometerModel
|
|
@synthesize tempStringValue;
|
@synthesize mesurementType;
|
@synthesize timeStampString;
|
@synthesize tempType;
|
|
|
- (instancetype)init
|
{
|
self = [super init];
|
return self;
|
}
|
|
|
|
/*!
|
* @method startDiscoverChar:
|
*
|
* @discussion Discovers the specified characteristics of a service..
|
*/
|
-(void)startDiscoverChar:(void (^) (BOOL success, NSError *error))handler
|
{
|
cbCharacteristicDiscoverHandler = handler;
|
[[CBMoralManager sharedManager] setCbCharacteristicDelegate:self];
|
[[[CBMoralManager sharedManager] myPeripheral] discoverCharacteristics:nil forService:[[CBMoralManager sharedManager] myService]];
|
|
}
|
|
/*!
|
* @method updateCharacteristicWithHandler:
|
*
|
* @discussion Sets notifications or indications for the value of a specified characteristic.
|
*/
|
-(void)updateCharacteristicWithHandler:(void (^) (BOOL success, NSError *error))handler
|
{
|
cbCharacteristicHandler = handler;
|
|
|
}
|
|
/*!
|
* @method stopUpdate
|
*
|
* @discussion Stop notifications or indications for the value of a specified characteristic.
|
*/
|
|
|
-(void)stopUpdate
|
{
|
cbCharacteristicHandler = nil;
|
|
if ([[[CBMoralManager sharedManager] myService].UUID isEqual:THM_SERVICE_UUID])
|
{
|
for (CBCharacteristic *aChar in [[CBMoralManager sharedManager] myService].characteristics)
|
{
|
if ([aChar.UUID isEqual:THM_TEMPERATURE_MEASUREMENT_CHARACTERISTIC_UUID]){
|
|
if (aChar.isNotifying)
|
{
|
[[[CBMoralManager sharedManager] myPeripheral] setNotifyValue:NO forCharacteristic:aChar];
|
[Utilities logDataWithService:[ResourceHandler getServiceNameForUUID:THM_SERVICE_UUID] characteristic:[ResourceHandler getCharacteristicNameForUUID:THM_TEMPERATURE_MEASUREMENT_CHARACTERISTIC_UUID] descriptor:nil operation:STOP_INDICATE];
|
}
|
cbCharacteristicDiscoverHandler(YES,nil);
|
}
|
}
|
|
}
|
}
|
|
|
#pragma mark - CBCharecteristicManger
|
|
/*!
|
* @method peripheral: didDiscoverCharacteristicsForService: error:
|
*
|
* @discussion Method invoked when characteristics are discovered for a service
|
*
|
*/
|
|
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
|
{
|
if ([service.UUID isEqual:THM_SERVICE_UUID]){
|
for (CBCharacteristic *aChar in service.characteristics){
|
if ([aChar.UUID isEqual:THM_TEMPERATURE_MEASUREMENT_CHARACTERISTIC_UUID]){
|
|
[[[CBMoralManager sharedManager] myPeripheral] setNotifyValue:YES forCharacteristic:aChar];
|
|
[Utilities logDataWithService:[ResourceHandler getServiceNameForUUID:THM_SERVICE_UUID] characteristic:[ResourceHandler getCharacteristicNameForUUID:THM_TEMPERATURE_MEASUREMENT_CHARACTERISTIC_UUID] descriptor:nil operation:START_INDICATE];
|
|
cbCharacteristicDiscoverHandler(YES,nil);
|
}
|
else if([aChar.UUID isEqual:THM_TEMPERATURE_TYPE_CHARACTERISTIC_UUID])
|
{
|
[[[CBMoralManager sharedManager] myPeripheral] readValueForCharacteristic:aChar];
|
|
[Utilities logDataWithService:[ResourceHandler getServiceNameForUUID:THM_SERVICE_UUID] characteristic:[ResourceHandler getCharacteristicNameForUUID:THM_TEMPERATURE_TYPE_CHARACTERISTIC_UUID] descriptor:nil operation:READ_REQUEST];
|
}
|
}
|
}
|
else
|
{
|
cbCharacteristicDiscoverHandler(NO,nil);
|
}
|
|
}
|
|
/*!
|
* @method peripheral: didUpdateValueForCharacteristic: error:
|
*
|
* @discussion Method invoked when the characteristic value changes
|
*
|
*/
|
|
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
|
{
|
if(error == nil)
|
{
|
if ([characteristic.UUID isEqual:THM_TEMPERATURE_MEASUREMENT_CHARACTERISTIC_UUID] && characteristic.value)
|
{
|
[self getTHMtemp:characteristic];
|
}
|
else if ([characteristic.UUID isEqual:THM_TEMPERATURE_TYPE_CHARACTERISTIC_UUID] && characteristic.value)
|
{
|
[self getTempType:characteristic];
|
}
|
|
cbCharacteristicHandler(YES,nil);
|
|
}
|
else
|
{
|
cbCharacteristicHandler(NO,error);
|
}
|
|
}
|
|
/*!
|
* @method getTHMtemp:
|
*
|
* @discussion Instance method to get the temperature value
|
*
|
*/
|
|
|
-(void)getTHMtemp:(CBCharacteristic *)characteristic
|
{
|
|
// Convert the contents of the characteristic value to a data-object //
|
NSData *data = [characteristic value];
|
|
// Get the byte sequence of the data-object //
|
const uint8_t *reportData = [data bytes];
|
|
// Initialise the offset variable //
|
NSUInteger offset = 1;
|
// Initialise the bpm variable //
|
|
if ((reportData[0] & 0x01) == 0) {
|
|
[self calculateTemperaturefromCharacteristic:characteristic];
|
|
offset = offset + 4; // Plus 4 byte //
|
self.mesurementType = @"°C";
|
}
|
else {
|
|
[self calculateTemperaturefromCharacteristic:characteristic];
|
|
offset = offset + 4; // Plus 4 bytes //
|
self.mesurementType = @"°F";
|
}
|
|
|
/* timestamp */
|
if( (reportData[0] & 0x02) )
|
{
|
uint16_t year = CFSwapInt16LittleToHost(*(uint16_t*)offset); offset += 2;
|
uint8_t month = *(uint8_t*)offset; offset++;
|
uint8_t day = *(uint8_t*)offset; offset++;
|
uint8_t hour = *(uint8_t*)offset; offset++;
|
uint8_t min = *(uint8_t*)offset; offset++;
|
uint8_t sec = *(uint8_t*)offset; offset++;
|
|
NSString * dateString = [NSString stringWithFormat:@"%d %d %d %d %d %d", year, month, day, hour, min, sec];
|
|
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
|
[dateFormat setDateFormat: @"yyyy MM dd HH mm ss"];
|
NSDate* date = [dateFormat dateFromString:dateString];
|
|
[dateFormat setDateFormat:@"EEE MMM dd, yyyy"];
|
NSString* dateFormattedString = [dateFormat stringFromDate:date];
|
|
[dateFormat setDateFormat:@"h:mm a"];
|
NSString* timeFormattedString = [dateFormat stringFromDate:date];
|
|
|
if( dateFormattedString && timeFormattedString )
|
{
|
self.timeStampString = [NSString stringWithFormat:@"%@ at %@", dateFormattedString, timeFormattedString];
|
}
|
}
|
|
[Utilities logDataWithService:[ResourceHandler getServiceNameForUUID:characteristic.service.UUID] characteristic:[ResourceHandler getCharacteristicNameForUUID:characteristic.UUID] descriptor:nil operation:[NSString stringWithFormat:@"%@%@ %@",NOTIFY_RESPONSE,DATA_SEPERATOR,[Utilities convertDataToLoggerFormat:data]]];
|
}
|
|
/*!
|
* @method calculateTemperaturefromCharacteristic
|
*
|
* @discussion Method to calculate the temperature
|
*
|
*/
|
|
|
-(void) calculateTemperaturefromCharacteristic:(CBCharacteristic *)characteristic
|
{
|
// Convert the contents of the characteristic value to a data-object //
|
NSData *data = [characteristic value];
|
|
// Get the byte sequence of the data-object //
|
const uint8_t *reportData = [data bytes];
|
|
unsigned char *commandPacket = (unsigned char *)malloc(4 * sizeof(unsigned char));
|
|
reportData++;
|
int32_t tempData ;
|
|
if (reportData[2] != 0xff)
|
{
|
commandPacket[0] = reportData[0];
|
commandPacket[1] = reportData[1];
|
commandPacket[2] = reportData[2];
|
commandPacket[3] = 0x00;
|
}
|
else
|
{
|
commandPacket[0] = ~ (reportData[0] - 1);
|
commandPacket[1] = ~reportData[1];
|
commandPacket[2] = ~reportData[2];
|
commandPacket[3] = 0x00;
|
}
|
|
NSData *testData = [NSData dataWithBytes:commandPacket length:4];
|
const uint8_t *re = [testData bytes];
|
tempData = (int32_t)CFSwapInt32LittleToHost(*(uint32_t*)re);
|
|
int8_t exponent = (int8_t)(tempData >> 24);
|
int32_t mantissa = (int32_t)(tempData & 0x00FFFFFF);
|
|
if( tempData == 0x007FFFFF )
|
{
|
NSLog(@"Invalid temperature value received");
|
return;
|
}
|
|
float tempValue = (float)(mantissa*pow(10, exponent));
|
|
if (reportData[2] == 0xff)
|
{
|
tempValue = tempValue * -1;
|
}
|
self.tempStringValue = [NSString stringWithFormat:@"%.1f",(float) tempValue];
|
free(commandPacket);
|
|
}
|
|
/*!
|
* @method isTempTypeValid:
|
*
|
* @discussion Instance method to check temperature type exist or not
|
*
|
*/
|
|
-(BOOL)isTempTypeValid:(CBCharacteristic *)characteristic
|
{
|
NSData * updatedValue = characteristic.value;
|
uint8_t* dataPointer = (uint8_t*)[updatedValue bytes];
|
|
uint8_t flags = dataPointer[0];
|
|
if( flags & 0x04 )
|
{
|
return true;
|
}
|
return false;
|
}
|
|
/*!
|
* @method getTempType:
|
*
|
* @discussion Instance method to get the Temperature Type characteristic is an enumeration that indicates where the temperature was measured
|
*
|
*/
|
|
-(void)getTempType:(CBCharacteristic *)characteristic
|
{
|
/* temperature type */
|
|
NSData * updatedValue = characteristic.value;
|
uint8_t* dataPointer = (uint8_t*)[updatedValue bytes];
|
uint8_t type = *(uint8_t*)dataPointer;
|
NSString* location = nil;
|
|
switch (type)
|
{
|
case 0x01:
|
location = @"Armpit";
|
break;
|
case 0x02:
|
location = @"Body (general)";
|
break;
|
case 0x03:
|
location = @"Ear";
|
break;
|
case 0x04:
|
location = @"Finger";
|
break;
|
case 0x05:
|
location = @"Gastro-intenstinal Tract";
|
break;
|
case 0x06:
|
location = @"Mouth";
|
break;
|
case 0x07:
|
location = @"Rectum";
|
break;
|
case 0x08:
|
location = @"Toe";
|
break;
|
case 0x09:
|
location = @"Tympanum - ear drum";
|
break;
|
default:
|
break;
|
}
|
if (location)
|
{
|
self.tempType = [NSString stringWithFormat:@"%@", location];
|
}
|
|
[Utilities logDataWithService:[ResourceHandler getServiceNameForUUID:characteristic.service.UUID] characteristic:[ResourceHandler getCharacteristicNameForUUID:characteristic.UUID] descriptor:nil operation:[NSString stringWithFormat:@"%@%@ %@",READ_RESPONSE,DATA_SEPERATOR,[Utilities convertDataToLoggerFormat:updatedValue]]];
|
}
|
|
|
|
|
@end
|