Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
805 - 1
// ///////////////////////////////////////////////////////////////////////////////
2
// Copyright (C) 2010, Frank Blumenberg
3
//
4
// See License.txt for complete licensing and attribution information.
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
// THE SOFTWARE.
22
//
23
// ///////////////////////////////////////////////////////////////////////////////
24
 
25
 
26
#import "MKFakeConnection.h"
27
#import "NSData+MKCommandDecode.h"
28
#import "NSData+MKCommandEncode.h"
29
#import "NSData+MKPayloadDecode.h"
30
#import "NSData+MKPayloadEncode.h"
31
 
32
#import "MKDataConstants.h"
33
 
34
static NSString * const MKDummyConnectionException = @"MKDummyConnectionException";
35
 
36
@interface MKFakeConnection (Private)
37
 
38
- (void) doConnect;
39
- (void) doDisconnect;
40
- (void) doResponseMkData:(NSData*)data;
41
 
42
@end
43
 
44
@implementation MKFakeConnection
45
 
46
#pragma mark Properties
47
 
48
@synthesize delegate;
49
 
50
#pragma mark Initialization
51
 
52
- (id) init {
53
  return [self initWithDelegate:nil];
54
}
55
 
56
- (id) initWithDelegate:(id)theDelegate;
57
{
58
  if (self = [super init]) {
59
    self.delegate = theDelegate;
60
 
61
    NSString *path = [[NSBundle mainBundle] pathForResource:@"AllSettings"
62
                                                     ofType:@"plist"];
63
 
64
    settings = [[NSMutableArray arrayWithContentsOfFile:path] retain];
65
 
66
    activeSetting = 3;
67
  }
68
  return self;
69
}
70
 
71
- (void) dealloc {
72
  [settings release];
73
  [super dealloc];
74
}
75
 
76
#pragma mark -
77
#pragma mark MKInput
78
 
79
- (BOOL) connectTo:(NSString *)hostOrDevice error:(NSError **)err;
80
{
81
  if (delegate == nil) {
82
    [NSException raise:MKDummyConnectionException
83
                format:@"Attempting to connect without a delegate. Set a delegate first."];
84
  }
85
 
86
  NSArray * hostItems = [hostOrDevice componentsSeparatedByString:@":"];
87
  if ( [hostItems count] != 2 ) {
88
    [NSException raise:MKDummyConnectionException
89
                format:@"Attempting to connect without a port. Set a port first."];
90
 
91
  }
92
 
93
  int port = [[hostItems objectAtIndex:1] intValue];
94
  NSString * host = [hostItems objectAtIndex:0];
95
 
96
  DLog(@"Try to connect to %@ on port %d", host, port);
97
 
98
  [self performSelector:@selector(doConnect) withObject:nil afterDelay:0.5];
99
  return YES;
100
}
101
 
102
- (BOOL) isConnected;
103
{
104
  return isConnected;
105
}
106
 
107
- (void) disconnect;
108
{
109
  [self performSelector:@selector(doDisconnect) withObject:nil afterDelay:0.1];
110
}
111
 
112
- (void) writeMkData:(NSData *)data;
113
{
114
  [self performSelector:@selector(doResponseMkData:) withObject:[data retain] afterDelay:0.1];
115
}
116
 
117
#pragma mark -
118
 
119
 
120
- (NSData*) versionResponse;
121
{
122
  VersionInfo v;
123
  v.SWMajor = 0;
124
  v.SWMinor = 78;
125
  v.ProtoMajor = 3;
126
  v.ProtoMinor = 1;
127
  v.SWPatch = 3;
128
  NSData * payload = [NSData dataWithBytes:(void*)&v length:sizeof(v)];
129
  return payload;
130
}
131
 
132
- (NSData*) debugResponse;
133
{
134
  DebugOut d;
135
  NSData * payload = [NSData dataWithBytes:(void*)&d length:sizeof(d)];
136
  return payload;
137
}
138
 
139
- (NSData*) channelResponse;
140
{
141
  int16_t data[26];
142
 
143
  for (int i=0; i<26; i++) {
144
    data[i]=random()%250;
145
  }
146
 
147
  NSData * payload = [NSData dataWithBytes:(void*)&data length:sizeof(data)];
148
  return payload;
149
}
150
 
151
 
152
 
153
- (NSData*) menuResponse:(NSData*)payload {
154
 
155
  const char * bytes = [payload bytes];
156
 
157
  uint8_t key=(uint8_t)bytes[0];
158
//  uint8_t interval=(uint8_t)bytes[1];
159
 
160
  if (key==0xFD) {
161
    menuPage++;
162
  } else if (key==0xFE) {
163
    menuPage--;
164
  }
165
 
166
  menuPage %= 16;
167
  menuCounter = 1;
168
 
169
  NSString* screen=[NSString stringWithFormat:@"Page %02d (%d)---------12345678901234567890abcdefghijklmnopqrst++++++++++++++++++++",
170
                    menuPage,menuCounter];
171
 
172
  NSData * newPayload = [screen dataUsingEncoding:NSASCIIStringEncoding];
173
 
174
  [self performSelector:@selector(resendMenuResponse) withObject:nil afterDelay:0.5];
175
 
176
  return newPayload;
177
}
178
 
179
- (void) resendMenuResponse {
180
 
181
  NSString* screen=[NSString stringWithFormat:@"Page %02d (%d)---------12345678901234567890abcdefghijklmnopqrst++++++++++++++++++++",
182
                    menuPage,menuCounter];
183
 
184
  NSData * newPayload = [screen dataUsingEncoding:NSASCIIStringEncoding];
185
 
186
  NSData * rspData = [newPayload dataWithCommand:MKCommandLcdResponse forAddress:MKAddressFC];
187
 
188
  if ( [delegate respondsToSelector:@selector(didReadMkData:)] ) {
189
    [delegate didReadMkData:rspData];
190
  }
191
 
192
  if ( (++menuCounter)<2 ) {
193
    [self performSelector:@selector(resendMenuResponse) withObject:nil afterDelay:0.5];
194
  }
195
}
196
 
197
 
198
 
199
- (NSData*) changeSettingsResponse:(NSData*)payload {
200
 
201
  const char * bytes = [payload bytes];
202
 
203
  uint8_t index=(uint8_t)bytes[0];
204
 
205
  activeSetting = index;
206
 
207
  NSData * newPayload = [NSData dataWithBytes:(void*)&index length:sizeof(index)];
208
  return newPayload;
209
 
210
}
211
 
212
- (NSData*) writeSettingResponse:(NSData*)payload {
213
 
214
  NSDictionary* d = [payload decodeReadSettingResponse];
215
 
216
  NSNumber* theIndex = [d objectForKey:kMKDataKeyIndex];
217
  uint8_t index = [theIndex unsignedCharValue];
218
 
219
  [settings replaceObjectAtIndex:index-1 withObject:d];
220
 
221
  NSData * newPayload = [NSData dataWithBytes:(void*)&index length:sizeof(index)];
222
  return newPayload;
223
}
224
 
225
- (NSData*) readSettingResponse:(NSData*)payload {
226
 
227
  const char * bytes = [payload bytes];
228
 
229
  uint8_t index=(uint8_t)bytes[0];
230
 
231
  if (index==0xFF) {
232
    index=activeSetting;
233
  }
234
 
235
  index--;
236
 
237
  NSDictionary* d = [settings objectAtIndex:index];
238
 
239
  DLog(@"%@",d);
240
 
241
  NSData * newPayload = [NSData payloadForWriteSettingRequest:d];
242
 
243
  return newPayload;
244
}
245
 
246
#pragma mark -
247
 
248
- (void) doConnect {
249
 
250
  isConnected=YES;
251
  if ( [delegate respondsToSelector:@selector(didConnectTo:)] ) {
252
    [delegate didConnectTo:@"Dummy"];
253
  }
254
 
255
  NSData * data = [NSData dataWithCommand:MKCommandVersionRequest
256
                               forAddress:MKAddressAll
257
                         payloadWithBytes:NULL
258
                                   length:0];
259
 
260
  [self writeMkData:data];
261
}
262
 
263
 
264
- (void) doDisconnect {
265
  isConnected=NO;
266
  if ( [delegate respondsToSelector:@selector(didDisconnect)] ) {
267
    [delegate didDisconnect];
268
  }
269
}
270
 
271
- (void) doResponseMkData:(NSData*)data {
272
 
273
  if ([data isCrcOk]) {
274
 
275
    NSData * payload = [data payload];
276
//    MKAddress address = [data address];
277
 
278
    NSData * rspPayload;
279
    MKCommandId rspCommand;  
280
 
281
    DLog(@"Need responde for command %c",[data command]);
282
 
283
    switch ([data command]) {
284
/*
285
      case MKCommandLcdMenuResponse:
286
        n = MKLcdMenuNotification;
287
        d = [payload decodeLcdMenuResponse];
288
        break;
289
      case MKCommandLcdResponse:
290
        n = MKLcdNotification;
291
        d = [payload decodeLcdResponse];
292
        break;
293
      case MKCommandDebugLabelResponse:
294
        n = MKDebugLabelNotification;
295
        d = [payload decodeAnalogLabelResponse];
296
        break;
297
*/
298
      case MKCommandLcdRequest:
299
        rspPayload = [self menuResponse:payload];
300
        rspCommand = MKCommandLcdResponse;
301
        break;
302
      case MKCommandDebugValueRequest:
303
        rspPayload = [self debugResponse];
304
        rspCommand = MKCommandDebugValueResponse;
305
        break;
306
      case MKCommandChannelsValueRequest:
307
        rspPayload = [self channelResponse];
308
        rspCommand = MKCommandChannelsValueResponse;
309
        break;
310
      case MKCommandVersionRequest:
311
        rspPayload = [self versionResponse];
312
        rspCommand = MKCommandVersionResponse;
313
        break;
314
      case MKCommandChangeSettingsRequest:
315
        rspPayload = [self changeSettingsResponse:payload];
316
        rspCommand = MKCommandChangeSettingsResponse;
317
        break;
318
      case MKCommandReadSettingsRequest:
319
        rspPayload = [self readSettingResponse:payload];
320
        rspCommand = MKCommandReadSettingsResponse;
321
        break;
322
      case MKCommandWriteSettingsRequest:
323
        rspPayload = [self writeSettingResponse:payload];
324
        rspCommand = MKCommandWriteSettingsResponse;
325
        break;
326
      case MKCommandEngineTestRequest:
327
        DLog(@"Engine Test %@",payload);
328
        [data release];
329
        return;
330
      default:
331
        ALog(@"Unknown command %c",[data command]);
332
        [data release];
333
        return;
334
    }
335
 
336
    NSData * rspData = [rspPayload dataWithCommand:rspCommand forAddress:MKAddressFC];
337
 
338
    if ( [delegate respondsToSelector:@selector(didReadMkData:)] ) {
339
      [delegate didReadMkData:rspData];
340
    }
341
 
342
  }  
343
 
344
  [data release];
345
}
346
 
347
@end