Beispiel #1
0
/* write flag */
static ZERO_OR_ERROR FS_w_flag(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	BYTE cr;
	BYTE fl = pn->selected_filetype->data.c;
	OWQ_allocate_struct_and_pointer(owq_flag);
	
	OWQ_create_temporary(owq_flag, (char *) &cr, 1, 0x0201, pn);
	if (COMMON_read_memory_F0(owq_flag, 0, 0)) {
		return -EINVAL;
	}
	if (OWQ_Y(owq)) {
		if (cr & fl) {
			return 0;
		}
	} else {
		if ((cr & fl) == 0) {
			return 0;
		}
	}
	cr ^= fl;					/* flip the bit */
	if (OW_w_mem(&cr, 1, 0x0201, pn)) {
		return -EINVAL;
	}
	return 0;
}
Beispiel #2
0
static GOOD_OR_BAD OW_r_mem(BYTE * p, size_t size, off_t offset, struct parsedname *pn)
{
	OWQ_allocate_struct_and_pointer(owq_read);

	OWQ_create_temporary(owq_read, (char *) p, size, offset, pn);
	return COMMON_read_memory_crc16_AA(owq_read, 0, _1W_2450_PAGESIZE);
}
Beispiel #3
0
static ZERO_OR_ERROR FS_r_set_alarm(struct one_wire_query *owq)
{
	BYTE c;
	OWQ_allocate_struct_and_pointer(owq_alarm);

	OWQ_create_temporary(owq_alarm, (char *) &c, 1, 0x0200, PN(owq));
	if (COMMON_read_memory_F0(owq_alarm, 0, 0)) {
		return -EINVAL;
	}
	OWQ_U(owq) = Avals[(c >> 3) & 0x07];
	return 0;
}
Beispiel #4
0
/* read flag */
static ZERO_OR_ERROR FS_r_flag(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	BYTE cr;
	BYTE fl = pn->selected_filetype->data.c;
	OWQ_allocate_struct_and_pointer(owq_flag);

	OWQ_create_temporary(owq_flag, (char *) &cr, 1, 0x0201, pn);
	if (COMMON_read_memory_F0(owq_flag, 0, 0)) {
		return -EINVAL;
	}
	OWQ_Y(owq) = (cr & fl) ? 1 : 0;
	return 0;
}
Beispiel #5
0
// This function probably needs to be modified a bit...
static SIZE_OR_ERROR FS_r_simultaneous(struct one_wire_query *owq)
{
	// Device not locked.
	OWQ_allocate_struct_and_pointer(owq_given);

	if (SpecifiedBus(PN(owq))) {
		return FS_r_given_bus(owq);
	}

	memcpy(owq_given, owq, sizeof(struct one_wire_query));	// shallow copy

	// it's hard to know what we should return when reading /simultaneous/temperature
	SetKnownBus(0, PN(owq_given));
	return FS_r_given_bus(owq_given);
}
Beispiel #6
0
SIZE_OR_ERROR FS_get(const char *path, char **return_buffer, size_t * buffer_length)
{
	SIZE_OR_ERROR size = 0 ;		/* current buffer string length */
	OWQ_allocate_struct_and_pointer( owq ) ;

	/* Check the parameters */
	if (return_buffer == NULL) {
		//  No buffer for read result.
		return -EINVAL;
	}

	if (path == NULL) {
		path = "/";
	}

	*return_buffer = NULL;				// default return string on error

	if ( BAD( OWQ_create(path, owq) ) ) {	/* Can we parse the input string */
		return -ENOENT;
	}

	if ( IsDir( PN(owq) ) ) { /* A directory of some kind */
		struct charblob cb ;
		CharblobInit(&cb) ;
		getdir( &cb, owq ) ;
		size = CharblobLength(&cb) ;
		*return_buffer = copy_buffer( CharblobData(&cb), size ) ;
		CharblobClear( &cb ) ;
	} else { /* A regular file  -- so read */
		if ( GOOD(OWQ_allocate_read_buffer(owq)) ) { // make the space in the buffer
			size = FS_read_postparse(owq) ;
			*return_buffer = copy_buffer( OWQ_buffer(owq), size ) ;
		}
	}
	// the buffer is allocated by getdir or getval
	OWQ_destroy(owq);

	/* Check the parameters */
	if (*return_buffer == NULL) {
		//  no data.
		return -EINVAL;
	}

	if ( buffer_length != NULL ) {
		*buffer_length = size ;
	}
	return size ;
}
Beispiel #7
0
/* return size if ok, else negative */
SIZE_OR_ERROR FS_write(const char *path, const char *buf, const size_t size, const off_t offset)
{
	ZERO_OR_ERROR write_return;
	OWQ_allocate_struct_and_pointer(owq);

	LEVEL_CALL("path=%s size=%d offset=%d", SAFESTRING(path), (int) size, (int) offset);

	// parsable path?
	if ( OWQ_create(path, owq) != 0 ) { // for write
		return -ENOENT;
	}
	OWQ_assign_write_buffer(buf, size, offset, owq) ;
	write_return = FS_write_postparse(owq);
	OWQ_destroy(owq);
	return write_return;		/* here's where the size is used! */
}
Beispiel #8
0
SIZE_OR_ERROR FS_read(const char *path, char *buf, const size_t size, const off_t offset)
{
	SIZE_OR_ERROR read_or_error;
	OWQ_allocate_struct_and_pointer(owq);

	LEVEL_CALL("path=%s size=%d offset=%d", SAFESTRING(path), (int) size, (int) offset);
	// Parseable path?
	if ( BAD( OWQ_create(path, owq) ) ) { // for read
		return -ENOENT;
	}
	OWQ_assign_read_buffer( buf, size, offset, owq) ;
	read_or_error = FS_read_postparse(owq);
	OWQ_destroy(owq);

	return read_or_error;
}
Beispiel #9
0
/* read REAL DS2431 pages -- 8 bytes. */
static GOOD_OR_BAD OW_w_2Dpage(BYTE * data, size_t size, off_t offset, struct parsedname *pn)
{
	off_t pageoff = offset & 0x07;
	BYTE p[4 + 8 + 2] = { _1W_WRITE_SCRATCHPAD, LOW_HIGH_ADDRESS(offset - pageoff),
	};
	struct transaction_log tcopy[] = {
		TRXN_START,
		TRXN_WRITE(p, 3 + 8),
		TRXN_END,
	};
	struct transaction_log tread[] = {
		TRXN_START,
		TRXN_WR_CRC16(p, 1, 3 + 8),
		TRXN_COMPARE(&p[4], data, size),
		TRXN_END,
	};
	struct transaction_log tsram[] = {
		TRXN_START,
		TRXN_WRITE(p, 4),
		TRXN_DELAY(13),
		TRXN_END,
	};

	if (size != 8) {			// incomplete page
		OWQ_allocate_struct_and_pointer(owq_old);
		OWQ_create_temporary(owq_old, (char *) &p[3], 8, offset - pageoff, pn);
		if (COMMON_read_memory_F0(owq_old, 0, 0)) {
			return gbBAD;
		}
	}

	memcpy(&p[3 + pageoff], data, size);

	/* Copy to scratchpad */
	RETURN_BAD_IF_BAD(BUS_transaction(tcopy, pn)) ;

	/* Re-read scratchpad and compare */
	p[0] = _1W_READ_SCRATCHPAD;
	RETURN_BAD_IF_BAD(BUS_transaction(tread, pn)) ;

	/* Copy Scratchpad to SRAM */
	p[0] = _1W_COPY_SCRATCHPAD;
	return BUS_transaction(tsram, pn) ;
}
Beispiel #10
0
/* read 4 or 5 byte number */
static GOOD_OR_BAD OW_r_ulong(uint64_t * L, size_t size, off_t offset, struct parsedname *pn)
{
	BYTE data[5] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
	OWQ_allocate_struct_and_pointer(owq_ulong);

	OWQ_create_temporary(owq_ulong, (char *) data, size, offset, pn);
	if (size > 5) {
		return gbBAD;
	}
	if (COMMON_read_memory_F0(owq_ulong, 0, 0)) {
		return gbBAD;
	}
	L[0] = ((uint64_t) data[0])
		+ (((uint64_t) data[1]) << 8)
		+ (((uint64_t) data[2]) << 16)
		+ (((uint64_t) data[3]) << 24)
		+ (((uint64_t) data[4]) << 32);
	return gbGOOD;
}
Beispiel #11
0
/* This function is only used by "Simultaneous" */
static ZERO_OR_ERROR FS_w_simultaneous(struct one_wire_query *owq)
{
	if (SpecifiedBus(PN(owq))) {
		return FS_w_given_bus(owq);
	} else if (Inbound_Control.head_port) {
		struct port_in * pin ;
		OWQ_allocate_struct_and_pointer(owq_given);

		memcpy(owq_given, owq, sizeof(struct one_wire_query));	// shallow copy

		for ( pin=Inbound_Control.head_port ; pin != NULL ; pin = pin->next ) {
			struct connection_in * cin;
					
			for( cin=pin->first; cin!=NO_CONNECTION ; cin=cin->next ) {
				SetKnownBus(cin->index, PN(owq_given));
				FS_w_given_bus(owq_given);
			}
		}
	}
	return 0;
}
Beispiel #12
0
SIZE_OR_ERROR FS_get(const char *path, char **return_buffer, size_t * buffer_length)
{
	SIZE_OR_ERROR size = 0 ;		/* current buffer string length */
	OWQ_allocate_struct_and_pointer( owq ) ;

	/* Check the parameters */
	if (return_buffer == NULL) {
		//  No buffer supplied for read result.
		return -EINVAL;
	}

	if (path == NULL) {
		path = "/";
	}

	*return_buffer = NULL;				// default return string on error

	if ( BAD( OWQ_create(path, owq) ) ) {	/* Can we parse the input string */
		return -ENOENT;
	}

	// Check for known type.
	if ( (PN(owq)->selected_filetype) != NO_FILETYPE ) { 
		// local owlib knows the type. 
		if ( IsDir( PN(owq) ) ) { /* A directory of some kind */
			struct charblob cb ;
			CharblobInit(&cb) ;
			getdir( &cb, owq ) ;
			size = CharblobLength(&cb) ;
			*return_buffer = copy_buffer( CharblobData(&cb), size ) ;
			CharblobClear(&cb) ;
		} else { /* A regular file  -- so read */
			if ( GOOD(OWQ_allocate_read_buffer(owq)) ) { // make the space in the buffer
				size = FS_read_postparse(owq) ;
				*return_buffer = copy_buffer( OWQ_buffer(owq), size ) ;
			}
		}
	} else {
		// local owlib doesn't know the type.
		struct charblob cb ;
		CharblobInit(&cb) ;

		// Try directory first.
		if (getdir( &cb, owq ) != -ENOTDIR) {
			// Is a directory.
			size = CharblobLength(&cb) ;
			*return_buffer = copy_buffer( CharblobData(&cb), size ) ;
		} else {
			// Is not a directory. Try file.
			if ( GOOD(OWQ_allocate_read_buffer(owq)) ) { // make the space in the buffer
				size = FS_read_postparse(owq) ;
				*return_buffer = copy_buffer( OWQ_buffer(owq), size ) ;
			}
		}
		CharblobClear(&cb) ;
	}	

	// the buffer is allocated by getdir or getval
	OWQ_destroy(owq);

	/* Check the parameters */
	if (*return_buffer == NULL) {
		//  error
		return -EINVAL;
	}

	if ( buffer_length != NULL ) {
		// return buffer length as well
		*buffer_length = size ;
	}
	return size ;
}
Beispiel #13
0
/*
 * lower level routine for actually handling a request
 * deals with data (ping is handled higher)
 */
void *DataHandler(void *v)
{
	struct handlerdata *hd = v;
	char *retbuffer = NULL;
	struct client_msg cm; // the return message

#if OW_CYGWIN
	/* Random generator seem to need initialization for each new thread
	 * If not, seed will be reset and rand() will return 0 the first call.
	 */
	{
		struct timeval tv;
		gettimeofday(&tv, NULL);
		srand((unsigned int) tv.tv_usec);
	}
#endif

	memset(&cm, 0, sizeof(struct client_msg));
	cm.version = MakeServerprotocol(OWSERVER_PROTOCOL_VERSION);
	cm.control_flags = hd->sm.control_flags;			// default flag return -- includes persistence state

	/* Pre-handling for special testing mode to exclude certain messages */
	switch ((enum msg_classification) hd->sm.type) {
	case msg_dirall:
	case msg_dirallslash:
		if (Globals.no_dirall) {
			LEVEL_DEBUG("DIRALL message rejected.") ;
			hd->sm.type = msg_error;
		}
		break;
	case msg_get:
	case msg_getslash:
		if (Globals.no_get) {
			LEVEL_DEBUG("GET message rejected.") ;
			hd->sm.type = msg_error;
		}
		break;
	default:
		break;
	}

	/* Now Check message types and only parse valid messages */
	switch ((enum msg_classification) hd->sm.type) {	// outer switch
	case msg_read:				// good message
	case msg_write:				// good message
	case msg_dir:				// good message
	case msg_presence:			// good message
	case msg_dirall:			// good message
	case msg_dirallslash:			// good message
	case msg_get:				// good message
	case msg_getslash:			// good message
		if (hd->sm.payload == 0) {	/* Bad query -- no data after header */
			LEVEL_DEBUG("No payload -- ignore.") ;
			cm.ret = -EBADMSG;
		} else {
			struct parsedname *pn;
			OWQ_allocate_struct_and_pointer(owq);
			pn = PN(owq);

			/* Parse the path string and crete  query object */
			LEVEL_CALL("DataHandler: parse path=%s", hd->sp.path);
			cm.ret = BAD( OWQ_create(hd->sp.path, owq) ) ? -1 : 0 ;
			if ( cm.ret != 0 ) {
				LEVEL_DEBUG("DataHandler: OWQ_create failed cm.ret=%d", cm.ret);
				break;
			}

			/* Use client persistent settings (temp scale, display mode ...) */
			pn->control_flags = hd->sm.control_flags;
			/* Override some settings from control flags */
			if ( (pn->control_flags & UNCACHED) != 0 ) {
				// client wants uncached
				pn->state |= ePS_uncached;
			}
			if ( (pn->control_flags & ALIAS_REQUEST) == 0 ) {
				// client wants unaliased
				pn->state |= ePS_unaliased;
			}
			

			/* Antilooping tags */
			pn->tokens = hd->sp.tokens;
			pn->tokenstring = hd->sp.tokenstring;
			//printf("Handler: sm.sg=%X pn.state=%X\n", sm.sg, pn.state);
			//printf("Scale=%s\n", TemperatureScaleName(SGTemperatureScale(sm.sg)));

			switch ((enum msg_classification) hd->sm.type) {
			case msg_presence:
				LEVEL_CALL("Presence message for %s", SAFESTRING(pn->path));
				// Basically, if we were able to ParsedName it's here!
				cm.size = 0;
				retbuffer = owmalloc( SERIAL_NUMBER_SIZE ) ;
				if ( retbuffer ) {
					memcpy( retbuffer, pn->sn, SERIAL_NUMBER_SIZE ) ;
					cm.payload = SERIAL_NUMBER_SIZE ;
				} else {
					cm.payload = 0 ;
				}
				cm.ret = 0;		// good answer
				break;
			case msg_read:
				LEVEL_CALL("Read message");
				retbuffer = ReadHandler(hd, &cm, owq);
				LEVEL_DEBUG("Read message done value=%p", retbuffer);
				break;
			case msg_write:
				LEVEL_CALL("Write message");
				if ( (int) hd->sp.datasize < hd->sm.size ) {
					cm.ret = -EMSGSIZE;
				} else {
					/* set buffer (size already set) */
					OWQ_assign_write_buffer( (ASCII *) hd->sp.data, hd->sm.size, hd->sm.offset, owq) ;
					WriteHandler(hd, &cm, owq);
				}
				break;
			case msg_dir:
				LEVEL_CALL("Directory message (one at a time)");
				DirHandler(hd, &cm, pn);
				break;
			case msg_dirall:
				LEVEL_CALL("Directory message (all at once)");
				retbuffer = DirallHandler(hd, &cm, pn);
				break;
			case msg_dirallslash:
				LEVEL_CALL("Directory message (all at once, with directory /)");
				retbuffer = DirallslashHandler(hd, &cm, pn);
				break;
			case msg_get:
				if (IsDir(pn)) {
					LEVEL_CALL("Get -> Directory message (all at once)");
					retbuffer = DirallHandler(hd, &cm, pn);
				} else {
					LEVEL_CALL("Get -> Read message");
					retbuffer = ReadHandler(hd, &cm, owq);
				}
				break;
			case msg_getslash:
				if (IsDir(pn)) {
					LEVEL_CALL("Get -> Directory message (all at once)");
					retbuffer = DirallslashHandler(hd, &cm, pn);
				} else {
					LEVEL_CALL("Get -> Read message");
					retbuffer = ReadHandler(hd, &cm, owq);
				}
				break;
			default:			// never reached
				LEVEL_CALL("Error: unknown message %d", (int) hd->sm.type);
				break;
			}
			OWQ_destroy(owq);
			LEVEL_DEBUG("DataHandler: FS_ParsedName_destroy done");
		}
		break;
	case msg_nop:				// "bad" message
		LEVEL_CALL("NOP message");
		cm.ret = 0;
		break;
	case msg_size:				// no longer used
	case msg_error:
	default:					// "bad" message
		cm.ret = -ENOMSG;
		LEVEL_CALL("No message");
		break;
	}
	LEVEL_DEBUG("DataHandler: cm.ret=%d", cm.ret);

	TOCLIENTLOCK(hd);
	if (cm.ret != -EIO) {
		ToClient(hd->file_descriptor, &cm, retbuffer);
	} else {
		ErrorToClient(hd, &cm) ;
	}

	// Signal to PingLoop that we're done.
	hd->toclient = toclient_complete ;
	if ( hd->ping_pipe[fd_pipe_write] != FILE_DESCRIPTOR_BAD ) {
		ignore_result = write( hd->ping_pipe[fd_pipe_write],"X",1) ; //dummy payload
	}
	TOCLIENTUNLOCK(hd);

	if (retbuffer) {
		owfree(retbuffer);
	}
	LEVEL_DEBUG("Finished with client request");
	return VOID_RETURN;
}