Esempio n. 1
0
void ZeroConfProtocol::addService( DNSSD::RemoteService::Ptr service )
{
    UDSEntry entry;
    entry.insert( UDSEntry::UDS_NAME,      service->serviceName() );
    entry.insert( UDSEntry::UDS_ACCESS,    0666);
    entry.insert( UDSEntry::UDS_FILE_TYPE, S_IFDIR );
    const QString iconName = KProtocolInfo::icon( knownProtocols[service->type()].protocol );
    if (!iconName.isNull())
        entry.insert( UDSEntry::UDS_ICON_NAME, iconName );

    listEntry( entry, false );
}
// TODO: each builder should refcount its services, so a shared one does not get removed to early
// (might disappear for one sd because of master breakdown)
void DNSSDNetworkBuilder::removeService( DNSSD::RemoteService::Ptr service )
{
    QList<NetDevice>& deviceList = mNetworkPrivate->deviceList();

    const QString hostName = service->hostName();

    // device
    QMutableListIterator<NetDevice> it( deviceList );
    while( it.hasNext())
    {
        const NetDevice& device = it.next();
        if( device.hostName() == hostName )
        {
// kDebug()<<hostName;
            QString id;
            const QString serviceType = service->type();
            foreach( const DNSSDNetSystemAble* factory, mNetSystemFactoryList )
            {
                if( factory->canCreateNetSystemFromDNSSD(serviceType) )
                {
                    id = factory->dnssdId( service );
                    break;
                }
            }
            NetDevicePrivate* d = device.dPtr();
            NetService netService = d->removeService( id );
            if( !netService.isValid() )
                break;

            QList<NetService> removedServices;
            removedServices.append( netService );
            mNetworkPrivate->emitServicesRemoved( removedServices );

            // remove device on last service
            if( d->serviceList().count() == 0 )
            {
                QList<NetDevice> removedDevices;
                removedDevices.append( device );
                // remove only after taking copy from reference into removed list
                it.remove();

                mNetworkPrivate->emitDevicesRemoved( removedDevices );
            }
            break;
        }
    }
Esempio n. 3
0
QString SimpleItemFactory::dnssdId( const DNSSD::RemoteService::Ptr& dnssdService ) const
{
    return dnssdService->type() + QLatin1Char('_') + dnssdService->serviceName();
}
void DNSSDNetworkBuilder::addService( DNSSD::RemoteService::Ptr service )
{
    QList<NetDevice>& deviceList = mNetworkPrivate->deviceList();

    QString hostName = service->hostName();
    // TODO: this blocks. and the ip address should be delivered from DNS-SD with resolve
    const QHostAddress hostAddress = DNSSD::ServiceBrowser::resolveHostName( hostName );
    const QString ipAddress = hostAddress.toString();
    // forget domain name if just ip address
    if( hostName == ipAddress )
        hostName.clear();

    // device TODO: only search for if we can create the service?
    NetDevicePrivate* d = 0;
    const NetDevice* deviceOfService = 0;
    foreach( const NetDevice& device, deviceList )
    {
        const QString deviceHostName = device.hostName();
        const bool useIpAddress = ( deviceHostName.isEmpty() || hostName.isEmpty() );
        const bool isSameAddress = useIpAddress ?
            ( device.ipAddress() == ipAddress ) :
            ( deviceHostName == hostName );
kDebug()<<"existing device:"<<deviceHostName<<"at"<<device.ipAddress()<<"vs."<<hostName<<"at"<<ipAddress<<":"<<isSameAddress;

        if( isSameAddress )
        {
            d = device.dPtr();
            // workaround: KDNSSD currently (4.7.0) emits two signals per service
            // just relying on service->serviceName() is fragile, but matches
            // current approach in removeService(...)
            QString id;
            const QString serviceType = service->type();
            foreach( const DNSSDNetSystemAble* factory, mNetSystemFactoryList )
            {
                if( factory->canCreateNetSystemFromDNSSD(serviceType) )
                {
                    id = factory->dnssdId( service );
                    break;
                }
            }
            if( d->hasService(id) )
                return;

            deviceOfService = &device;
            break;
        }
    }
    if( !d )
    {
        const QString deviceName = hostName.left( hostName.indexOf(QLatin1Char('.')) );
        d = new NetDevicePrivate( deviceName );
        d->setHostName( hostName );
        d->setIpAddress( ipAddress );
        NetDevice device( d );
        deviceList.append( device );
        deviceOfService = &deviceList.last();

        QList<NetDevice> newDevices;
        newDevices.append( device );
        // TODO: the new service will be announced two times, once with the new device and once alone.
        // what to do about that? which order? okay? for now just do not attach services before. find usecases.
        mNetworkPrivate->emitDevicesAdded( newDevices );
kDebug()<<"new device:"<<deviceName<<"at"<<hostName<<"by"<<service->type();
    }
    else
    {
        if( d->hostName().isEmpty() && ! hostName.isEmpty() )
            d->setHostName( hostName );
    }


    const QString serviceType = service->type();

    NetServicePrivate* netServicePrivate = 0;
    // do a priority based lookup who can build the object
    // TODO: priorisation
    foreach( const DNSSDNetSystemAble* factory, mNetSystemFactoryList )
    {
        if( factory->canCreateNetSystemFromDNSSD(serviceType) )
        {
            // TODO: here we should rather see if this service already exists
            netServicePrivate = factory->createNetService( service, *deviceOfService );
            break;
        }
    }
    // TODO: create dummy service
//     if( ! netServicePrivate )
//         netServicePrivate = new UnknownService;

    NetService netService( netServicePrivate );
    d->addService( netService );

    // try guessing the device type by the services on it
    // TODO: move into  devicefactory
    NetDevice::Type deviceTypeByService = NetDevice::Unknown;
    QString deviceName;
    if( serviceType == QLatin1String("_workstation._tcp") )
    {
        deviceTypeByService = NetDevice::Workstation;
        deviceName = service->serviceName().left( service->serviceName().lastIndexOf(QLatin1Char('[')) ).trimmed();
    }
    else if( serviceType == QLatin1String("_net-assistant._udp") )
    {
        deviceTypeByService = NetDevice::Workstation;
        deviceName = service->serviceName();
    }
    else if( serviceType == QLatin1String("_airport._tcp") )
        deviceTypeByService = NetDevice::Router;
    else if( serviceType == QLatin1String("_ipp._tcp")
             || serviceType == QLatin1String("_printer._tcp")
             || serviceType == QLatin1String("_pdl-datastream._tcp") )
    {
        deviceTypeByService = NetDevice::Printer;
        deviceName = service->serviceName();
    }

    if( deviceTypeByService != NetDevice::Unknown )
    {
        if( deviceTypeByService > d->type() )
        {
            d->setType( deviceTypeByService );
            if( ! deviceName.isEmpty() )
                d->setName( deviceName );
        }
    }

    QList<NetService> newServices;
    newServices.append( netService );
    mNetworkPrivate->emitServicesAdded( newServices );
}