|
1
2
3
4
5
6
7
8
9
10
11
12
|
//
// 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 ()
|
|
13
14
|
@property Boolean messageAvailableMobile;
@property Boolean messageAvailableDevice;
|
|
15
16
17
18
|
@property NSMutableString *message;
@property NSUInteger currentIndex;
@property NSUInteger remainingBytes;
@property NSInteger numPackets;
|
|
19
|
|
|
20
21
22
23
|
@end
@implementation CommunicationProtocol
|
|
24
25
|
+ (id)sharedProtocol
{
|
|
26
27
28
29
|
static CommunicationProtocol *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[self alloc] init];
|
|
30
31
|
[shared setMessageAvailableDevice:FALSE];
[shared setMessageAvailableMobile:FALSE];
|
|
32
33
34
35
|
});
return shared;
}
|
|
36
|
-(void) readMessage
|
|
37
|
{
|
|
38
|
[self setMessage:[NSMutableString stringWithFormat:@""]];
|
|
39
|
self.numPackets = -1;
|
|
40
|
[self waitForMessage: 0];
|
|
41
42
|
}
|
|
43
|
- (void) readNextFragment
|
|
44
|
{
|
|
45
|
__block NSUInteger numBytes;
|
|
46
|
[[EMConnectionManager sharedManager] readResource:@"numBytes" onSuccess:^(id readValue)
|
|
47
|
{
|
|
48
49
50
|
numBytes = [readValue unsignedCharValue];
NSLog(@"[CommunicationProtocol.m]: numBytes read: %d",numBytes);
[[EMConnectionManager sharedManager] readResource:@"data" onSuccess:^(id readValue)
|
|
51
|
{
|
|
52
53
54
55
56
57
|
/*
* BUG: If previously sent message is longer than the response, the excess bytes are appended to the response
* coming from the device. Trimming is applied to correct that. A possible cause may be a bug in the device's
* code, not the app
*/
//NSString *readData = readValue;
|
|
58
59
|
NSString *readData = [readValue substringToIndex:numBytes];
if([readValue length] < numBytes)
|
|
60
|
{
|
|
61
62
63
64
65
66
67
68
69
70
|
NSLog(@"[CommunicationProtocol.m]: WARNING: Device issued wrong numBytes, possible truncated message.");
}
[self.message appendString:readData];
NSLog(@"[CommunicationProtocol.m]: data read: %@",readData);
[[EMConnectionManager sharedManager] writeValue:@"0" toResource:@"messageAvailableDevice" onSuccess:^
{
NSLog(@"[CommunicationProtocol.m]: messageAvailableDevice set to FALSE");
NSLog(@"[CommunicationProtocol.m]: packet read");
self.numPackets--;
if(self.numPackets)
|
|
71
|
{
|
|
72
|
[self waitForMessage: 0];
|
|
73
74
|
}
else
|
|
75
|
{
|
|
76
77
|
[[self delegate] processMessage:self didFinishEnteringItem:self.message];
}
|
|
78
79
|
}onFail:^(NSError *error)
{
|
|
80
81
|
NSLog(@"[CommunicationProtocol.m]: On setMessageAvailableDevice to FALSE: %@",error);
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while reading answer from device",nil),[error localizedDescription]]];
|
|
82
83
84
|
}];
}onFail:^(NSError *error)
{
|
|
85
86
|
NSLog(@"[CommunicationProtocol.m]: On readData: %@",error);
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while reading answer from device",nil),[error localizedDescription]]];
|
|
87
|
}];
|
|
88
|
}onFail:^(NSError *error)
|
|
89
|
{
|
|
90
91
92
|
NSLog(@"[CommunicationProtocol.m]: On readNumBytes: %@",error);
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while reading answer from device",nil),[error localizedDescription]]];
}];
|
|
93
94
|
}
|
|
95
|
- (void) readNumPackets
|
|
96
|
{
|
|
97
|
[[EMConnectionManager sharedManager] readResource:@"numPackets" onSuccess:^(id readValue)
|
|
98
|
{
|
|
99
100
101
102
103
104
|
self.numPackets = [readValue unsignedCharValue];
NSLog(@"[CommunicationProtocol.m]: numPackets read: %d",self.numPackets);
[self readNextFragment];
}onFail:^(NSError *error)
{
NSLog(@"[CommunicationProtocol.m]: On readNumPackets: %@",error);
|
|
105
|
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while reading answer from device",nil),[error localizedDescription]]];
|
|
106
|
}];
|
|
107
108
|
}
|
|
109
|
- (void) waitForMessage: (uint8_t) retries
|
|
110
|
{
|
|
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
if(retries == MAX_RETRIES)
{
NSLog(@"[CommunicationProtocol.m]: Device not ready.");
NSLog(@"[CommunicationProtocol.m]: Timeout while expecting message");
}
else
{
NSLog(@"[CommunicationProtocol.m]: Reading messageAvailable from device");
[[EMConnectionManager sharedManager] readResource:@"messageAvailableDevice" onSuccess:^(id readValue)
{
[self setMessageAvailableDevice:[readValue intValue]];
if(![self messageAvailableDevice])
{
NSLog(@"[CommunicationProtocol.m]: Device not ready. Retrying...");
[NSThread sleepForTimeInterval:SLEEP_TIME];
[self waitForMessage:retries + 1];
}
else
{
if(self.numPackets == -1)
{
[self readNumPackets];
}
else
{
[self readNextFragment];
}
}
}onFail:^(NSError *error)
{
NSLog(@"[CommunicationProtocol.m]: On waitForMessage: %@",error);
|
|
142
|
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while reading answer from device",nil),[error localizedDescription]]];
|
|
143
144
|
}];
}
|
|
145
146
|
}
|
|
147
|
-(void) writeMessage: (NSString*) message
|
|
148
|
{
|
|
149
150
151
152
|
NSLog(@"[CommunicationProtocol.m]: Sending message: %@",message);
[self setMessage:[NSMutableString stringWithString:message]];
[self setRemainingBytes:[message length]];
[self setCurrentIndex:0];
|
|
153
154
|
[[EMConnectionManager sharedManager] writeValue:[NSNumber numberWithUnsignedChar:(unsigned char)([message length]/MAX_STRING_LENGTH)+1] toResource:@"numPackets" onSuccess:^
{
|
|
155
|
NSLog(@"[CommunicationProtocol.m]: numPackets set to %u",([message length]/MAX_STRING_LENGTH) + 1);
|
|
156
157
|
[self sendNextFragment];
}onFail:^(NSError *error)
|
|
158
|
{
|
|
159
|
NSLog(@"[CommunicationProtocol.m]: On setNumPackets: %@",error);
|
|
160
|
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while sending command to device",nil),[error localizedDescription]]];
|
|
161
162
163
164
165
|
}];
}
- (void) sendNextFragment
{
|
|
166
|
if(self.remainingBytes)
|
|
167
|
{
|
|
168
|
NSLog(@"[CommunicationProtocol.m]: Sending next fragment");
|
|
169
|
NSUInteger numBytes;
|
|
170
|
if(self.remainingBytes > MAX_STRING_LENGTH)
|
|
171
|
{
|
|
172
173
|
numBytes = MAX_STRING_LENGTH;
self.remainingBytes -= MAX_STRING_LENGTH;
|
|
174
175
176
|
}
else
{
|
|
177
178
|
numBytes = self.remainingBytes;
self.remainingBytes = 0;
|
|
179
|
}
|
|
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
[[EMConnectionManager sharedManager] writeValue:[NSNumber numberWithUnsignedChar:(unsigned char)numBytes] toResource:@"numBytes" onSuccess:^
{
NSLog(@"[CommunicationProtocol.m]: numBytes set to %d", numBytes);
NSString *data = [self.message substringWithRange:NSMakeRange(self.currentIndex, numBytes)];
self.currentIndex += numBytes;
[[EMConnectionManager sharedManager] writeValue:data toResource:@"data" onSuccess:^
{
NSLog(@"[CommunicationProtocol.m]: data set to: %@",data);
[[EMConnectionManager sharedManager] writeValue:@"1" toResource:@"messageAvailableMobile" onSuccess:^
{
NSLog(@"[CommunicationProtocol.m]: messageAvailableMobile set to TRUE");
NSLog(@"[CommunicationProtocol.m]: Packet written");
[self readACK: 0];
}onFail:^(NSError *error)
{
NSLog(@"[CommunicationProtocol.m]: On setMessageAvailable to TRUE: %@",error);
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while sending command to device",nil),[error localizedDescription]]];
}];
}onFail:^(NSError *error)
{
NSLog(@"[CommunicationProtocol.m]: On setData: %@",error);
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while sending command to device",nil),[error localizedDescription]]];
}];
}onFail:^(NSError *error)
{
NSLog(@"[CommunicationProtocol.m]: On setNumBytes: %@",error);
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while sending command to device",nil),[error localizedDescription]]];
}];
}
else
|
|
210
|
{
|
|
211
212
213
|
NSLog(@"[CommunicationProtocol.m]: Finished sending message");
[self readMessage];
}
|
|
214
215
|
}
|
|
216
|
- (void) readACK: (uint8_t) retries
|
|
217
|
{
|
|
218
|
if(retries == MAX_RETRIES)
|
|
219
|
{
|
|
220
221
222
223
224
225
226
|
NSLog(@"[CommunicationProtocol.m]: Device not ready.");
NSLog(@"[CommunicationProtocol.m]: Timeout while expecting ACK");
}
else
{
NSLog(@"[CommunicationProtocol.m]: Reading ACK from device");
[[EMConnectionManager sharedManager] readResource:@"messageAvailableMobile" onSuccess:^(id readValue)
|
|
227
|
{
|
|
228
229
|
[self setMessageAvailableMobile:[readValue intValue]];
if([self messageAvailableMobile])
|
|
230
|
{
|
|
231
232
233
234
235
|
NSLog(@"[CommunicationProtocol.m]: Device not ready. Retrying...");
[NSThread sleepForTimeInterval:SLEEP_TIME];
[self readACK:retries + 1];
}
else
|
|
236
|
{
|
|
237
238
239
|
[self sendNextFragment];
}
}onFail:^(NSError *error)
|
|
240
|
{
|
|
241
|
NSLog(@"[CommunicationProtocol.m]: On readACK: %@",error);
|
|
242
|
[[self delegate] reportProtocolError:self didFinishEnteringItem:[NSString stringWithFormat:@"%@: %@",NSLocalizedString(@"Error occurred while sending command to device",nil),[error localizedDescription]]];
|
|
243
244
|
}];
}
|
|
245
246
|
}
|
|
247
|
-(void) establishConnection
|
|
248
|
{
|
|
249
|
NSLog(@"[CommunicationProtocol.m]: Establishing connection...");
|
|
250
251
|
[self writeMessage:@"Hello"];
NSLog(@"[CommunicationProtocol.m]: Hello sent");
|
|
252
253
|
}
|
|
254
255
256
257
258
259
260
|
-(void) disconnect
{
NSLog(@"[CommunicationProtocol.m]: Terminating connection...");
[self writeMessage:@"Bye"];
NSLog(@"[CommunicationProtocol.m]: Bye sent");
}
|
|
261
|
-(void) updateTime: (NSDateComponents*) date
|
|
262
263
264
265
|
{
NSMutableString *command = [NSMutableString stringWithFormat: @"A5"];
NSInteger year = [date year];
year = year - (year/100)*100;
|
|
266
|
[command appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld%02ld%02ld",(long)year,(long)[date month],(long)[date day],(long)[date hour],(long)[date minute],(long)[date second]]];
|
|
267
268
269
|
[self writeMessage:command];
}
|
|
270
|
-(void) updatePrice: (uint8_t) channel : (uint8_t) product : (uint8_t) eur : (uint8_t) cents
|
|
271
272
273
274
275
|
{
NSMutableString *command = [NSMutableString stringWithFormat: @"A6%01d%01d%02d%02d",channel,product,eur,cents];
[self writeMessage:command];
}
|
|
276
|
-(void) updateProductName: (uint8_t) channel : (uint8_t) product : (NSString*) name
|
|
277
278
279
280
281
282
283
284
285
|
{
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];
}
|
|
286
|
-(void) readSensorData
|
|
287
288
289
|
{
NSString *command = @"A4";
[self writeMessage:command];
|
|
290
291
|
}
|
|
292
|
-(void) readSalesLog : (NSDateComponents*) start : (NSDateComponents*) end
|
|
293
|
{
|
|
294
295
|
NSMutableString *startDate = [NSMutableString stringWithString:@""];
NSMutableString *endDate = [NSMutableString stringWithString:@""];
|
|
296
297
298
299
300
301
302
|
NSMutableString *command = [NSMutableString stringWithString:@"A2"];
if(start == nil)
{
[startDate setString:@""];
}
else
{
|
|
303
304
|
NSInteger year = [start year];
year = year - (year/100)*100;
|
|
305
|
[startDate appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld%02ld",(long)year,(long)[start month],(long)[start day],(long)[start hour],(long)[start minute]]];
|
|
306
307
308
309
310
311
312
|
}
if(end == nil)
{
[endDate setString:@""];
}
else
{
|
|
313
314
|
NSInteger year = [end year];
year = year - (year/100)*100;
|
|
315
|
[endDate appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld%02ld",(long)year,(long)[end month],(long)[end day],(long)[end hour],(long)[end minute]]];
|
|
316
317
318
319
320
|
}
[command appendString:startDate];
[command appendString:@"-"];
[command appendString:endDate];
[self writeMessage:command];
|
|
321
322
|
}
|
|
323
324
325
326
327
328
329
330
331
332
333
334
335
|
-(void) readIncidentLog:(NSDateComponents *)start :(NSDateComponents *)end
{
NSMutableString *startDate = [NSMutableString stringWithString:@""];
NSMutableString *endDate = [NSMutableString stringWithString:@""];
NSMutableString *command = [NSMutableString stringWithString:@"A3"];
if(start == nil)
{
[startDate setString:@""];
}
else
{
NSInteger year = [start year];
year = year - (year/100)*100;
|
|
336
|
[startDate appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld%02ld",(long)year,(long)[start month],(long)[start day],(long)[start hour],(long)[start minute]]];
|
|
337
338
339
340
341
342
343
344
345
|
}
if(end == nil)
{
[endDate setString:@""];
}
else
{
NSInteger year = [end year];
year = year - (year/100)*100;
|
|
346
|
[endDate appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld%02ld",(long)year,(long)[end month],(long)[end day],(long)[end hour],(long)[end minute]]];
|
|
347
348
349
350
351
352
353
|
}
[command appendString:startDate];
[command appendString:@"-"];
[command appendString:endDate];
[self writeMessage:command];
}
|
|
354
|
@end
|