CommunicationProtocol.m 7.36 KB
//
//  CommunicationProtocol.m
//  DUREX Vendor Control
//
//  Created by Imanol Barba on 5/23/14.
//  Copyright (c) 2014 Emmoco. All rights reserved.
//

#import "CommunicationProtocol.h"

@interface CommunicationProtocol ()

@end

@implementation CommunicationProtocol

+ (id)sharedProtocol {
    static CommunicationProtocol *shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[self alloc] init];
    });
    return shared;
}

-(Boolean) waitForMessageAvailable: (Boolean) status
{
    uint8_t retries = 0;
    while([self messageAvailable] != status)
    {
        [NSThread sleepForTimeInterval:5];
        if([self messageAvailable] != status)
        {
            if(retries++ == MAX_RETRIES)
            {
                return FALSE;
            }
        }
    }
    return TRUE;
}

-(NSString*) readMessage
{
    __block uint8_t numPackets, numBytes;
    __block NSMutableString *message;
    [message setString:@""];
    if([self waitForMessageAvailable:TRUE])
    {
        [[EMConnectionManager sharedManager] readResource:@"numPackets" onSuccess:^(id readValue)
         {
             numPackets = (uint8_t) [readValue unsignedCharValue];
         }
                                                   onFail:^(NSError *error)
         {
             NSLog(@"[CommunicationProtocol.m]: %@",error);
             numPackets = 0;
         }];
        if(numPackets)
        {
            for(int i = 0; i < numPackets; i++)
            {
                [[EMConnectionManager sharedManager] readResource:@"numBytes" onSuccess:^(id readValue)
                 {
                     numBytes = (uint8_t) [readValue unsignedCharValue];
                 }
                                                           onFail:^(NSError *error)
                 {
                     NSLog(@"[CommunicationProtocol.m]: %@",error);
                     numBytes = 0;
                 }];
                if(numBytes)
                {
                    [[EMConnectionManager sharedManager] readResource:@"data" onSuccess:^(id readValue)
                     {
                         [message appendString:[readValue stringValue]];
                     }
                                                               onFail:^(NSError *error)
                     {
                         NSLog(@"[CommunicationProtocol.m]: %@",error);
                     }];
                }
            }
        }
    }
    [[EMConnectionManager sharedManager] writeValue:@"FALSE" toResource:@"messageAvailable" onSuccess:^
     {
         
     }
                                             onFail:^(NSError *error)
     {
         NSLog(@"[CommunicationProtocol.m]: %@",error);
     }
     ];
    return message;
}

-(Boolean) writeMessage: (NSString*) message
{
    unsigned long remainingBytes = [message length];
    uint8_t numBytes, current_index = 0;
    __block Boolean status = FALSE;
    [[EMConnectionManager sharedManager] writeValue:[NSNumber numberWithUnsignedChar:(unsigned char)([message length]/MAX_STRING_LENGTH)+1] toResource:@"numPackets" onSuccess:^
     {
         status = TRUE;
     }
                                             onFail:^(NSError *error)
     {
         NSLog(@"[CommunicationProtocol.m]: %@",error);
         status = FALSE;
     }
     ];
    if(status != FALSE)
    {
        while(remainingBytes)
        {
            if(![self waitForMessageAvailable:FALSE])
            {
                status = FALSE;
                break;
            }
            if(remainingBytes > MAX_STRING_LENGTH)
            {
                numBytes = MAX_STRING_LENGTH;
                remainingBytes -= MAX_STRING_LENGTH;
            }
            else
            {
                numBytes = remainingBytes;
                remainingBytes = 0;
            }
            [[EMConnectionManager sharedManager] writeValue:[NSNumber numberWithUnsignedChar:(unsigned char)numBytes] toResource:@"numBytes" onSuccess:^
             {
                 status = TRUE;
             }
                                                     onFail:^(NSError *error)
             {
                 NSLog(@"[CommunicationProtocol.m]: %@",error);
                 status = FALSE;
             }
             ];
            if(status != FALSE)
            {
                NSString *data = [message substringWithRange:NSMakeRange(current_index, numBytes)];
                current_index += numBytes;
                [[EMConnectionManager sharedManager] writeValue:data toResource:@"data" onSuccess:^
                 {
                     status = TRUE;
                 }
                                                         onFail:^(NSError *error)
                 {
                     NSLog(@"[CommunicationProtocol.m]: %@",error);
                     status = FALSE;
                 }
                 ];
                if(status != FALSE)
                {
                    [[EMConnectionManager sharedManager] writeValue:@"TRUE" toResource:@"messageAvailable" onSuccess:^
                     {
                         status = TRUE;
                     }
                                                             onFail:^(NSError *error)
                     {
                         NSLog(@"[CommunicationProtocol.m]: %@",error);
                         status = FALSE;
                     }
                     ];
                }
            }
        }
    }
    return status;
}

-(Boolean) establishConnection
{
    if([self writeMessage:@"Hello"])
    {
        NSString *answer = [self readMessage];
        if([answer isEqualToString:@"Hello"])
        {
            return TRUE;
        }
    }
    return FALSE;
}

-(Boolean) updateTime: (NSDateComponents*) date
{
    if(date == nil)
    {
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
        date = [calendar components:units fromDate:[NSDate date]];
    }
    NSMutableString *command = [NSMutableString stringWithFormat: @"A5"];
    NSInteger year = [date year];
    year = year - (year/100)*100;
    [command appendString:[NSString stringWithFormat:@"%02d",year]];
    [command appendString:[NSString stringWithFormat:@"%02d%02d%02d%02d%02d",[date month],[date day],[date hour],[date minute],[date second]]];
    [self writeMessage:command];
    NSString *answer = [self readMessage];
    if([answer isEqualToString:@"P51"])
    {
        return TRUE;
    }
    return FALSE;
}

-(Boolean) updatePrice: (uint8_t) channel : (uint8_t) product : (uint8_t) eur : (uint8_t) cents
{
    NSMutableString *command = [NSMutableString stringWithFormat: @"A6%01d%01d%02d%02d",channel,product,eur,cents];
    [self writeMessage:command];
    NSString *answer = [self readMessage];
    if([answer isEqualToString:@"P61"])
    {
        return TRUE;
    }
    return FALSE;
}

-(Boolean) updateProductName: (uint8_t) channel : (uint8_t) product : (NSString*) name
{
    if([name length] > MAX_PRODUCT_NAME_LENGTH)
    {
        name = [name substringToIndex:MAX_PRODUCT_NAME_LENGTH-1];
    }
    NSMutableString *command = [NSMutableString stringWithFormat: @"A7%01d%01d%@",channel,product,name];
    [self writeMessage:command];
    NSString *answer = [self readMessage];
    if([answer isEqualToString:@"P71"])
    {
        return TRUE;
    }
    return FALSE;
}

@end