// Look on a given connection for the device static INDEX_OR_ERROR CheckThisConnection(int bus_nr, struct parsedname *pn) { struct parsedname s_pn_copy; struct parsedname * pn_copy = &s_pn_copy ; struct connection_in * in = find_connection_in(bus_nr) ; INDEX_OR_ERROR connection_result = INDEX_BAD ; if ( in == NO_CONNECTION ) { return INDEX_BAD ; } memcpy(pn_copy, pn, sizeof(struct parsedname)); // shallow copy pn_copy->selected_connection = in; if ( BAD( TestConnection(pn_copy) ) ) { // Connection currently disconnected return INDEX_BAD; } else if (BusIsServer(in)) { // Server if ( INDEX_VALID( ServerPresence(pn_copy) ) ) { connection_result = in->index; } } else if ( in->iroutines.flags & ADAP_FLAG_sham ) { return INDEX_BAD ; } else if ( in->iroutines.flags & ADAP_FLAG_presence_from_dirblob ) { // local connection with a dirblob (like fake, mock, ...) if ( GOOD( PresenceFromDirblob( pn_copy ) ) ) { connection_result = in->index ; } } else { // local connection but need to ask directly struct transaction_log t[] = { TRXN_NVERIFY, TRXN_END, }; if ( GOOD( BUS_transaction(t, pn_copy) ) ) { connection_result = in->index ; } } if ( connection_result == INDEX_BAD ) { LEVEL_DEBUG("Presence of "SNformat" NOT found on bus %s",SNvar(pn_copy->sn),SAFESTRING(DEVICENAME(in))) ; } else { LEVEL_DEBUG("Presence of "SNformat" FOUND on bus %s",SNvar(pn_copy->sn),SAFESTRING(DEVICENAME(in))) ; Cache_Add_Device(in->index,pn_copy->sn) ; // add or update cache */ } return connection_result ; }
/** The BUS_next function does a general search. This function continues from the previous search state (held in struct device_search). The search state can be reset by using the BUS_first function. Returns: 0=No problems, 1=Problems Sets LastDevice=1 if no more */ enum search_status BUS_next(struct device_search *ds, const struct parsedname *pn) { switch ( BUS_next_3try(ds, pn) ) { case search_good: // found a device in a directory search, add to "presence" cache LEVEL_DEBUG("Device found: " SNformat, SNvar(ds->sn)); Cache_Add_Device(pn->selected_connection->index,ds->sn) ; return search_good ; case search_done: BUS_next_cleanup(ds); return search_done; case search_error: default: BUS_next_cleanup(ds); return search_error; } }
/* Get a device that isn't a serial number -- see if it's an alias */ static enum parse_enum Parse_Alias(char *filename, enum parse_pass remote_status, struct parsedname *pn) { INDEX_OR_ERROR bus ; // See if the alias is known in the permanent list. We get the serial number if ( GOOD( Cache_Get_Alias_SN(filename,pn->sn)) ) { // Success! The alias is already registered and the serial // number just now loaded in pn->sn return Parse_Alias_Known( filename, remote_status, pn ) ; } // By definition this is a remote device, or non-existent. pn->selected_device = &RemoteDevice ; // is alias name cached from previous query? bus = Cache_Get_Alias_Bus( filename ) ; if ( bus != INDEX_BAD ) { // This alias is cached in temporary list SetKnownBus(bus, pn); return parse_prop ; } // Look for alias in remote buses bus = RemoteAlias(pn) ; if ( bus == INDEX_BAD ) { return parse_error ; } // Found the alias (remotely) SetKnownBus(bus, pn); if ( pn->sn[0] == 0 && pn->sn[7]==0 ) { // no serial number owserver (older) Cache_Add_Alias_Bus(filename,bus) ; } else { Cache_Add_Alias( filename, pn->sn ) ; Cache_Add_Device( bus, pn->sn ) ; pn->selected_device = FS_devicefindhex(pn->sn[0], pn); } return parse_prop ; }
/* Check if device exists -- >=0 yes, -1 no */ INDEX_OR_ERROR CheckPresence(struct parsedname *pn) { INDEX_OR_ERROR bus_nr; if (NotRealDir(pn)) { return INDEX_DEFAULT; } if ((pn->selected_device == DeviceSimultaneous) || (pn->selected_device == DeviceThermostat)) { return INDEX_DEFAULT; } /* If set, already found bus. */ /* Use UnsetKnownBus to clear and allow a new search */ if (KnownBus(pn)) { return pn->known_bus->index; } if ( GOOD( Cache_Get_Device(&bus_nr, pn)) ) { LEVEL_DEBUG("Found device on bus %d",bus_nr); SetKnownBus(bus_nr, pn); return bus_nr; } LEVEL_DETAIL("Checking presence of %s", SAFESTRING(pn->path)); bus_nr = CheckPresence_low(pn); // check only allocated inbound connections if ( INDEX_VALID(bus_nr) ) { SetKnownBus(bus_nr, pn); Cache_Add_Device( bus_nr, pn->sn ) ; return bus_nr; } UnsetKnownBus(pn); return INDEX_BAD; }