Beispiel #1
0
/* Choose in order:
 * (first) 0x81
 * (first) 0x01
 * first other family
 * 0x00
 * */
GOOD_OR_BAD DS9490_ID_this_master(struct connection_in *in)
{
	struct dirblob db ;
	BYTE sn[SERIAL_NUMBER_SIZE] ;
	int device_number ;

	
	RETURN_BAD_IF_BAD( DS9490_root_dir( &db, in ) ) ;

	// Use 0x00 if no devices (homegrown adapters?)
	if ( DirblobElements( &db) == 0 ) {
		DirblobClear( &db ) ;
		memset( in->master.usb.ds1420_address, 0, SERIAL_NUMBER_SIZE ) ;
		LEVEL_DEFAULT("Set DS9490 %s unique id 0x00 (no devices at all)", SAFESTRING(DEVICENAME(in))) ;
		return gbGOOD ;
	}
	
	// look for the special 0x81 device
	device_number = 0 ;
	while ( DirblobGet( device_number, sn, &db ) == 0 ) {
		if (sn[0] == 0x81) {	// 0x81 family code
			memcpy(in->master.usb.ds1420_address, sn, SERIAL_NUMBER_SIZE);
			LEVEL_DEFAULT("Set DS9490 %s unique id to " SNformat, SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
			DirblobClear( &db ) ;
			return gbGOOD ;
		}
		++device_number ;
	}

	// look for the (less specific, for older DS9490s) 0x01 device
	device_number = 0 ;
	while ( DirblobGet( device_number, sn, &db ) == 0 ) {
		if (sn[0] == 0x01) {	// 0x01 family code
			memcpy(in->master.usb.ds1420_address, sn, SERIAL_NUMBER_SIZE);
			LEVEL_DEFAULT("Set DS9490 %s unique id to " SNformat, SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
			DirblobClear( &db ) ;
			return gbGOOD ;
		}
		++device_number ;
	}

	// Take the first device, whatever it is
	DirblobGet( 0, sn, &db ) ;
	memcpy(in->master.usb.ds1420_address, sn, SERIAL_NUMBER_SIZE);
	LEVEL_DEFAULT("Set DS9490 %s unique id to " SNformat, SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
	DirblobClear( &db ) ;
	return gbGOOD;
}
Beispiel #2
0
/* return 0 if good, 1 if not */
GOOD_OR_BAD Cache_Add_Device(const int bus_nr, const BYTE * sn)
{
	time_t duration = TimeOut(fc_presence);
	struct tree_node *tn;

	if (duration <= 0) {
		return gbGOOD;				/* in case timeout set to 0 */
	}

	if ( sn[0] == 0 ) { //bad serial number
		return gbGOOD ;
	}

	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + sizeof(int));
	if (!tn) {
		return gbBAD;
	}

	LEVEL_DEBUG("Adding device location " SNformat " bus=%d", SNvar(sn), (int) bus_nr);
	LoadTK(sn, Device_Marker, 0, tn );
	tn->expires = duration + NOW_TIME;
	tn->dsize = sizeof(int);
	memcpy(TREE_DATA(tn), &bus_nr, sizeof(int));
	return Add_Stat(&cache_dev, Cache_Add_Common(tn));
}
Beispiel #3
0
/* Look in caches, 0=found and valid, 1=not or uncachable in the first place */
GOOD_OR_BAD Cache_Get(void *data, size_t * dsize, const struct parsedname *pn)
{
	time_t duration;
	struct tree_node tn;
	int persistent ;

	// do check here to avoid needless processing
	if (IsUncachedDir(pn) || IsAlarmDir(pn)) {
		return gbBAD;
	}

	// Special handling of Mock
	persistent = IsThisPersistent(pn) ;
	if ( persistent ) {
		duration = 1 ;
	} else {
		duration = TimeOut(pn->selected_filetype->change);
		if (duration <= 0) {
			return gbBAD;				/* in case timeout set to 0 */
		}
	}


	LEVEL_DEBUG(SNformat " size=%d IsUncachedDir=%d", SNvar(pn->sn), (int) dsize[0], IsUncachedDir(pn));
	LoadTK( pn->sn, pn->selected_filetype, pn->extension, &tn );
	return persistent ?
		Get_Stat(&cache_pst, Cache_Get_Persistent(data, dsize, &duration, &tn)) :
		Get_Stat(&cache_ext, Cache_Get_Common(data, dsize, &duration, &tn));
}
Beispiel #4
0
/* Test for a  simultaneous property
If the property isn't independently cached, return false (1)
If the simultaneous conversion is more recent, return false (1)
Else return the cached value and true (0)
*/
GOOD_OR_BAD Cache_Get_Simul_Time(enum simul_type type, time_t * dwell_time, const struct parsedname * pn)
{
	// valid cached primary data -- see if a simultaneous conversion should be used instead
	struct tree_node tn;
	time_t duration ;
	time_t time_left ;
	size_t dsize_simul = 0 ;
	struct parsedname pn_directory ;

	duration = TimeOut(ipSimul[type].change); // time allocated this conversion
	if ( duration <= 0) {
		// uncachable
		return gbBAD;
	}

	LEVEL_DEBUG("Looking for conversion time "SNformat, SNvar(pn->sn));
	
	FS_LoadDirectoryOnly(&pn_directory, pn);
	LoadTK(pn_directory.sn, Simul_Marker[type], pn->selected_connection->index, &tn ) ;
	if ( Get_Stat(&cache_int, Cache_Get_Common(NULL, &dsize_simul, &time_left, &tn)) ) {
		return gbBAD ;
	}
	// duration_simul is time left
	// duration is time allocated
	// back-compute dwell time
	dwell_time[0] = duration - time_left ;
	return gbGOOD ;
}
Beispiel #5
0
static enum search_status DS9490_next_both(struct device_search *ds, const struct parsedname *pn)
{
	int dir_gulp_elements = (pn->ds2409_depth==0) ? DS2490_DIR_GULP_ELEMENTS : 1 ;

	// LOOK FOR NEXT ELEMENT
	++ds->index;
	LEVEL_DEBUG("Index %d", ds->index);

	if (ds->index % dir_gulp_elements == 0) {
		if (ds->LastDevice) {
			return search_done;
		}
		switch ( DS9490_directory(ds, pn) ) {
			case search_done:
				return search_done;
			case search_error:
				return search_error;
			case search_good:
				break;
		}
	}

	switch ( DirblobGet(ds->index % dir_gulp_elements, ds->sn, &(ds->gulp) ) ) {
		case 0:
			LEVEL_DEBUG("SN found: " SNformat, SNvar(ds->sn));
			return search_good;
		case -ENODEV:
		default:
			LEVEL_DEBUG("SN finished");
			return search_done;
	}
}
Beispiel #6
0
// Delete a serial number's alias
// Safe to call if no alias exists
// Also deletes from linked alias_sn file
void Cache_Del_Alias(const BYTE * sn)
{
	ASCII * alias_name ;
	struct tree_node *tn;
	size_t size ;

	alias_name = Cache_Get_Alias( sn ) ;
	if ( alias_name == NULL ) {
		// doesn't exist
		// (or a memory error -- unlikely)
		return ;
	}

	LEVEL_DEBUG("Deleting alias %s from "SNformat, alias_name, SNvar(sn)) ;
	size = strlen( alias_name ) ;
	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size + 1 );
	if ( tn != NULL ) {
		tn->expires = NOW_TIME;
		tn->dsize = size;
		memcpy((ASCII *)TREE_DATA(tn), alias_name, size+1); // includes NULL
		LoadTK( sn, Alias_Marker, 0, tn ) ;
		Del_Stat(&cache_pst, Cache_Del_Persistent(tn));
		Cache_Del_Alias_SN( alias_name ) ;
	}
	owfree( alias_name ) ;
}
Beispiel #7
0
/* return 0 if good, 1 if not */
GOOD_OR_BAD Cache_Add_SlaveSpecific(const void *data, const size_t datasize, const struct internal_prop *ip, const struct parsedname *pn)
{
	struct tree_node *tn;
	time_t duration;
	//printf("Cache_Add_SlaveSpecific\n");
	if (!pn) {
		return gbGOOD;				// do check here to avoid needless processing
	}

	duration = TimeOut(ip->change);
	if (duration <= 0) {
		return gbGOOD;				/* in case timeout set to 0 */
	}

	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + datasize);
	if (!tn) {
		return gbBAD;
	}

	LEVEL_DEBUG("Adding internal data for "SNformat " size=%d", SNvar(pn->sn), (int) datasize);
	LoadTK( pn->sn, ip->name, EXTENSION_INTERNAL, tn );
	tn->expires = duration + NOW_TIME;
	tn->dsize = datasize;
	if (datasize) {
		memcpy(TREE_DATA(tn), data, datasize);
	}
	//printf("ADD INTERNAL name= %s size=%d \n",tn->tk.p.nm,tn->dsize);
	//printf("  ADD INTERNAL data[0]=%d size=%d \n",((BYTE *)data)[0],datasize);
	switch (ip->change) {
	case fc_persistent:
		return Add_Stat(&cache_pst, Cache_Add_Persistent(tn));
	default:
		return Add_Stat(&cache_int, Cache_Add_Common(tn));
	}
}
Beispiel #8
0
static enum search_status LINK_next_both(struct device_search *ds, const struct parsedname *pn)
{
	struct connection_in * in = pn->selected_connection ;

	//Special case for DS2409 hub, use low-level code
	if ( pn->ds2409_depth>0 ) {
		return search_error ;
	}

	if (ds->LastDevice) {
		return search_done;
	}

	if (ds->index == -1) {
		if ( BAD(LINK_directory(ds, in)) ) {
			return search_error;
		}
	}

	// LOOK FOR NEXT ELEMENT
	++ds->index;
	LEVEL_DEBUG("Index %d", ds->index);

	switch ( DirblobGet(ds->index, ds->sn, &(ds->gulp) ) ) {
		case 0:
			LEVEL_DEBUG("SN found: " SNformat "", SNvar(ds->sn));
			return search_good;
		case -ENODEV:
		default:
			ds->LastDevice = 1;
			LEVEL_DEBUG("SN finished");
			return search_done;
	}
}
Beispiel #9
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 #10
0
enum search_status BUS_first_alarm(struct device_search *ds, const struct parsedname *pn)
{
	LEVEL_DEBUG("Start of directory path=%s device=" SNformat, SAFESTRING(pn->path), SNvar(pn->sn));
	// reset the search state
	BUS_first_both(ds);
	ds->search = _1W_CONDITIONAL_SEARCH_ROM;
	return BUS_next(ds, pn);
}
Beispiel #11
0
// very strange command to get out of test mode.
// Uses a different 1-wire command 
static GOOD_OR_BAD OW_out_of_test_mode( const struct parsedname * pn )
{
	BYTE out_of_test[] = { 0x96, SNvar(pn->sn), 0x3C, } ;
	struct transaction_log t[] = {
		TRXN_RESET,
		TRXN_WRITE(out_of_test, 1 + SERIAL_NUMBER_SIZE + 1 ),
		TRXN_END,
	};
	return BUS_transaction( t, pn ) ;
}	
Beispiel #12
0
/* return 0 if good, 1 if not */
GOOD_OR_BAD Cache_Add_Simul(const enum simul_type type, const struct parsedname *pn)
{
	// Note: pn already points to directory
	time_t duration = TimeOut(fc_volatile);
	struct tree_node *tn;

	if (pn==NO_PARSEDNAME || pn->selected_connection==NO_CONNECTION) {
		return gbGOOD;				// do check here to avoid needless processing
	}
	
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_fake:
		case bus_tester:
		case bus_mock:
		case bus_bad:
		case bus_unknown:
			return gbGOOD ;
		default:
			break ;
	}
	
	if (duration <= 0) {
		return gbGOOD;				/* in case timeout set to 0 */
	}
	
	// allocate space for the node and data
	LEVEL_DEBUG("Adding for conversion time for "SNformat, SNvar(pn->sn));
	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node));
	if (!tn) {
		return gbBAD;
	}
	
	LEVEL_DEBUG(SNformat, SNvar(pn->sn));
	
	// populate node with directory name and dirblob
	LoadTK( pn->sn, Simul_Marker[type], pn->selected_connection->index, tn) ;
	LEVEL_DEBUG("Simultaneous add type=%d",type);
	tn->expires = duration + NOW_TIME;
	tn->dsize = 0;
	return Add_Stat(&cache_dir, Cache_Add_Common(tn));
}
Beispiel #13
0
/* Run it as twalk(dababase, tree_show ) */
static void node_show(struct tree_node *tn)
{
	int i;
	char b[26];
	ctime_r(&tn->expires, b);
	fprintf(stderr,"\tNode " SNformat
		   " pointer=%p extension=%d length=%d start=%p expires=%s", SNvar(tn->tk.sn), tn->tk.p, tn->tk.extension, tn->dsize, tn, b ? b : "null\n");
	for (i = 0; i < sizeof(struct tree_key); ++i) {
		fprintf(stderr,"%.2X ", ((uint8_t *) tn)[i]);
	}
	fprintf(stderr,"\n");
}
Beispiel #14
0
/* return 0 if good, 1 if not */
GOOD_OR_BAD Cache_Add_Dir(const struct dirblob *db, const struct parsedname *pn)
{
	time_t duration = TimeOut(fc_directory);
	struct tree_node *tn;
	size_t size = DirblobElements(db) * SERIAL_NUMBER_SIZE;
	struct parsedname pn_directory;

	if (pn==NO_PARSEDNAME || pn->selected_connection==NO_CONNECTION) {
		return gbGOOD;				// do check here to avoid needless processing
	}
	
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_fake:
		case bus_tester:
		case bus_mock:
		case bus_w1:
		case bus_bad:
		case bus_unknown:
			return gbGOOD ;
		default:
			break ;
	}
	
	if (duration <= 0) {
		return 0;				/* in case timeout set to 0 */
	}

	if ( DirblobElements(db) < 1 ) {
		// only cache long directories.
		// zero (or one?) entry is possibly an error and needs to be repeated more quickly
		LEVEL_DEBUG("Won\'t cache empty directory");
		Cache_Del_Dir( pn ) ;
		return gbGOOD ;
	}
	
	// allocate space for the node and data
	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size);
	if (!tn) {
		return gbBAD;
	}
	
	LEVEL_DEBUG("Adding directory for " SNformat " elements=%d", SNvar(pn->sn), DirblobElements(db));
	
	// populate node with directory name and dirblob
	FS_LoadDirectoryOnly(&pn_directory, pn);
	LoadTK( pn_directory.sn, Directory_Marker, pn->selected_connection->index, tn );
	tn->expires = duration + NOW_TIME;
	tn->dsize = size;
	if (size) {
		memcpy(TREE_DATA(tn), db->snlist, size);
	}
	return Add_Stat(&cache_dir, Cache_Add_Common(tn));
}
Beispiel #15
0
/* Look in caches, 0=found and valid, 1=not or uncachable in the first place */
GOOD_OR_BAD Cache_Get_Device(void *bus_nr, const struct parsedname *pn)
{
	time_t duration = TimeOut(fc_presence);
	size_t size = sizeof(int);
	struct tree_node tn;
	if (duration <= 0) {
		return gbBAD;
	}

	LEVEL_DEBUG("Looking for device "SNformat, SNvar(pn->sn));
	LoadTK( pn->sn, Device_Marker, 0, &tn ) ;
	return Get_Stat(&cache_dev, Cache_Get_Common(bus_nr, &size, &duration, &tn));
}
Beispiel #16
0
/* Look in caches, 0=found and valid, 1=not or uncachable in the first place */
GOOD_OR_BAD Cache_Get_Dir(struct dirblob *db, const struct parsedname *pn)
{
	time_t duration = TimeOut(fc_directory);
	struct tree_node tn;
	struct parsedname pn_directory;
	DirblobInit(db);
	if (duration <= 0) {
		return gbBAD;
	}

	LEVEL_DEBUG("Looking for directory "SNformat, SNvar(pn->sn));
	FS_LoadDirectoryOnly(&pn_directory, pn);
	LoadTK( pn_directory.sn, Directory_Marker, pn->selected_connection->index, &tn) ;
	return Get_Stat(&cache_dir, Cache_Get_Common_Dir(db, &duration, &tn));
}
Beispiel #17
0
/* duration is time left */
static enum cache_task_return Cache_Get_Common(void *data, size_t * dsize, time_t * duration, const struct tree_node *tn)
{
	enum cache_task_return ctr_ret;
	time_t now = NOW_TIME;
	struct tree_opaque *opaque;
	
	LEVEL_DEBUG("Search in cache sn " SNformat " pointer=%p index=%d size=%d", SNvar(tn->tk.sn), tn->tk.p, tn->tk.extension, (int) dsize[0]);
	//node_show(tn);
	//new_tree();
	CACHE_RLOCK;
	opaque = tfind(tn, &cache.temporary_tree_new, tree_compare) ;
	if ( opaque == NULL ) {
		// not found in new tree
		if ( cache.time_retired + duration[0] > now ) {
			// retired time isn't too old for this data item
			opaque = tfind(tn, &cache.temporary_tree_old, tree_compare) ;
		}
	}
	if ( opaque != NULL ) {
		// modify duration to time left (can be negative if expired)
		duration[0] = opaque->key->expires - now ;
		if (duration[0] > 0) {
			LEVEL_DEBUG("Value found in cache. Remaining life: %d seconds.",duration[0]);
			// Compared with >= before, but fc_second(1) always cache for 2 seconds in that case.
			// Very noticable when reading time-data like "/26.80A742000000/date" for example.
			if ( dsize[0] >= opaque->key->dsize) {
				// lower data size if stored value is shorter
				dsize[0] = opaque->key->dsize;
				//tree_show(opaque,leaf,0);
				if (dsize[0] > 0) {
					memcpy(data, TREE_DATA(opaque->key), dsize[0]);
				}
				ctr_ret = ctr_ok;
				//twalk(cache.temporary_tree_new,tree_show) ;
			} else {
				ctr_ret = ctr_size_mismatch;
			}
		} else {
			LEVEL_DEBUG("Value found in cache, but expired by %d seconds.",-duration[0]);
			ctr_ret = ctr_expired;
		}
	} else {
		LEVEL_DEBUG("Value not found in cache");
		ctr_ret = ctr_not_found;
	}
	CACHE_RUNLOCK;
	return ctr_ret;
}
Beispiel #18
0
static SEQ_OR_ERROR w1_send_touch( const BYTE * data, size_t size, const struct parsedname *pn )
{
	struct w1_netlink_msg w1m;
	struct w1_netlink_cmd w1c;

	memset(&w1m, 0, W1_W1M_LENGTH);
	w1m.type = W1_MASTER_CMD;
	w1m.id.mst.id = pn->selected_connection->master.w1.id ;

	memset(&w1c, 0, W1_W1C_LENGTH);
	w1c.cmd = W1_CMD_TOUCH ;
	w1c.len = size ;

	LEVEL_DEBUG("Sending w1 send/receive data message for "SNformat,SNvar(pn->sn));
	return W1_send_msg( pn->selected_connection, &w1m, &w1c, data );
}
Beispiel #19
0
static SEQ_OR_ERROR w1_send_selecttouch( const BYTE * data, size_t size, const struct parsedname *pn )
{
	struct w1_netlink_msg w1m;
	struct w1_netlink_cmd w1c;

	memset(&w1m, 0, W1_W1M_LENGTH);
	w1m.type = W1_SLAVE_CMD;
	memcpy( w1m.id.id, pn->sn, 8) ;

	memset(&w1c, 0, W1_W1C_LENGTH);
	w1c.cmd = W1_CMD_TOUCH ;
	w1c.len = size ;

	LEVEL_DEBUG("Sending w1 select message for "SNformat,SNvar(pn->sn));
	return W1_send_msg( pn->selected_connection, &w1m, &w1c, data );
}
Beispiel #20
0
/* return 0 if good, 1 if not */
static GOOD_OR_BAD Cache_Add_Common(struct tree_node *tn)
{
	struct tree_opaque *opaque;
	enum { no_add, yes_add, just_update } state = no_add;

	node_show(tn);
	LEVEL_DEBUG("Add to cache sn " SNformat " pointer=%p index=%d size=%d", SNvar(tn->tk.sn), tn->tk.p, tn->tk.extension, tn->dsize);
	CACHE_WLOCK;
	if (cache.time_to_kill < NOW_TIME) {	// old database has timed out
		FlipTree() ;
	}
	if (Globals.cache_size && (cache.old_ram_size + cache.new_ram_size > Globals.cache_size)) {
		// failed size test
		owfree(tn);
	} else if ((opaque = tsearch(tn, &cache.temporary_tree_new, tree_compare))) {
		//printf("Cache_Add_Common to %p\n",opaque);
		if (tn != opaque->key) {
			cache.new_ram_size += sizeof(tn) - sizeof(opaque->key);
			owfree(opaque->key);
			opaque->key = tn;
			state = just_update;
		} else {
			state = yes_add;
			cache.new_ram_size += sizeof(tn);
		}
	} else {					// nothing found or added?!? free our memory segment
		owfree(tn);
	}
	CACHE_WUNLOCK;
	/* Added or updated, update statistics */
	switch (state) {
		case yes_add: // add new entry
			STATLOCK;
			AVERAGE_IN(&new_avg);
			++cache_adds;			/* statistics */
			STATUNLOCK;
			return gbGOOD;
		case just_update: // update the time mark and data
			STATLOCK;
			AVERAGE_MARK(&new_avg);
			++cache_adds;			/* statistics */
			STATUNLOCK;
			return gbGOOD;
		default: // unable to add
			return gbBAD;
	}
}
Beispiel #21
0
/** 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;
	}
}
Beispiel #22
0
/* look in persistent alias->sn tree */
static enum cache_task_return Cache_Get_Alias_Persistent( BYTE * sn, struct alias_tree_node * atn)
{
	struct tree_opaque *opaque;
	GOOD_OR_BAD ret = gbBAD ;

	PERSISTENT_RLOCK;
	opaque = tfind(atn, &cache.persistent_alias_tree, alias_tree_compare) ;
	if ( opaque != NULL ) {
		memcpy( sn, ((struct alias_tree_node *)(opaque->key))->sn, SERIAL_NUMBER_SIZE ) ;
		LEVEL_DEBUG("Lookup of %s gives "SNformat, CONST_ALIAS_TREE_DATA(atn), SNvar(sn) ) ;
		ret = gbGOOD ;
	} else {
		LEVEL_DEBUG("Lookup of %s unsuccessful",CONST_ALIAS_TREE_DATA(atn)) ;
	}
	PERSISTENT_RUNLOCK;
	owfree(atn) ;
	return ret;
}
Beispiel #23
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 #24
0
/* Look in caches, 0=found and valid, 1=not or uncachable in the first place */
static enum cache_task_return Cache_Get_Common_Dir(struct dirblob *db, time_t * duration, const struct tree_node *tn)
{
	enum cache_task_return ctr_ret;
	time_t now = NOW_TIME;
	size_t size;
	struct tree_opaque *opaque;
	LEVEL_DEBUG("Get from cache sn " SNformat " pointer=%p extension=%d", SNvar(tn->tk.sn), tn->tk.p, tn->tk.extension);
	CACHE_RLOCK;
	opaque = tfind(tn, &cache.temporary_tree_new, tree_compare) ;
	if ( opaque == NULL ) {
		// not found in new tree
		if ( cache.time_retired + duration[0] > now ) {
			// old tree could be new enough
			opaque = tfind(tn, &cache.temporary_tree_old, tree_compare) ;
		}
	}
	if ( opaque != NULL ) {
		duration[0] = opaque->key->expires - now ;
		if (duration[0] >= 0) {
			LEVEL_DEBUG("Dir found in cache");
			size = opaque->key->dsize;
			if (DirblobRecreate(TREE_DATA(opaque->key), size, db) == 0) {
				//printf("Cache: snlist=%p, devices=%lu, size=%lu\n",*snlist,devices[0],size) ;
				ctr_ret = ctr_ok;
			} else {
				ctr_ret = ctr_size_mismatch;
			}
		} else {
			//char b[26];
			//printf("GOT DEAD now:%s",ctime_r(&now,b)) ;
			//printf("        then:%s",ctime_r(&opaque->key->expires,b)) ;
			LEVEL_DEBUG("Dir expired in cache");
			ctr_ret = ctr_expired;
		}
	} else {
		LEVEL_DEBUG("Dir not found in cache");
		ctr_ret = ctr_not_found;
	}
	CACHE_RUNLOCK;
	return ctr_ret;
}
Beispiel #25
0
/* returns null-terminated string */
ASCII * Cache_Get_Alias(const BYTE * sn)
{
	struct tree_node tn;
	struct tree_opaque *opaque;
	ASCII * alias_name = NULL ;
	

	LoadTK(sn, Alias_Marker, 0, &tn ) ;

	PERSISTENT_RLOCK;
	opaque = tfind(&tn, &cache.persistent_tree, tree_compare) ;
	if ( opaque != NULL ) {
		alias_name = owmalloc( opaque->key->dsize + 1 ) ;
		if ( alias_name != NULL ) {
			memcpy( alias_name, (ASCII *)TREE_DATA(opaque->key), opaque->key->dsize+1 ) ;
			LEVEL_DEBUG("Retrieving " SNformat " alias=%s", SNvar(sn), alias_name );
		}
	}
	PERSISTENT_RUNLOCK;
	return alias_name ;
}
Beispiel #26
0
/* return 0 if good, 1 if not */
static GOOD_OR_BAD Cache_Add(const void *data, const size_t datasize, const struct parsedname *pn)
{
	struct tree_node *tn;
	time_t duration;
	int persistent ;

	if (!pn || IsAlarmDir(pn)) {
		return gbGOOD;				// do check here to avoid needless processing
	}

	// Special handling of Mock
	persistent = IsThisPersistent(pn) ;
	if ( persistent ) {
		duration = 1 ;
	} else {
		duration = TimeOut(pn->selected_filetype->change);
		if (duration <= 0) {
			return gbGOOD;				/* in case timeout set to 0 */
		}
	}

	// allocate space for the node and data
	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + datasize);
	if (!tn) {
		return gbBAD;
	}

	LEVEL_DEBUG(SNformat " size=%d", SNvar(pn->sn), (int) datasize);

	// populate the node structure with data
	LoadTK( pn->sn, pn->selected_filetype, pn->extension, tn );
	tn->expires = duration + NOW_TIME;
	tn->dsize = datasize;
	if (datasize) {
		memcpy(TREE_DATA(tn), data, datasize);
	}
	return persistent ?
		Add_Stat(&cache_pst, Cache_Add_Persistent(tn)) :
		Add_Stat(&cache_ext, Cache_Add_Common(tn)) ;
}
Beispiel #27
0
/* return 0 if good, 1 if not */
GOOD_OR_BAD Cache_Add_Alias(const ASCII *name, const BYTE * sn)
{
	struct tree_node *tn;
	size_t size = strlen(name) ;

	if ( size == 0 ) {
		return gbGOOD ;
	}

	tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size + 1 );
	if (!tn) {
		return gbBAD;
	}

	LEVEL_DEBUG("Adding alias for " SNformat " = %s", SNvar(sn), name);
	LoadTK( sn, Alias_Marker, 0, tn );
	tn->expires = NOW_TIME;
	tn->dsize = size;
	memcpy((ASCII *)TREE_DATA(tn), name, size+1 ); // includes NULL
	Cache_Add_Alias_SN( name, sn ) ;
	return Add_Stat(&cache_pst, Cache_Add_Persistent(tn));
}
Beispiel #28
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 #29
0
/* Look in caches, 0=found and valid, 1=not or uncachable in the first place */
static GOOD_OR_BAD Cache_Get_Internal(void *data, size_t * dsize, const struct internal_prop *ip, const struct parsedname *pn)
{
	struct tree_node tn;
	time_t duration;
	//printf("Cache_Get_Internal");
	if (!pn) {
		return gbBAD;				// do check here to avoid needless processing
	}
	
	duration = TimeOut(ip->change);
	if (duration <= 0) {
		return gbBAD;				/* in case timeout set to 0 */
	}
	
	LEVEL_DEBUG(SNformat " size=%d", SNvar(pn->sn), (int) dsize[0]);
	LoadTK( pn->sn, ip->name, EXTENSION_INTERNAL, &tn) ;
	switch (ip->change) {
		case fc_persistent:
			return Get_Stat(&cache_pst, Cache_Get_Persistent(data, dsize, &duration, &tn));
		default:
			return Get_Stat(&cache_int, Cache_Get_Common(data, dsize, &duration, &tn));
	}
}
Beispiel #30
0
static enum search_status W1_next_both(struct device_search *ds, const struct parsedname *pn)
{
	if (ds->LastDevice) {
		return search_done;
	}
	if (++(ds->index) == 0) {
		// first pass, load the directory
		DirblobClear( &(ds->gulp) );
		if ( W1_Process_Response( search_callback, w1_send_search(ds,pn), ds, pn ) != nrs_complete) {
			return search_error;
		}
	}

	switch ( DirblobGet(ds->index, ds->sn, &(ds->gulp) ) ) {
		case 0:
			LEVEL_DEBUG("SN found: " SNformat "", SNvar(ds->sn));
			return search_good;
		case -ENODEV:
		default:
			ds->LastDevice = 1;
			LEVEL_DEBUG("SN finished");
			return search_done;
	}
}