/* 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)); }
/* 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; }
static void GetAllDeviceNames( struct port_in * pin ) { struct connection_in * in = pin->first ; ASCII * remaining_device_list = owstrdup( pin->init_data ) ; ASCII * remember_location = remaining_device_list ; while (remaining_device_list != NULL) { const ASCII *current_device_start; for (current_device_start = strsep(&remaining_device_list, " ,"); current_device_start[0] != '\0'; ++current_device_start) { // note that strsep updates "remaining_device_list" pointer if (current_device_start[0] != ' ' && current_device_start[0] != ',') { break; } } GetDeviceName( ¤t_device_start, in ) ; } SAFEFREE( remember_location ) ; in->AnyDevices = (DirblobElements(&(in->master.fake.main)) > 0) ? anydevices_yes : anydevices_no ; }
static void GetDeviceName(const ASCII ** strpointer, struct connection_in * in) { BYTE sn[SERIAL_NUMBER_SIZE] ; BYTE dn[SERIAL_NUMBER_SIZE] ; if ( isxdigit((*strpointer)[0]) && isxdigit((*strpointer)[1]) ) { // family code specified sn[0] = string2num(*strpointer); *strpointer += 2; GetDefaultDeviceName( dn, sn, in ) ; // Choice of default or specified ID GetNextByte(strpointer,dn[1],&sn[1]); GetNextByte(strpointer,dn[2],&sn[2]); GetNextByte(strpointer,dn[3],&sn[3]); GetNextByte(strpointer,dn[4],&sn[4]); GetNextByte(strpointer,dn[5],&sn[5]); GetNextByte(strpointer,dn[6],&sn[6]); } else { const ASCII * name_to_familycode = namefind((*strpointer)) ; if ( name_to_familycode != NULL) { // device name specified (e.g. DS2401) sn[0] = string2num(name_to_familycode); GetDefaultDeviceName( dn, sn, in ) ; sn[1] = dn[1] ; sn[2] = dn[2] ; sn[3] = dn[3] ; sn[4] = dn[4] ; sn[5] = dn[5] ; sn[6] = dn[6] ; } else { // Bad device name LEVEL_DEFAULT("Device %d <%s> not recognized for %s %d -- ignored",DirblobElements(&(in->master.fake.main))+1,*strpointer,in->adapter_name,in->master.fake.index); return ; } } sn[SERIAL_NUMBER_SIZE-1] = CRC8compute(sn, SERIAL_NUMBER_SIZE-1, 0); DirblobAdd(sn, &(in->master.fake.main)); // Ignore bad return }
/* 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; }