Subversion Repositories Projects

Rev

Rev 805 | Details | Compare with Previous | 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
#import "SynthesizeSingleton.h"
26
#import "MKConnectionController.h"
27
#import "NSData+MKCommandDecode.h"
28
#import "NSData+MKCommandEncode.h"
29
#import "NSData+MKPayloadDecode.h"
30
#import "MKDataConstants.h"
31
#import "MKHost.h"
32
#import "MKIpConnection.h"
33
 
34
// ///////////////////////////////////////////////////////////////////////////////
35
 
36
NSString * const MKConnectedNotification = @"MKConnectedNotification";
37
NSString * const MKDisconnectedNotification = @"MKDisconnectedNotification";
38
NSString * const MKDisconnectErrorNotification = @"MKDisconnectErrorNotification";
39
 
40
NSString * const MKVersionNotification = @"MKVersionNotification";
41
NSString * const MKDebugDataNotification = @"MKDebugDataNotification";
42
NSString * const MKDebugLabelNotification = @"MKDebugLabelNotification";
43
NSString * const MKLcdMenuNotification = @"MKLcdMenuNotification";
44
NSString * const MKLcdNotification = @"MKLcdNotification";
45
NSString * const MKReadSettingNotification = @"MKReadSettingNotification";
46
NSString * const MKWriteSettingNotification = @"MKWriteSettingNotification";
47
NSString * const MKChangeSettingNotification = @"MKChangeSettingNotification";
48
 
49
NSString * const MKChannelValuesNotification = @"MKChannelValuesNotification";
50
 
51
NSString * const MKReadMixerNotification = @"MKReadMixerNotification";
52
NSString * const MKWriteMixerNotification = @"MKWriteMixerNotification";
53
 
54
NSString * const MKOsdNotification = @"MKOsdNotification";
55
 
56
// ///////////////////////////////////////////////////////////////////////////////
57
 
58
@implementation MKConnectionController
59
 
60
// -------------------------------------------------------------------------------
61
 
62
//@synthesize hostOrDevice;
63
//@synthesize inputController;
64
 
65
@synthesize primaryDevice;
66
@synthesize currentDevice;
67
 
68
-(void) setCurrentDevice:(MKAddress)theAddress {
69
 
70
//  if(primaryDevice==MKAddressNC) {
71
    if(theAddress != currentDevice) {
72
      currentDevice=theAddress;
73
 
74
      if(currentDevice==MKAddressNC)
75
      {
76
        uint8_t bytes[5];
77
        bytes[0] = 0x1B;
78
        bytes[1] = 0x1B;
79
        bytes[2] = 0x55;
80
        bytes[3] = 0xAA;
81
        bytes[4] = 0x00;
82
        bytes[5] = '\r';
83
 
84
        NSData * data = [NSData dataWithBytes:&bytes length:6];
85
 
86
        [self sendRequest:data];
87
 
88
      }
89
      else {
90
        uint8_t byte=0;
91
 
92
        switch (currentDevice) {
93
          case MKAddressFC:
94
            byte=0;
95
            break;
96
          case MKAddressMK3MAg:
97
            byte=1;
98
            break;
99
        }
100
 
101
        NSData * data = [NSData dataWithCommand:MKCommandRedirectRequest
102
                                     forAddress:MKAddressNC
103
                                 payloadForByte:byte];
104
 
105
        [self sendRequest:data];
106
      }
107
    }
108
 // }
109
}
110
 
111
 
112
SYNTHESIZE_SINGLETON_FOR_CLASS(MKConnectionController);
113
 
114
// -------------------------------------------------------------------------------
115
 
116
- (void) dealloc {
117
  [hostOrDevice release];
118
  [inputController release];
119
  [shortVersions[MKAddressFC] release];
120
  [shortVersions[MKAddressNC] release];
121
  [shortVersions[MKAddressMK3MAg] release];
122
  [longVersions[MKAddressMK3MAg] release];
123
  [longVersions[MKAddressNC] release];
124
  [longVersions[MKAddressMK3MAg] release];
125
  [super dealloc];
126
}
127
 
128
// -------------------------------------------------------------------------------
129
 
130
- (void) start:(MKHost*)host {
131
 
132
  if (![inputController isConnected]) {
133
 
134
    Class nsclass = NSClassFromString(host.connectionClass);
135
    if (!nsclass) {
136
      nsclass = [MKIpConnection class];
137
    }
138
 
139
    [inputController release];
140
    inputController = [[nsclass alloc] initWithDelegate:self];
141
 
142
    [hostOrDevice release];
143
    hostOrDevice = [NSString stringWithFormat:@"%@:%d",host.address,host.port];
144
    [hostOrDevice retain];
145
 
146
    didPostConnectNotification = NO;
147
 
148
    currentDevice=MKAddressAll;
149
    primaryDevice=MKAddressAll;
150
 
151
    NSError * err = nil;
152
    if (![inputController connectTo:hostOrDevice error:&err]) {
153
      NSLog(@"Error: %@", err);
154
    }
155
  }
156
}
157
 
158
- (void) stop {
159
  if ([inputController isConnected]) {
160
    DLog(@"disconnect");
161
    [inputController disconnect];
162
  }
163
 
164
//  self.inputController=nil;
165
 
166
}
167
 
168
- (BOOL) isRunning;
169
{
170
  return [inputController isConnected];
171
}
172
 
173
- (void) sendRequest:(NSData *)data;
174
{
175
  DLog(@"%@",data);
176
  NSString * msg = [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
177
  DLog(@"%@", msg);
178
 
179
  [inputController writeMkData:data];
180
}
181
 
182
- (NSString *) shortVersionForAddress:(MKAddress)theAddress;
183
{
184
  if (theAddress <= MKAddressAll || theAddress > MKAddressMK3MAg)
185
    return nil;
186
  return shortVersions[theAddress];
187
}
188
 
189
- (NSString *) longVersionForAddress:(MKAddress)theAddress;
190
{
191
  if (theAddress <= MKAddressAll || theAddress > MKAddressMK3MAg)
192
    return nil;
193
  return longVersions[theAddress];
194
}
195
 
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
#pragma mark -
198
 
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
- (BOOL) hasNaviCtrl {
201
  return primaryDevice==MKAddressNC;
202
}
203
 
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
- (void) activateNaviCtrl {
206
 
207
  if(primaryDevice!=MKAddressAll && ![self hasNaviCtrl])
208
    return;
209
 
210
  uint8_t bytes[5];
211
  bytes[0] = 0x1B;
212
  bytes[1] = 0x1B;
213
  bytes[2] = 0x55;
214
  bytes[3] = 0xAA;
215
  bytes[4] = 0x00;
216
  bytes[5] = '\r';
217
 
218
  NSData * data = [NSData dataWithBytes:&bytes length:6];
219
  [self sendRequest:data];
220
 
221
  currentDevice=MKAddressNC;
222
}
223
 
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225
- (void) activateFlightCtrl {
226
 
227
  if(![self hasNaviCtrl])
228
    return;
229
 
230
  uint8_t byte=0;
231
  NSData * data = [NSData dataWithCommand:MKCommandRedirectRequest
232
                               forAddress:MKAddressNC
233
                           payloadForByte:byte];
234
 
235
  [self sendRequest:data];
236
  currentDevice=MKAddressFC;
237
}
238
 
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240
- (void) activateMK3MAG {
241
 
242
  if(![self hasNaviCtrl])
243
    return;
244
 
245
  uint8_t byte=1;
246
  NSData * data = [NSData dataWithCommand:MKCommandRedirectRequest
247
                               forAddress:MKAddressNC
248
                           payloadForByte:byte];
249
 
250
  [self sendRequest:data];
251
  currentDevice=MKAddressMK3MAg;
252
}
253
 
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255
- (void) activateMKGPS {
256
 
257
  if(![self hasNaviCtrl])
258
    return;
259
 
260
  uint8_t byte=3;
261
  NSData * data = [NSData dataWithCommand:MKCommandRedirectRequest
262
                               forAddress:MKAddressNC
263
                           payloadForByte:byte];
264
 
265
  [self sendRequest:data];
266
  currentDevice=MKAddressMKGPS;
267
}
268
 
269
 
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271
#pragma mark -
272
#pragma mark MKInputDelegate
273
 
274
 
275
- (void) requestPrimaryDeviceVersion {
276
  NSData * data = [NSData dataWithCommand:MKCommandVersionRequest
277
                               forAddress:MKAddressAll
278
                         payloadWithBytes:NULL
279
                                   length:0];
280
 
281
  [self sendRequest:data];
282
}
283
 
284
- (void) didConnectTo:(NSString *)hostOrDevice {
285
 
286
  [self activateNaviCtrl];
287
  [self performSelector:@selector(requestPrimaryDeviceVersion) withObject:self afterDelay:0.1];
288
}
289
 
290
- (void) willDisconnectWithError:(NSError *)err {
291
  NSDictionary * d = [NSDictionary dictionaryWithObjectsAndKeys:err, @"error", nil];
292
 
293
  NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
294
 
295
  [nc postNotificationName:MKDisconnectErrorNotification object:self userInfo:d];
296
}
297
 
298
- (void) didDisconnect {
299
  NSDictionary * d = nil;
300
 
301
  NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
302
 
303
  [nc postNotificationName:MKDisconnectedNotification object:self userInfo:d];
304
 
305
}
306
 
307
- (void) setVersionsFrom:(NSDictionary *)d forAddress:(MKAddress)address  {
308
  if (address != MKAddressAll) {
309
 
310
    [shortVersions[address] release];
311
    shortVersions[address] = [[d objectForKey:kMKDataKeyVersion] retain];
312
 
313
    [longVersions[address] release];
314
    longVersions[address] = [[d objectForKey:kMKDataKeyVersionShort] retain];
315
  }
316
}
317
 
318
- (void) didReadMkData:(NSData *)data {
319
 
806 - 320
  NSData * strData = [data subdataWithRange:NSMakeRange(0, [data length] - 1)];
805 - 321
 
322
  NSString * msg = [[[NSString alloc] initWithData:strData encoding:NSASCIIStringEncoding] autorelease];
323
  DLog(@">>%@<<", msg);
324
 
325
  if ([strData isCrcOk]) {
326
//    DLog(@"Data length %d",[strData length]);
327
 
328
    NSData * payload = [strData payload];
329
    MKAddress address = [strData address];
330
    NSDictionary * d = nil;
331
    NSString * n = nil;
332
 
333
    switch ([strData command]) {
334
      case MKCommandLcdMenuResponse:
335
        n = MKLcdMenuNotification;
336
        d = [payload decodeLcdMenuResponseForAddress:address];
337
        break;
338
      case MKCommandLcdResponse:
339
        n = MKLcdNotification;
340
        d = [payload decodeLcdResponseForAddress:address];
341
        break;
342
      case MKCommandDebugLabelResponse:
343
        n = MKDebugLabelNotification;
344
        d = [payload decodeAnalogLabelResponseForAddress:address];
345
        break;
346
      case MKCommandDebugValueResponse:
347
        n = MKDebugDataNotification;
348
        d = [payload decodeDebugDataResponseForAddress:address];
349
        break;
350
      case MKCommandChannelsValueResponse:
351
        n = MKChannelValuesNotification;
352
        d = [payload decodeChannelsDataResponse];
353
        break;
354
      case MKCommandReadSettingsResponse:
355
        n = MKReadSettingNotification;
356
        d = [payload decodeReadSettingResponse];
357
        break;
358
      case MKCommandWriteSettingsResponse:
359
        n = MKWriteSettingNotification;
360
        d = [payload decodeWriteSettingResponse];
361
        break;
362
      case MKCommandMixerReadResponse:
363
        n = MKReadMixerNotification;
364
        d = [payload decodeMixerReadResponse];
365
        break;
366
      case MKCommandMixerWriteResponse:
367
        n = MKWriteMixerNotification;
368
        d = [payload decodeMixerWriteResponse];
369
        break;
370
 
371
      case MKCommandChangeSettingsResponse:
372
        n = MKChangeSettingNotification;
373
        d = [payload decodeChangeSettingResponse];
374
        break;
375
      case MKCommandOsdResponse:
376
        n = MKOsdNotification;
377
        d = [payload decodeOsdResponse];
378
        break;
379
      case MKCommandVersionResponse:
380
        n = MKVersionNotification;
381
        d = [payload decodeVersionResponseForAddress:address];
382
        [self setVersionsFrom:d forAddress:address];
383
        if (!didPostConnectNotification) {
384
 
385
          currentDevice=address;
386
          primaryDevice=address;
387
          DLog(@"Connected to primaryDevice %d, currentDevice %d",primaryDevice,currentDevice);
388
 
389
          NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
390
          [nc postNotificationName:MKConnectedNotification object:self userInfo:nil];
391
        }
392
        break;
393
      default:
394
        break;
395
    }
396
 
397
    if (d)
398
      DLog(@"(%d) %@", [d retainCount],d );
399
 
400
    NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
401
    [nc postNotificationName:n object:self userInfo:d];
402
 
403
//    if (d)
404
//      DLog(@"(%d)", [d retainCount] );
405
 
406
  } else {
407
    NSString * msg = [[[NSString alloc] initWithData:strData encoding:NSASCIIStringEncoding] autorelease];
408
    DLog(@"%@", msg);
409
  }
410
}
411
 
412
@end
413
 
414