Beispiel #1
0
/* See if a cached location is accurate -- called with "Known Bus" set */
INDEX_OR_ERROR ReCheckPresence(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 (KnownBus(pn)) {
		if ( INDEX_VALID( CheckThisConnection(pn->known_bus->index,pn) ) ) {
			return pn->known_bus->index ;
		}
	}
	
	if ( GOOD( Cache_Get_Device(&bus_nr, pn)) ) {
		LEVEL_DEBUG("Found device on bus %d",bus_nr);
		if ( INDEX_VALID( CheckThisConnection(bus_nr,pn) ) ) {
			SetKnownBus(bus_nr, pn);
			return bus_nr ;
		}
	}
	
	UnsetKnownBus(pn);
	Cache_Del_Device(pn) ;
	return CheckPresence(pn);
}
Beispiel #2
0
static void * RemoteAlias_callback_conn(void * v)
{
	struct remotealias_struct * ras = (struct remotealias_struct *) v ;
	struct remotealias_struct ras_next ;
	pthread_t thread;
	int threadbad = 0;
	
	// set up for next server connection
	ras_next.cin = NextServer(ras->cin->next) ;
	if ( ras_next.cin == NO_CONNECTION ) {
		threadbad = 1 ;
	} else {
		ras_next.pin = ras->pin ;
		ras_next.pn = ras->pn ;
		ras_next.bus_nr = INDEX_BAD ;
		memset( ras_next.sn, 0, SERIAL_NUMBER_SIZE) ;
		threadbad = pthread_create(&thread, DEFAULT_THREAD_ATTR, RemoteAlias_callback_conn, (void *) (&ras_next)) ;
	}
	
	// Result for this server connection (while next one is processing)
	ras->bus_nr = ServerAlias( ras->sn, ras->cin, ras->pn ) ;
	
	if (threadbad == 0) {		/* was a thread created? */
		if (pthread_join(thread, NULL)==0) {
			// Set answer to the next bus if it's found
			// else use current answer
			if ( INDEX_VALID(ras_next.bus_nr) ) {
				ras->bus_nr = ras_next.bus_nr ;
				memcpy( ras->sn, ras_next.sn, SERIAL_NUMBER_SIZE ) ;
			}
		}
	}
	return VOID_RETURN ;
}
Beispiel #3
0
static void * CheckPresence_callback_port(void * v)
{
	struct checkpresence_struct * cps = (struct checkpresence_struct *) v ;
	struct checkpresence_struct cps_next ;
	pthread_t thread;
	int threadbad = 0 ;
	
	cps_next.pin = cps->pin->next ;
	if ( cps_next.pin == NULL ) {
		threadbad = 1 ;
	} else {
		cps_next.pn = cps->pn ;
		cps_next.bus_nr = INDEX_BAD ;
		threadbad = pthread_create(&thread, DEFAULT_THREAD_ATTR, CheckPresence_callback_port, (void *) (&cps_next)) ;
	}
	
	cps->cin = cps->pin->first ;
	if ( cps->cin != NO_CONNECTION ) {
		CheckPresence_callback_conn(v) ;
	}
			
	if (threadbad == 0) {		/* was a thread created? */
		if (pthread_join(thread, NULL)==0) {
			if ( INDEX_VALID(cps_next.bus_nr) ) {
				cps->bus_nr = cps_next.bus_nr ;
			}
		}
	}
	return VOID_RETURN ;
}
Beispiel #4
0
static INDEX_OR_ERROR CheckPresence_low(struct parsedname *pn)
{
	struct port_in * pin ;
	
	for ( pin=Inbound_Control.head_port ; pin ; pin=pin->next ) {
		struct connection_in * cin ;
		for ( cin=pin->first ; cin ; cin=cin->next ) {
			int bus_nr = CheckThisConnection( cin->index, pn ) ;
			if ( INDEX_VALID(bus_nr) ) {
				return bus_nr ;
			}
		}
	}
	return INDEX_BAD;				// no success
}
Beispiel #5
0
// 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 ;
}
Beispiel #6
0
INDEX_OR_ERROR RemoteAlias(struct parsedname *pn)
{
	struct port_in * pin ;
	
	for ( pin = Inbound_Control.head_port ; pin ; pin = pin->first ) {
		struct connection_in * cin ;
		
		for ( cin=NextServer(pin->first) ; cin ; cin=NextServer(cin->next) ) {
			BYTE sn[SERIAL_NUMBER_SIZE] ;
			INDEX_OR_ERROR bus_nr = ServerAlias( sn, cin, pn ) ;
			if ( INDEX_VALID(bus_nr) ) {
				memcpy( pn->sn, sn, SERIAL_NUMBER_SIZE ) ;
				LEVEL_DEBUG("Remote alias for %s bus=%d "SNformat,pn->path_to_server,bus_nr,SNvar(sn));
				return bus_nr ;
			}
		}
	}
	return INDEX_BAD;				// no success
}
Beispiel #7
0
void
uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx)
{
    uu_list_node_impl_t *np;

    np = INDEX_TO_NODE(idx);
    if (np == NULL)
        np = &lp->ul_null_node;

    if (lp->ul_debug) {
        if (!INDEX_VALID(lp, idx))
            uu_panic("uu_list_insert(%p, %p, %p): %s\n",
                     (void *)lp, elem, (void *)idx,
                     INDEX_CHECK(idx)? "outdated index" :
                     "invalid index");
        if (np->uln_prev == NULL)
            uu_panic("uu_list_insert(%p, %p, %p): out-of-date "
                     "index\n", (void *)lp, elem, (void *)idx);
    }

    list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
}
Beispiel #8
0
INDEX_OR_ERROR RemoteAlias(struct parsedname *pn)
{
	struct remotealias_struct ras ; 
	
	ras.pin = Inbound_Control.head_port ;
	ras.pn = pn ;
	ras.bus_nr = INDEX_BAD ;
	memset( ras.sn, 0, SERIAL_NUMBER_SIZE) ;

	if ( ras.pin != NULL ) {
		RemoteAlias_callback_port( (void *) (&ras) ) ;
	}
	
	memcpy( pn->sn, ras.sn, SERIAL_NUMBER_SIZE ) ;

	if ( INDEX_VALID( ras.bus_nr ) ) {
		LEVEL_DEBUG("Remote alias for %s bus=%d "SNformat,pn->path_to_server,ras.bus_nr,SNvar(ras.sn));
	} else {
		LEVEL_DEBUG("Remote alias for %s not found",pn->path_to_server);
	}
	return ras.bus_nr;		
}
Beispiel #9
0
/* 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;
}