summaryrefslogtreecommitdiff
path: root/examples/osx/avb_viewer/AVB Viewer/OutlineViewController.m
blob: 6dd0d227310b4081006cce35233103beb46375bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//
//  OutlineViewController.m
//  AVB Viewer
//
//  Created by John Gildred on 10/29/13.
//  Copyright (c) 2013 AVB.io. All rights reserved.
//

#import "OutlineViewController.h"

#define kIconImageSize          16.0

@implementation OutlineViewController

NSString *avbDevicesChanged = @"AVBCHANGED";
NSString *interfaceName;

- (id)init {
    self = [super init];
    if (self) {
        _avbDevices = [[NSMutableArray alloc] init];
        
        // Test device insertion
        //AvbDevice *newDevice = [[AvbDevice alloc] initWithId: @"Test Switch"];
        //[newDevice addChild:[[AvbDevice alloc] initWithId: @"Test Talker"]];
        //[self.avbDevices addObject:newDevice];
        
        [self getLocalInterface];
        //[self createLocalEntity];  Not used yet
        [self resetDiscovery];
    }
    return self;
}

- (void)updateDetailView:(AvbDevice *)avbDevice {
    NSImage *image = avbDevice.image;
    [image setSize:NSMakeSize(64, 64)];
    [_detailsImage setImage:                 image];
    [_detailsName setStringValue:            avbDevice.name ? avbDevice.name : @"-"];
    [_detailsDeviceId setStringValue:        avbDevice.deviceId ? avbDevice.deviceId : @"-"];
    [_detailsModelId setStringValue:         avbDevice.modelId ? avbDevice.modelId : @"-"];
    [_detailsVendorId setStringValue:        avbDevice.vendorId ? avbDevice.vendorId : @"-"];
    [_detailsIsTalker setStringValue:        avbDevice.isTalker ? @"YES" : @"NO"];
    [_detailsIsListener setStringValue:      avbDevice.isListener ? @"YES" : @"NO"];
    [_detailsIsController setStringValue:    avbDevice.isController ? @"YES" : @"NO"];
    [_detailsTalkerStreams setStringValue:   avbDevice.talkerSources ? [NSString stringWithFormat:@"%u", avbDevice.talkerSources] : @"-"];
    [_detailsListenerStreams setStringValue: avbDevice.listenerSinks ? [NSString stringWithFormat:@"%u", avbDevice.listenerSinks] : @"-"];
    [_detailsTalkerType setStringValue:      avbDevice.talkerType ? avbDevice.talkerType : @"-"];
    [_detailsListenerType setStringValue:    avbDevice.listenerType ? avbDevice.listenerType : @"-"];
    AVBMACAddress *address = (avbDevice.macAddresses.count > 0) ? [avbDevice.macAddresses objectAtIndex:0] : [[AVBMACAddress alloc] init];
    [_detailsMacAddresses setStringValue:    [address.stringRepresentation substringFromIndex:(address.stringRepresentation.length - 17)]];
}

- (void)updateDeviceList:(NSNotification *)notification {

}

- (IBAction)add:(id)sender {
    NSLog ( @"Adding...");
    AvbDevice *device = [self.outlineView itemAtRow:[self.outlineView selectedRow]];
    if (device) {
        [device addChild:[[AvbDevice alloc] init]];
    }
    else {
        [self.avbDevices addObject:[[AvbDevice alloc] init]];
    }
    [self.outlineView reloadData];
}

- (IBAction)remove:(id)sender {
    NSLog ( @"Removing...");
    AvbDevice *device = [self.outlineView itemAtRow:[self.outlineView selectedRow]];
    AvbDevice *parent = [self.outlineView parentForItem:device];
    if (parent) {
        [parent removeChild:device];
    }
    else if (device) {
        [self.avbDevices removeObject:device];
    }
    [self.outlineView reloadData];
}

- (id)getLocalInterface {
    NSString *interfaceName;
    NSArray *interfaces = [AVBEthernetInterface supportedInterfaces];
    NSString *result = interfaces ? [interfaces componentsJoinedByString: @", "] : @"NONE";
    NSLog ( @"AVB interfaces: %@", result );
    
    if (interfaces && ([interfaces count] > 0)) {
        interfaceName = interfaces[0];
        NSString *capable = [AVBInterface isAVBEnabledOnInterfaceNamed: interfaceName] ? @"YES" : @"NO";
        NSLog ( @"Support AVB? %@", capable );
        NSString *enabled = [AVBInterface isAVBEnabledOnInterfaceNamed: interfaceName] ? @"YES" : @"NO";
        NSLog ( @"Enabled for AVB? %@", enabled );
    }
    return interfaces[0];
}

- (id)createLocalEntity {
    AVB17221EntityDiscovery *disco = [[AVB17221EntityDiscovery alloc] init];
    NSError *__autoreleasing err = [[NSError alloc] init];
    AVB17221Entity *entity = [[AVB17221Entity alloc] init];
    [disco addLocalEntity:entity error:&err];
    [disco setInterfaceName:@"en3"];
    [entity setTalkerStreamSources:1];
    [entity setEntityID:666666];
    [entity setLocalEntity:YES];
    AVB17221ACMPInterface *acmp = [[AVB17221ACMPInterface alloc] init];
    return acmp;
}

- (void)resetDiscovery {
    // Check interfaces and log result to the console
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDeviceList:) name:avbDevicesChanged object:nil];
    _avbInterface = [[AVBInterface alloc] initWithInterfaceName: interfaceName];
    [self.avbInterface.entityDiscovery setDiscoveryDelegate:self];
    [self.avbInterface.entityDiscovery primeIterators];
    [self.avbInterface.entityDiscovery discoverEntities];
}

- (IBAction)refresh:(id)sender {
    [self.avbInterface.entityDiscovery setDiscoveryDelegate:self];
    [self.avbInterface.entityDiscovery primeIterators];
    [self.avbInterface.entityDiscovery discoverEntities];
}

- (IBAction)changedSelection:(id)sender {
    AvbDevice *device = [self.outlineView itemAtRow:[self.outlineView selectedRow]];
    [self updateDetailView:device];
}

#pragma mark NSOutlineView Data Source Methods

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    return !item ? [self.avbDevices count] : [[item children] count];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return !item ? NO : [[item children] count] != 0;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    return !item ? [self.avbDevices objectAtIndex:index] : [[item children] objectAtIndex:index];
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    if ([[tableColumn identifier] isEqualToString: @"name"]) {
        return [item name];
    }
    else {
        return @"";
    }
}

- (id)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    if ([[tableColumn identifier] isEqualToString: @"name"]) {
        NSTableCellView *result = [outlineView makeViewWithIdentifier:tableColumn.identifier owner:self];
        [result.textField setStringValue:[item name]];
        NSImage *image = [item image];
		[image setSize:NSMakeSize(64, 64)];
        [result.imageView setImage:image];
        return result;
    }
    else {
        return nil;
    }
}

- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    [(AvbDevice *)item setName:object];
}

// AVB Discovery Stuff

- (AvbDevice *)deviceExistsWithEntity:(AVB17221Entity *)entity {
    AvbDevice *matchedDevice;
    NSString *deviceId = [NSString stringWithFormat:@"0x00%llx", [entity entityID]];
    for (AvbDevice *device in self.avbDevices) {
        if ([device.deviceId isEqualToString: deviceId]) {
            matchedDevice = device;
        }
    }
    return matchedDevice;
};

- (void)updateDevicesWithEntity:(AVB17221Entity *)entity {
    AvbDevice *device = [self deviceExistsWithEntity:entity];
    if (device) {
        [device updateFromEntity:entity];
    }
    else {
        AvbDevice *newDevice = [[AvbDevice alloc] initWithEntity:entity];
        [self.avbDevices addObject: newDevice];
    }
}

- (void)didAddRemoteEntity:(AVB17221Entity *)newEntity on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Found something remote: %@", newEntity );
    if (![self deviceExistsWithEntity:newEntity]) {
        AvbDevice *newDevice = [[AvbDevice alloc] initWithEntity:newEntity];
        [self.avbDevices addObject: newDevice];
        [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
    }
};

- (void)didRemoveRemoteEntity:(AVB17221Entity *)oldEntity on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Lost something remote: %@", oldEntity );
    AvbDevice *device = [self deviceExistsWithEntity:oldEntity];
    if (device) {
        [self.avbDevices removeObject: device];
        [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
    }
};

- (void)didRediscoverRemoteEntity:(AVB17221Entity *)entity on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Rediscovered something remote: %@", entity );
    [self updateDevicesWithEntity:entity];
    [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
};

- (void)didUpdateRemoteEntity:(AVB17221Entity *)entity changedProperties:(AVB17221EntityPropertyChanged)changedProperties on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Updated something remote: %@", entity );
    [self updateDevicesWithEntity:entity];
    [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
};

- (void)didAddLocalEntity:(AVB17221Entity *)newEntity on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Found something local: %@", newEntity );
    if (![self deviceExistsWithEntity:newEntity]) {
        AvbDevice *newDevice = [[AvbDevice alloc] initWithEntity:newEntity];
        [self.avbDevices addObject: newDevice];
        [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
    }
};

- (void)didRemoveLocalEntity:(AVB17221Entity *)oldEntity on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Lost something local: %@", oldEntity );
    AvbDevice *device = [self deviceExistsWithEntity:oldEntity];
    if (device) {
        [self.avbDevices removeObject: device];
        [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
    }
};

- (void)didRediscoverLocalEntity:(AVB17221Entity *)entity on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Rediscovered something local: %@", entity );
    [self updateDevicesWithEntity:entity];
    [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
};

- (void)didUpdateLocalEntity:(AVB17221Entity *)entity changedProperties:(AVB17221EntityPropertyChanged)changedProperties on17221EntityDiscovery:(AVB17221EntityDiscovery *)entityDiscovery {
    NSLog ( @"Updated something local: %@", entity );
    [self updateDevicesWithEntity:entity];
    [[NSNotificationCenter defaultCenter] postNotificationName:avbDevicesChanged object:nil];
};

@end