Esempio n. 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;
}
Esempio n. 2
0
/* Open a DS9490  -- low level code (to allow for repeats)  */
static GOOD_OR_BAD DS9490_redetect_match( struct connection_in * in)
{
	struct dirblob db ;
	BYTE sn[SERIAL_NUMBER_SIZE] ;
	int device_number ;

	LEVEL_DEBUG("Attempting reconnect on %s",SAFESTRING(DEVICENAME(in)));

	// Special case -- originally untagged adapter
	if ( in->master.usb.ds1420_address[0] == '\0' ) {
		LEVEL_CONNECT("Since originally untagged bus master, we will use first available slot.");
		return gbGOOD ;
	}

	// Generate a root directory
	RETURN_BAD_IF_BAD( DS9490_root_dir( &db, in ) ) ;

	// This adapter has no tags, so not the one we want
	if ( DirblobElements( &db) == 0 ) {
		DirblobClear( &db ) ;
		LEVEL_DATA("Empty directory on [%s] (Doesn't match initial scan).", SAFESTRING(DEVICENAME(in)));
		return gbBAD ;
	}

	// Scan directory for a match to the original tag
	device_number = 0 ;
	while ( DirblobGet( device_number, sn, &db ) == 0 ) {
		if (memcmp(sn, in->master.usb.ds1420_address, SERIAL_NUMBER_SIZE) == 0) {	// same tag device?
			LEVEL_DATA("Matching device [%s].", SAFESTRING(DEVICENAME(in)));
			DirblobClear( &db ) ;
			return gbGOOD ;
		}
		++device_number ;
	}
	// Couldn't find correct ds1420 chip on this adapter
	LEVEL_CONNECT("Couldn't find correct ds1420 chip on this bus master [%s] (want: " SNformat ")", SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
	DirblobClear( &db ) ;
	return gbBAD;
}
Esempio n. 3
0
static GOOD_OR_BAD PresenceFromDirblob( struct parsedname * pn )
{
	struct dirblob db;	// cached dirblob
	if ( GOOD( Cache_Get_Dir( &db , pn ) ) ) {
		// Use the dirblob from the cache
		GOOD_OR_BAD ret = ( DirblobSearch(pn->sn, &db ) >= 0 ) ? gbGOOD : gbBAD ;
		DirblobClear( &db ) ;
		return ret ;
	} else {
		// look through actual directory
		struct device_search ds ;
		enum search_status nextboth = BUS_first( &ds, pn ) ;
		while ( nextboth == search_good ) {
			if ( memcmp( ds.sn, pn->sn, SERIAL_NUMBER_SIZE ) == 0 ) {
				// found it. Early exit.
				BUS_next_cleanup( &ds );
				return gbGOOD ;
			}
			// Not found. Clean up done by BUS_next in this case
			nextboth = BUS_next( &ds, pn ) ;
		}
		return gbBAD ;
	}
}
Esempio n. 4
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;
	}
}
Esempio n. 5
0
static void Fake_close(struct connection_in *in)
{
	DirblobClear( &(in->master.fake.main) );
	DirblobClear( &(in->master.fake.alarm) );
}
Esempio n. 6
0
static GOOD_OR_BAD LINK_directory(struct device_search *ds, struct connection_in * in)
{
	char resp[DEVICE_LENGTH+COMMA_LENGTH+PLUS_LENGTH+in->CRLF_size];

	DirblobClear( &(ds->gulp) );

	// Send the configuration command and check response
	RETURN_BAD_IF_BAD( LINK_search_type( ds, in )) ;

	// send the first search
	RETURN_BAD_IF_BAD(LINK_write(LINK_string("f"), 1, in)) ;

	//One needs to check the first character returned.
	//If nothing is found, the link will timeout rather then have a quick
	//return.  This happens when looking at the alarm directory and
	//there are no alarms pending
	//So we grab the first character and check it.  If not an E leave it
	//in the resp buffer and get the rest of the response from the LINK
	//device

	RETURN_BAD_IF_BAD(LINK_read(LINK_string(resp), 1, in)) ;
	
	switch (resp[0]) {
		case 'E':
			LEVEL_DEBUG("LINK returned E: No devices in alarm");
			// pass through
		case 'N':
			// remove extra 2 bytes
			LEVEL_DEBUG("LINK returned E or N: Empty bus");
			if (ds->search != _1W_CONDITIONAL_SEARCH_ROM) {
				in->AnyDevices = anydevices_no;
			}
			return gbGOOD ;
		default:
			break ;
	}
	
	if ( BAD(LINK_read(LINK_string(&resp[1+in->CRLF_size]), DEVICE_LENGTH+COMMA_LENGTH+PLUS_LENGTH-1-in->CRLF_size, in)) ) {
		return gbBAD;
	}

	// Check if we should start scanning
	switch (resp[0]) {
	case '-':
	case '+':
		if (ds->search != _1W_CONDITIONAL_SEARCH_ROM) {
			in->AnyDevices = anydevices_yes;
		}
		break;
	default:
		LEVEL_DEBUG("LINK_search unrecognized case");
		return gbBAD;
	}

	/* Join the loop after the first query -- subsequent handled differently */
	while ((resp[0] == '+') || (resp[0] == '-')) {
		BYTE sn[SERIAL_NUMBER_SIZE];

		sn[7] = string2num(&resp[2]);
		sn[6] = string2num(&resp[4]);
		sn[5] = string2num(&resp[6]);
		sn[4] = string2num(&resp[8]);
		sn[3] = string2num(&resp[10]);
		sn[2] = string2num(&resp[12]);
		sn[1] = string2num(&resp[14]);
		sn[0] = string2num(&resp[16]);
		LEVEL_DEBUG("SN found: " SNformat, SNvar(sn));

		// CRC check
		if (CRC8(sn, SERIAL_NUMBER_SIZE) || (sn[0] == 0x00)) {
			LEVEL_DEBUG("BAD family or CRC8");
			return gbBAD;
		}

		DirblobAdd(sn,  &(ds->gulp) );

		switch (resp[0]) {
		case '+':
			// get next element
			if ( BAD(LINK_write(LINK_string("n"), 1, in))) {
				return gbBAD;
			}
			if ( BAD(LINK_read(LINK_string((resp)), DEVICE_LENGTH+COMMA_LENGTH+PLUS_LENGTH, in)) ) {
				return gbBAD;
			}
			break;
		case '-':
			return gbGOOD;
		default:
			break;
		}
	}

	return gbGOOD;
}
Esempio n. 7
0
// Read up to 7 (DS2490_DIR_GULP_ELEMENTS) at a time, and  place into
// a dirblob. Called from DS9490_next_both every 7 devices to fill.
static enum search_status DS9490_directory(struct device_search *ds, const struct parsedname *pn)
{
	BYTE status_buffer[ DS9490_getstatus_BUFFER_LENGTH + 1 ];
	BYTE EP2_data[SERIAL_NUMBER_SIZE] ; //USB endpoint 3 buffer
	union {
		BYTE b[DS2490_BULK_BUFFER_SIZE] ;
		BYTE sn[DS2490_BULK_BUFFER_SIZE/SERIAL_NUMBER_SIZE][SERIAL_NUMBER_SIZE];
	} EP3 ; //USB endpoint 3 buffer
	SIZE_OR_ERROR ret;
	int bytes_back;
	int devices_found;
	int device_index;
	int dir_gulp_elements = (pn->ds2409_depth==0) ? DS2490_DIR_GULP_ELEMENTS : 1 ;
	int readlen = 0 ;
	
	DirblobClear(&(ds->gulp));

	if ( BAD( BUS_select(pn) ) ) {
		LEVEL_DEBUG("Selection problem before a directory listing") ;
		return search_error ;
	}

	if ( pn->selected_connection->AnyDevices == anydevices_no ) {
		// empty bus detected, no presence pulse detected
		return search_done ;
	}
	
	SetupDiscrepancy(ds, EP2_data);

	// set the search start location
	ret = DS9490_write(EP2_data, SERIAL_NUMBER_SIZE, pn) ;
	if ( ret < SERIAL_NUMBER_SIZE ) {
		LEVEL_DATA("bulk write problem = %d", ret);
		return search_error;
	}
	// Send the search request
	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS, (dir_gulp_elements << 8) | (ds->search), pn) ) ) {
		LEVEL_DATA("control error");
		return search_error;
	}
	// read the search status
	if ( DS9490_getstatus(status_buffer, &readlen, pn)  != BUS_RESET_OK ) {
		return search_error;
	}

	// test the buffer size waiting for us
	bytes_back = status_buffer[13];
	LEVEL_DEBUG("Got %d bytes from USB search", bytes_back);
	if (bytes_back == 0) {
		/* Nothing found on the bus. Have to return something != search_good to avoid
		 * getting stuck in loop in FS_realdir() and FS_alarmdir()
		 * which ends when ret!=search_good */
		LEVEL_DATA("ReadBufferstatus == 0");
		return search_done;
	} else if ( bytes_back % SERIAL_NUMBER_SIZE != 0 ) {
		LEVEL_DATA("ReadBufferstatus size %d not a multiple of %d", bytes_back,SERIAL_NUMBER_SIZE);
		return search_error;
	} else if ( bytes_back > (dir_gulp_elements + 1) * SERIAL_NUMBER_SIZE ) {
		LEVEL_DATA("ReadBufferstatus size %d too large", bytes_back);
		return search_error;
	}
	devices_found = bytes_back / SERIAL_NUMBER_SIZE;
	if (devices_found > dir_gulp_elements) {
		devices_found = dir_gulp_elements;
	}

	// read in the buffer that holds the devices found
	if ((ret = DS9490_read(EP3.b, bytes_back, pn)) <= 0) {
		LEVEL_DATA("bulk read problem ret=%d", ret);
		return search_error;
	}

	// analyze each device found
	for (device_index = 0; device_index < devices_found; ++device_index) {
		/* test for CRC error */
		LEVEL_DEBUG("gulp. Adding element %d:" SNformat, device_index, SNvar(EP3.sn[device_index]));
		if (CRC8(EP3.sn[device_index], SERIAL_NUMBER_SIZE) != 0 || EP3.sn[device_index][0] == 0) {
			LEVEL_DATA("CRC error");
			return search_error;
		}
	}
	// all ok, so add the devices
	for (device_index = 0; device_index < devices_found; ++device_index) {
		DirblobAdd(EP3.sn[device_index], &(ds->gulp));
	}
	ds->LastDiscrepancy = FindDiscrepancy(EP3.sn[devices_found-1], EP3.sn[devices_found]);
	ds->LastDevice = (bytes_back == devices_found * SERIAL_NUMBER_SIZE);	// no more to read

	return search_good;
}
Esempio n. 8
0
void BUS_next_cleanup( struct device_search *ds )
{
	DirblobClear(&(ds->gulp));
}	
Esempio n. 9
0
void Detail_Close( void ) 
{
	DirblobClear( & (DD.sn) ) ;
	DirblobClear( & (DD.length) ) ;
}