bool CZeroconfBrowserOSX::doResolveService(CZeroconfBrowser::ZeroconfService &fr_service, double f_timeout) { bool ret = false; CFStringRef type = CFStringCreateWithCString(NULL, fr_service.GetType().c_str(), kCFStringEncodingUTF8); CFStringRef name = CFStringCreateWithCString(NULL, fr_service.GetName().c_str(), kCFStringEncodingUTF8); CFStringRef domain = CFStringCreateWithCString(NULL, fr_service.GetDomain().c_str(), kCFStringEncodingUTF8); CFNetServiceRef service = CFNetServiceCreate (NULL, domain, type, name, 0); if (CFNetServiceResolveWithTimeout(service, f_timeout, NULL) ) { std::string ip; int port = 0; ret = CopyFirstIPv4Address(service, ip, port); fr_service.SetIP(ip); fr_service.SetPort(port); //get txt-record list fr_service.SetTxtRecords(GetTxtRecords(service)); } CFRelease(type); CFRelease(name); CFRelease(domain); CFRelease(service); return ret; }
// netservice browser callback - calls whenever service is discovered void ofxBonjourIp::NetServiceBrowserCallBack(CFNetServiceBrowserRef browser,CFOptionFlags flags,CFTypeRef domainOrService,CFStreamError* error,void* info) { ofLog() << "----------------------"; if(error->error != 0) { ofLog() << "Error: " << error->error; return; } // unresovled still... but can get type and domain (pointless) CFNetServiceRef netServiceRef = (CFNetServiceRef) domainOrService; // casting to this thing //service removed/closed if (flags & kCFNetServiceFlagRemove) { ofLog() << "Service was removed."; if(info != NULL) { // notify service has been removed ofxBonjourIp* bonjour = (ofxBonjourIp*)info; ofNotifyEvent(bonjour->removedServiceEvent,bonjour->serverIp,bonjour); // reset bonjour->serverHostName = ""; bonjour->serverIp = ""; bonjour->connectedToService = false; // dont know if i need this? maybe causing a crash after long period of time. I don't think it's been added to the run loop yet either //CFNetServiceUnscheduleFromRunLoop(netServiceRef, CFRunLoopGetCurrent(),kCFRunLoopCommonModes); //CFNetServiceSetClient(netServiceRef, NULL, NULL); } return; } // the 'flags' property = 8 when it closes, and 0 when it opens. let's use that for now? /*if(flags != 0) { ofLog() << "Flag error/ service closed elsewhere (8): " << flags; return; }*/ // resolve the service CFNetServiceClientContext clientContext = { 0, info, NULL, NULL, NULL }; CFNetServiceSetClient(netServiceRef, ofxBonjourIp::NetServiceResolvedCallBack, &clientContext); CFNetServiceScheduleWithRunLoop(netServiceRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); if(!CFNetServiceResolveWithTimeout(netServiceRef, 0, NULL)) { ofLog() << "Error resolving service"; CFNetServiceUnscheduleFromRunLoop(netServiceRef, CFRunLoopGetCurrent(),kCFRunLoopCommonModes); CFNetServiceSetClient(netServiceRef, NULL, NULL); } }
static int _netservice_get_first_addr( CFNetServiceRef netService, socklen_t * size, struct sockaddr ** addr ) { CFArrayRef addresses; CFDataRef data; CFNetServiceCancel( netService ); CFNetServiceResolveWithTimeout( netService, 0.1, NULL ); addresses = CFNetServiceGetAddressing( netService ); if( addresses == NULL || CFArrayGetCount( addresses ) < 1 ) { return 1; } data = CFArrayGetValueAtIndex( addresses, 0 ); *size = CFDataGetLength( data ); *addr = CFDataGetBytePtr( data ); return 0; }