예제 #1
0
파일: ow_fake.c 프로젝트: M-o-a-T/owfs
// set up default device ID
static void GetDefaultDeviceName(BYTE * dn, const BYTE * sn, const struct connection_in * in)
{
	switch (get_busmode(in)) {
		case bus_tester:
			// "bus number"
			dn[1] = BYTE_MASK(in->master.tester.index >> 0) ;
			dn[2] = BYTE_MASK(in->master.tester.index >> 8) ;
			// repeat family code
			dn[3] = sn[0] ;
			// family code complement
			dn[4] = BYTE_INVERSE(sn[0]) ;
			// "device" number
			dn[5] = BYTE_MASK(DirblobElements(&(in->master.fake.main)) >> 0) ;
			dn[6] = BYTE_MASK(DirblobElements(&(in->master.fake.main)) >> 8) ;
			break ;
		case bus_fake:
		case bus_mock:
		default: // only for compiler warning
			dn[1]  = BYTE_MASK(rand()) ;
			dn[2]  = BYTE_MASK(rand()) ;
			dn[3]  = BYTE_MASK(rand()) ;
			dn[4]  = BYTE_MASK(rand()) ;
			dn[5]  = BYTE_MASK(rand()) ;
			dn[6]  = BYTE_MASK(rand()) ;
			break ;
	}
}
예제 #2
0
static enum e_visibility VISIBLE_HA5( const struct parsedname * pn )
{
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_ha5:
			return visible_now ;
		default:
			return visible_not_now ;
	}
}
예제 #3
0
static ZERO_OR_ERROR FS_r_PPM(struct one_wire_query *owq)
{
	struct connection_in * in = PN(owq)->selected_connection ;
	switch ( get_busmode(in) ) {
		case bus_i2c:
			OWQ_Y(owq) = ( (in->master.i2c.configreg & DS2482_REG_CFG_PPM) != 0x00 ) ;
			return 0;
		default:
			return -ENOTSUP ;
	}
}
예제 #4
0
static ZERO_OR_ERROR FS_r_APU(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_i2c:
			OWQ_Y(owq) = ( (pn->selected_connection->master.i2c.configreg & DS2482_REG_CFG_APU) != 0x00 ) ;
			return 0;
		default:
			return -ENOTSUP ;
	}
}
예제 #5
0
static enum e_visibility VISIBLE_PSEUDO( const struct parsedname * pn )
{
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_fake:
		case bus_tester:
		case bus_mock:
			return visible_now ;
		default:
			return visible_not_now ;
	}
}
예제 #6
0
static enum e_visibility VISIBLE_DS2480B( const struct parsedname * pn )
{
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_serial:
		case bus_xport:
		case bus_pbm:
			return visible_now ;
		default:
			return visible_not_now ;
	}
}
예제 #7
0
/*
 * Value is between 0 and 7.
 * Default value is 3.
 *
 * PARMSET_Slew15Vus   0x0
 * PARMSET_Slew2p20Vus 0x1
 * PARMSET_Slew1p65Vus 0x2
 * PARMSET_Slew1p37Vus 0x3 (default with altUSB)
 * PARMSET_Slew1p10Vus 0x4
 * PARMSET_Slew0p83Vus 0x5 (default without altUSB)
 * PARMSET_Slew0p70Vus 0x6
 * PARMSET_Slew0p55Vus 0x7
 */
static ZERO_OR_ERROR FS_r_pulldownslewrate(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	if (get_busmode(pn->selected_connection) != bus_usb) {
		return -ENOTSUP;
#if OW_USB
	} else {
		OWQ_U(owq) = pn->selected_connection->master.usb.pulldownslewrate;
#endif /* OW_USB */
	}
	return 0;
}
예제 #8
0
/*
 * Value is between 8 and 15, which represents 8us and 15us.
 * Default value is 10us. (with altUSB)
 * Default value is 12us. (without altUSB)
 */
static ZERO_OR_ERROR FS_r_writeonelowtime(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	if (get_busmode(pn->selected_connection) != bus_usb) {
		OWQ_U(owq) = 10;
#if OW_USB
	} else {
		OWQ_U(owq) = pn->selected_connection->master.usb.writeonelowtime + 8;
#endif /* OW_USB */
	}
	return 0;
}
예제 #9
0
/*
 * Value is between 3 and 10, which represents 3us and 10us.
 * Default value is 8us. (with altUSB)
 * Default value is 7us. (without altUSB)
 */
static ZERO_OR_ERROR FS_r_datasampleoffset(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	if (get_busmode(pn->selected_connection) != bus_usb) {
		OWQ_U(owq) = 8;
#if OW_USB
	} else {
		OWQ_U(owq) = pn->selected_connection->master.usb.datasampleoffset + 3;
#endif /* OW_USB */
	}
	return 0;
}
예제 #10
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));
}
예제 #11
0
/* fake adapter temperature limits */
static ZERO_OR_ERROR FS_r_templimit(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_fake:
		case bus_mock:
		case bus_tester:
			OWQ_F(owq) = pn->selected_filetype->data.i ? pn->selected_connection->master.fake.templow : pn->selected_connection->master.fake.temphigh;
			return 0;
		default:
			return -ENOTSUP ;
	}
}
예제 #12
0
/* Serial baud rate */
static ZERO_OR_ERROR FS_r_baud(struct one_wire_query *owq)
{
	struct connection_in * in = PN(owq)->selected_connection ;
	switch ( get_busmode(in) ) {
		case bus_serial:
		case bus_link:
		case bus_ha5:
		case bus_ha7e:
		case bus_pbm:
			OWQ_U(owq) = COM_BaudRate( in->pown->baud ) ;
			return 0;
		default:
			return -ENOTSUP ;
	}
}
예제 #13
0
static ZERO_OR_ERROR FS_w_baud(struct one_wire_query *owq)
{
	struct connection_in * in = PN(owq)->selected_connection ;
	switch ( get_busmode(in) ) {
		case bus_serial:
		case bus_link:
		case bus_pbm:
			in->pown->baud = COM_MakeBaud( (speed_t) OWQ_U(owq) ) ;
			++in->changed_bus_settings ;
			break ;
		default:
			break ;
	}
	return 0 ;
}
예제 #14
0
static ZERO_OR_ERROR FS_w_APU(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_i2c:
			if ( OWQ_Y(owq) ) {
				pn->selected_connection->master.i2c.configreg |= DS2482_REG_CFG_APU ;
			} else {
				pn->selected_connection->master.i2c.configreg &= ~DS2482_REG_CFG_APU ;
			}
			break ;
		default:
			break ;
	}
	return 0 ;
}
예제 #15
0
static ZERO_OR_ERROR FS_w_PPM(struct one_wire_query *owq)
{
	struct connection_in * in = PN(owq)->selected_connection ;
	switch ( get_busmode(in) ) {
		case bus_i2c:
			if ( OWQ_Y(owq) ) {
				in->master.i2c.configreg |= DS2482_REG_CFG_PPM ;
			} else {
				in->master.i2c.configreg &= ~DS2482_REG_CFG_PPM ;
			}
			break ;
		default:
			break ;
	}
	return 0 ;
}
예제 #16
0
static ZERO_OR_ERROR FS_w_datasampleoffset(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	if (get_busmode(pn->selected_connection) != bus_usb){
		return -ENOTSUP;
	}

#if OW_USB
	if ((OWQ_U(owq) < 3) || (OWQ_U(owq) > 10)) {
		return -ENOTSUP;
	}

	pn->selected_connection->master.usb.datasampleoffset = OWQ_U(owq) - 3;
	pn->selected_connection->changed_bus_settings |= CHANGED_USB_OFFSET;	// force a reset
#endif /* OW_USB */

	return 0;
}
예제 #17
0
static ZERO_OR_ERROR FS_w_writeonelowtime(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	if (get_busmode(pn->selected_connection) != bus_usb) {
		return -ENOTSUP;
	}

#if OW_USB
	if ((OWQ_U(owq) < 8) || (OWQ_U(owq) > 15)) {
		return -ENOTSUP;
	}

	pn->selected_connection->master.usb.writeonelowtime = OWQ_U(owq) - 8;
	pn->selected_connection->changed_bus_settings |= CHANGED_USB_LOW ;	// force a reset
#endif /* OW_USB */

	return 0;
}
예제 #18
0
static ZERO_OR_ERROR FS_w_pulldownslewrate(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	if (get_busmode(pn->selected_connection) != bus_usb) {
		return -ENOTSUP;
	}
#if OW_USB
	if (OWQ_U(owq) > 7) {
		return -ENOTSUP;
	}

	pn->selected_connection->master.usb.pulldownslewrate = OWQ_U(owq);
	pn->selected_connection->changed_bus_settings |= CHANGED_USB_SLEW ;	// force a reset

	LEVEL_DEBUG("Set slewrate to %d", pn->selected_connection->master.usb.pulldownslewrate);
#endif /* OW_USB */
	return 0;
}
예제 #19
0
static ZERO_OR_ERROR FS_w_templimit(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	switch ( get_busmode(pn->selected_connection) ) {
		case bus_fake:
		case bus_mock:
		case bus_tester:
			if (pn->selected_filetype->data.i) {
				pn->selected_connection->master.fake.templow = OWQ_F(owq);
			} else {
				pn->selected_connection->master.fake.temphigh = OWQ_F(owq);
			}
			return 0;
		default:
			break ;
	}
	return 0 ;
}
예제 #20
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));
}
예제 #21
0
void FreeIn(struct connection_in *target)
{
	if (target == NULL) {
		return;
	}
	switch (target->state) {
	case connection_vacant:
		break;
	case connection_pending:
		if (target->name) {
			free(target->name);
			target->name = NULL;
		}
		break;
	case connection_active:
		switch (get_busmode(target)) {
		case bus_zero:
			if (target->connin.tcp.type)
				free(target->connin.tcp.type);
			if (target->connin.tcp.domain)
				free(target->connin.tcp.domain);
			if (target->connin.tcp.fqdn)
				free(target->connin.tcp.fqdn);
			// fall through
		case bus_server:
			LEVEL_DEBUG("FreeClientAddr\n");
			FreeClientAddr(target);
			break;
		default:
			break;
		}
		if (target->name) {
			free(target->name);
			target->name = NULL;
		}
#if OW_MT
		my_pthread_mutex_destroy(&(target->bus_mutex));
#endif
	}
	target->state = connection_vacant;
}
예제 #22
0
static ZERO_OR_ERROR FS_r_ds2490status(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	char res[256];
	char buffer[ DS9490_getstatus_BUFFER_LENGTH ];
	int ret;
	res[0] = '\0';
	if (get_busmode(pn->selected_connection) == bus_usb) {
#if OW_USB
		ret = DS9490_getstatus(buffer, 0, PN(owq));
		if (ret < 0) {
			sprintf(res, "DS9490_getstatus failed: %d\n", ret);
		} else {
			sprintf(res,
					"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
					buffer[0], buffer[1], buffer[2], buffer[3],
					buffer[4], buffer[5], buffer[6], buffer[7],
					buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15]);
		}
		/*
		   uchar    EnableFlags;
		   uchar    OneWireSpeed;
		   uchar    StrongPullUpDuration;
		   uchar    ProgPulseDuration;
		   uchar    PullDownSlewRate;
		   uchar    Write1LowTime;
		   uchar    DSOW0RecoveryTime;
		   uchar    Reserved1;
		   uchar    StatusFlags;
		   uchar    CurrentCommCmd1;
		   uchar    CurrentCommCmd2;
		   uchar    CommBufferStatus;  // Buffer for COMM commands
		   uchar    WriteBufferStatus; // Buffer we write to
		   uchar    ReadBufferStatus;  // Buffer we read from
		 */
#endif
	}
	return OWQ_format_output_offset_and_size_z(res, owq);
}
예제 #23
0
static int IsThisPersistent( const struct parsedname * pn )
{
	return ( (pn->selected_filetype->change==fc_persistent) || get_busmode(pn->selected_connection)==bus_mock ) ;
}
예제 #24
0
/* If error, try twice more */
static ZERO_OR_ERROR FS_write_real(int depth, struct one_wire_query *owq)
{
	ZERO_OR_ERROR write_or_error;
	struct parsedname *pn = PN(owq);
	struct filetype * ft = pn->selected_filetype ;
	INDEX_OR_ERROR initial_bus = pn->selected_connection->index ; // current selected bus
	INDEX_OR_ERROR rechecked_bus ;

	if ( depth > 1 ) {
		LEVEL_DEBUG("Too many bus changes for write");
		return -ENODEV ;
	}

	if ( ft->write == FS_w_alias ) {
		// Special check for alias
		// it's ok for fake and tester and mock as well
		// so do this before the fake test
		// also no need to three-peat.
		return FS_write_owq(owq) ;
	}

	/* Special case for "fake" adapter */
	switch (get_busmode(pn->selected_connection)) {
		case bus_mock:
			// Mock -- write even "unwritable" to the cache for testing
			OWQ_Cache_Add(owq) ;
			// fall through
		case bus_fake:
		case bus_tester:
			return ( ft->write == NO_WRITE_FUNCTION ) ? -ENOTSUP : 0 ;
		default:
			// non-virtual devices get handled below
			break ;
	}

	/* First try */
	/* in and bus_nr already set */
	STAT_ADD1(write_tries[0]);
	write_or_error = FS_w_given_bus(owq);
	if ( write_or_error ==0 ) {
		return 0 ;
	}

	/* Second Try */
	STAT_ADD1(write_tries[1]);
	if (SpecifiedBus(pn)) {
		// The bus number casn't be changed -- it was specified in the path
		write_or_error = FS_w_given_bus(owq);
		if ( write_or_error == 0 ) {
			return 0 ;
		}

		// The bus number casn't be changed -- it was specified in the path
		STAT_ADD1(write_tries[2]);
		return FS_w_given_bus(owq);
	}

	/* Recheck location */
	/* if not a specified bus, relook for chip location */
	rechecked_bus = ReCheckPresence(pn) ;
	if ( rechecked_bus < 0 ) {
		// can't find the location
		return -ENOENT ;
	}

	if ( initial_bus == rechecked_bus ) {
		// special handling for remote
		// only repeat if the bus number is wrong
		// because the remote does the rewrites
		if (BusIsServer(pn->selected_connection)) {
			return write_or_error ;
		}
		// try again
		STAT_ADD1(write_tries[1]);
		write_or_error = FS_w_given_bus(owq);
		if ( write_or_error == 0 ) {
			return 0 ;
		}
		// third try
		STAT_ADD1(write_tries[2]);
		return FS_w_given_bus(owq);
	}		

	// Changed location retry everything
	LEVEL_DEBUG("Bus location changed from %d to %d\n",initial_bus,rechecked_bus);
	return FS_write_real(depth+1,owq);
}
예제 #25
0
/* return 0 if ok */
static ZERO_OR_ERROR FS_w_local(struct one_wire_query *owq)
{
	// Device already locked
	struct parsedname *pn = PN(owq);
	struct filetype * ft = pn->selected_filetype ;

	/* Writable? */
	if ( ft->write == NO_WRITE_FUNCTION ) {
		return -ENOTSUP;
	}

	/* Special case for "fake" adapter */
	switch (get_busmode(pn->selected_connection)) {
		case bus_mock:
		case bus_fake:
		case bus_tester:
			return 0 ;
		default:
			// non-virtual devices get handled below
			break ;
	}

	/* Non-array? */
	if ( ft->ag == NON_AGGREGATE ) {
		LEVEL_DEBUG("Write a non-array element %s",pn->path);
		return FS_write_owq(owq);
	}

	/* array */
	switch ( ft->ag->combined ) {
		case ag_sparse:
			// avoid cache
			return (ft->write) (owq);;
		case ag_aggregate:
			switch (pn->extension) {
				case EXTENSION_BYTE:
					LEVEL_DEBUG("Write an aggregate .BYTE %s",pn->path);
					return FS_write_owq(owq);
				case EXTENSION_ALL:
					LEVEL_DEBUG("Write an aggregate .ALL %s",pn->path);
					return FS_write_all(owq);
				default:
					LEVEL_DEBUG("Write an aggregate element %s",pn->path);
					return FS_write_a_part(owq) ;
			}
		case ag_mixed:
			switch (pn->extension) {
				case EXTENSION_BYTE:
					LEVEL_DEBUG("Write a mixed .BYTE %s",pn->path);
					OWQ_Cache_Del_parts(owq);
					return FS_write_owq(owq);
				case EXTENSION_ALL:
					LEVEL_DEBUG("Write a mixed .ALL %s",pn->path);
					OWQ_Cache_Del_parts(owq);
					return FS_write_all(owq);
				default:
					LEVEL_DEBUG("Write a mixed element %s",pn->path);
					OWQ_Cache_Del_ALL(owq);
					OWQ_Cache_Del_BYTE(owq);
					return FS_write_owq(owq);
			}
		case ag_separate:
			switch (pn->extension) {
				case EXTENSION_BYTE:
					LEVEL_DEBUG("Write a separate .BYTE %s",pn->path);
					return FS_write_as_bits(owq);
				case EXTENSION_ALL:
					LEVEL_DEBUG("Write a separate .ALL %s",pn->path);
					return FS_write_in_parts(owq);
				default:
					LEVEL_DEBUG("Write a separate element %s",pn->path);
					return FS_write_owq(owq);
			}
		default:
			return -ENOENT ;
	}
}