1// 2// Copyright (c) ZeroC, Inc. All rights reserved. 3// 4 5#import "ControllerView.h" 6 7#include <ifaddrs.h> 8#include <arpa/inet.h> 9#include <net/if.h> 10 11@implementation ControllerView 12 13- (void)viewDidLoad 14{ 15 [super viewDidLoad]; 16 17 // 18 // Load the controller bundle. 19 // 20 NSString* bundlePath = [[NSBundle mainBundle] privateFrameworksPath]; 21#ifdef ICE_CPP11_MAPPING 22 const char* bundle = "Cpp11ControllerBundle.bundle"; 23#else 24 const char* bundle = "Cpp98ControllerBundle.bundle"; 25#endif 26 bundlePath = [bundlePath stringByAppendingPathComponent:[NSString stringWithUTF8String:bundle]]; 27 28 NSURL* bundleURL = [NSURL fileURLWithPath:bundlePath]; 29 CFBundleRef handle = CFBundleCreate(NULL, (CFURLRef)bundleURL); 30 if(!handle) 31 { 32 [self println:[NSString stringWithFormat:@"Could not find bundle %@", bundlePath]]; 33 return; 34 } 35 36 CFErrorRef error = nil; 37 Boolean loaded = CFBundleLoadExecutableAndReturnError(handle, &error); 38 if(error != nil || !loaded) 39 { 40 [self println:[(__bridge NSError *)error description]]; 41 return; 42 } 43 44 startController = CFBundleGetFunctionPointerForName(handle, CFSTR("startController")); 45 if(startController == 0) 46 { 47 NSString* err = [NSString stringWithFormat:@"Could not get function pointer startController from bundle %@", 48 bundlePath]; 49 [self println:err]; 50 return; 51 } 52 53 stopController = CFBundleGetFunctionPointerForName(handle, CFSTR("stopController")); 54 if(stopController == 0) 55 { 56 NSString* err = [NSString stringWithFormat:@"Could not get function pointer stopController from bundle %@", 57 bundlePath]; 58 [self println:err]; 59 return; 60 } 61 62 // 63 // Search for local network interfaces 64 // 65 interfacesIPv4 = [NSMutableArray array]; 66 [interfacesIPv4 addObject:@"127.0.0.1"]; 67 interfacesIPv6 = [NSMutableArray array]; 68 [interfacesIPv6 addObject:@"::1"]; 69 struct ifaddrs* ifap; 70 if(getifaddrs(&ifap) == 0) 71 { 72 struct ifaddrs* curr = ifap; 73 while(curr != 0) 74 { 75 if(curr->ifa_addr && curr->ifa_flags & IFF_UP && !(curr->ifa_flags & IFF_LOOPBACK)) 76 { 77 if(curr->ifa_addr->sa_family == AF_INET) 78 { 79 char buf[INET_ADDRSTRLEN]; 80 const struct sockaddr_in *addr = (const struct sockaddr_in*)curr->ifa_addr; 81 if(inet_ntop(AF_INET, &addr->sin_addr, buf, INET_ADDRSTRLEN)) 82 { 83 [interfacesIPv4 addObject:[NSString stringWithUTF8String:buf]]; 84 } 85 } 86 else if(curr->ifa_addr->sa_family == AF_INET6) 87 { 88 char buf[INET6_ADDRSTRLEN]; 89 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)curr->ifa_addr; 90 if(inet_ntop(AF_INET6, &addr6->sin6_addr, buf, INET6_ADDRSTRLEN)) 91 { 92 [interfacesIPv6 addObject:[NSString stringWithUTF8String:buf]]; 93 } 94 } 95 } 96 curr = curr->ifa_next; 97 } 98 freeifaddrs(ifap); 99 } 100 101 // By default, use the loopback 102 [interfaceIPv4 selectRow:0 inComponent:0 animated:NO]; 103 [interfaceIPv6 selectRow:0 inComponent:0 animated:NO]; 104 (*startController)(self, 105 [interfacesIPv4 objectAtIndex:[interfaceIPv4 selectedRowInComponent:0]], 106 [interfacesIPv6 objectAtIndex:[interfaceIPv6 selectedRowInComponent:0]]); 107} 108 109- (void) dealloc 110{ 111 (*stopController)(self); 112} 113 114-(void) write:(NSString*)msg 115{ 116 [output insertText:msg]; 117 [output layoutIfNeeded]; 118 [output scrollRangeToVisible:NSMakeRange([output.text length] - 1, 1)]; 119} 120 121#pragma mark ControllerView 122 123-(void) print:(NSString*)msg 124{ 125 [self performSelectorOnMainThread:@selector(write:) withObject:msg waitUntilDone:NO]; 126} 127-(void) println:(NSString*)msg 128{ 129 [self print:[msg stringByAppendingString:@"\n"]]; 130} 131 132#pragma mark UIPickerViewDelegate 133 134- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 135{ 136 if(pickerView == interfaceIPv4) 137 { 138 return [interfacesIPv4 objectAtIndex:row]; 139 } 140 else 141 { 142 return [interfacesIPv6 objectAtIndex:row]; 143 } 144} 145 146- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 147{ 148 (*stopController)(self); 149 (*startController)(self, 150 [interfacesIPv4 objectAtIndex:[interfaceIPv4 selectedRowInComponent:0]], 151 [interfacesIPv6 objectAtIndex:[interfaceIPv6 selectedRowInComponent:0]]); 152} 153 154#pragma mark UIPickerViewDataSource 155 156- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 157{ 158 return 1; 159} 160 161- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 162{ 163 if(pickerView == interfaceIPv4) 164 { 165 return interfacesIPv4.count; 166 } 167 else 168 { 169 return interfacesIPv6.count; 170 } 171} 172 173@end 174