GOOD_OR_BAD OWQ_allocate_write_buffer( const char * write_buffer, size_t buffer_length, off_t offset, struct one_wire_query * owq ) { char * buffer_copy ; if ( buffer_length == 0 ) { // Buffer size is zero. Allowed, but make it NULL and no cleanup needed. OWQ_size(owq) = 0 ; OWQ_offset(owq) = 0 ; return gbGOOD ; } buffer_copy = owmalloc( buffer_length+1) ; if ( buffer_copy == NULL) { // cannot allocate space for buffer LEVEL_DEBUG("Cannot allocate %ld bytes for buffer", buffer_length) ; OWQ_size(owq) = 0 ; OWQ_offset(owq) = 0 ; return gbBAD ; } memcpy( buffer_copy, write_buffer, buffer_length) ; buffer_copy[buffer_length] = '\0' ; // make sure it's zero-ended OWQ_buffer(owq) = buffer_copy ; OWQ_size(owq) = buffer_length ; OWQ_length(owq) = buffer_length ; OWQ_offset(owq) = offset ; OWQ_cleanup(owq) |= owq_cleanup_buffer ; // buffer needs cleanup return gbGOOD ; }
ZERO_OR_ERROR COMMON_offset_process( ZERO_OR_ERROR (*func) (struct one_wire_query *), struct one_wire_query * owq, off_t shift_offset) { ZERO_OR_ERROR func_return_value ; OWQ_offset(owq) += shift_offset ; func_return_value = func(owq) ; OWQ_offset(owq) -= shift_offset ; return func_return_value ; }
static ZERO_OR_ERROR OW_read_external_script( struct sensor_node * sensor_n, struct property_node * property_n, struct one_wire_query * owq ) { char cmd[PATH_MAX+1] ; struct parsedname * pn = PN(owq) ; FILE * script_f ; int snp_return ; ZERO_OR_ERROR zoe ; // load the command script and arguments if ( pn->sparse_name == NULL ) { // not a text sparse name snp_return = snprintf( cmd, PATH_MAX+1, "%s %s %s %d %s %d %d %s %s", property_n->read, // command sensor_n->name, // sensor name property_n->property, // property, pn->extension, // extension "read", // mode (int) OWQ_size(owq), // size (int) OWQ_offset(owq), // offset sensor_n->data, // sensor-specific data property_n->data // property-specific data ) ; } else { snp_return = snprintf( cmd, PATH_MAX+1, "%s %s %s %s %s %d %d %s %s", property_n->read, // command sensor_n->name, // sensor name property_n->property, // property, pn->sparse_name, // extension "read", // mode (int) OWQ_size(owq), // size (int) OWQ_offset(owq), // offset sensor_n->data, // sensor-specific data property_n->data // property-specific data ) ; } if ( snp_return < 0 ) { LEVEL_DEBUG("Problem creating script string for %s/%s",sensor_n->name,property_n->property) ; return -EINVAL ; } script_f = popen( cmd, "r" ) ; if ( script_f == NULL ) { ERROR_DEBUG("Cannot create external program link for reading %s/%s",sensor_n->name,property_n->property); return -EIO ; } zoe = OW_script_read( script_f, owq ) ; fclose( script_f ) ; return zoe ; }
void OWQ_create_temporary(struct one_wire_query *owq_temporary, char *buffer, size_t size, off_t offset, struct parsedname *pn) { OWQ_buffer(owq_temporary) = buffer; OWQ_size(owq_temporary) = size; OWQ_offset(owq_temporary) = offset; memcpy(PN(owq_temporary), pn, sizeof(struct parsedname)); }
static ZERO_OR_ERROR FS_w_TS(struct one_wire_query *owq) { ZERO_OR_ERROR ret = 0; if (OWQ_size(owq) == 0 || OWQ_offset(owq) > 0) { return 0; /* do nothing */ } switch (OWQ_buffer(owq)[0]) { case 'C': case 'c': Globals.temp_scale = temp_celsius ; break; case 'F': case 'f': Globals.temp_scale = temp_fahrenheit ; break; case 'R': case 'r': Globals.temp_scale = temp_rankine ; break; case 'K': case 'k': Globals.temp_scale = temp_kelvin ; break; default: ret = -EINVAL; } SetLocalControlFlags() ; return ret; }
/* Put a string ionto the OWQ structure and return the length check lengths and offsets as part of the process */ static SIZE_OR_ERROR OWQ_parse_output_offset_and_size(const char *string, size_t length, struct one_wire_query *owq) { size_t copy_length = length; off_t offset = OWQ_offset(owq); Debug_Bytes("OWQ_parse_output_offset_and_size", (const BYTE *) string, length); /* offset is after the length of the string -- return 0 since some conditions a read after the end is done automatically */ if (offset > (off_t) length) { return 0; } /* correct length for offset (cannot be negative because of previous check) */ copy_length -= offset; /* correct length for buffer space */ if (copy_length > OWQ_size(owq)) { copy_length = OWQ_size(owq); } /* and copy */ memcpy(OWQ_buffer(owq), &string[offset], copy_length); // Warning, this will overwrite the I U or DATA value, // but that shouldn't matter since it's only called on ascii values // and all structure values OWQ_length(owq) = copy_length; return copy_length; }
/* Use an single OWQ as a template for the aggregate one */ struct one_wire_query * OWQ_create_aggregate( struct one_wire_query * owq_single ) { int sz = sizeof( struct one_wire_query ) + OWQ_DEFAULT_READ_BUFFER_SIZE; struct one_wire_query * owq_all = owmalloc( sz ); LEVEL_DEBUG("%s with extension ALL", PN(owq_single)->path); if ( owq_all == NO_ONE_WIRE_QUERY) { LEVEL_DEBUG("No memory to create object for extension ALL") ; return NO_ONE_WIRE_QUERY ; } memset(owq_all, 0, sz); OWQ_cleanup(owq_all) = owq_cleanup_owq ; memcpy( PN(owq_all), PN(owq_single), sizeof(struct parsedname) ) ; PN(owq_all)->extension = EXTENSION_ALL ; OWQ_buffer(owq_all) = (char *) (& owq_all[1]) ; // point just beyond the one_wire_query struct OWQ_size(owq_all) = OWQ_DEFAULT_READ_BUFFER_SIZE ; OWQ_offset(owq_all) = 0 ; if ( BAD( OWQ_allocate_array(owq_all)) ) { OWQ_destroy(owq_all); return NO_ONE_WIRE_QUERY ; } return owq_all ; }
/* cm.ret is also set to an error <0 or the read length */ void *ReadHandler(struct handlerdata *hd, struct client_msg *cm, struct one_wire_query *owq) { BYTE * retbuffer = NULL ; SIZE_OR_ERROR read_or_error; LEVEL_DEBUG("ReadHandler start"); if (hd == NULL || owq == NULL || cm == NULL) { LEVEL_DEBUG("ReadHandler: illegal null inputs hd==%p owq==%p cm==%p", hd, owq, cm); return NULL; // only sane response for bad inputs } LEVEL_DEBUG("ReadHandler: From Client sm->payload=%d sm->size=%d sm->offset=%d", hd->sm.payload, hd->sm.size, hd->sm.offset); if (hd->sm.payload >= PATH_MAX) { cm->ret = -EMSGSIZE; } else if ((hd->sm.size <= 0) || (hd->sm.size > MAX_OWSERVER_PROTOCOL_PAYLOAD_SIZE)) { cm->ret = -EMSGSIZE; LEVEL_DEBUG("ReadHandler: error hd->sm.size == %d", hd->sm.size); } else if ( BAD( OWQ_allocate_read_buffer(owq)) ) { // allocate read buffer LEVEL_DEBUG("ReadHandler: can't allocate memory"); cm->ret = -ENOBUFS; } else { struct parsedname *pn = PN(owq); if ( OWQ_size(owq) > (size_t) hd->sm.size ) { OWQ_size(owq) = hd->sm.size ; } OWQ_offset(owq) = hd->sm.offset ; LEVEL_DEBUG("ReadHandler: call FS_read_postparse on %s", pn->path); read_or_error = FS_read_postparse(owq); LEVEL_DEBUG("ReadHandler: FS_read_postparse read on %s return = %d", pn->path, read_or_error); Debug_OWQ(owq); if (read_or_error <= 0) { LEVEL_DEBUG("ReadHandler: FS_read_postparse error %d", read_or_error); cm->ret = read_or_error; } else { LEVEL_DEBUG("ReadHandler: FS_read_postparse ok size=%d", read_or_error); // make return size smaller (just large enough) cm->payload = read_or_error; cm->offset = hd->sm.offset; cm->size = read_or_error; cm->ret = read_or_error; /* Move this pointer, and let owfree remove it instead of OWQ_destroy() */ retbuffer = (BYTE *)OWQ_buffer(owq); OWQ_buffer(owq) = NULL; } } LEVEL_DEBUG("ReadHandler: To Client cm->payload=%d cm->size=%d cm->offset=%d", cm->payload, cm->size, cm->offset); if ((cm->size > 0)) { Debug_Bytes("Data returned to client",(BYTE *) OWQ_buffer(owq),cm->size) ; } return retbuffer; }
/* If offset is too large, size is set to 0 */ static void adjust_file_size(struct one_wire_query *owq) { size_t file_length = 0; /* Adjust file length -- especially important for fuse which uses 4k buffers */ /* First file filelength */ file_length = FullFileLength(PN(owq)); /* next adjust for offset */ if ((unsigned long) OWQ_offset(owq) >= (unsigned long) file_length) { // This check is done in OWQ_parse_output() too, since it's always called when this function OWQ_size(owq) = 0 ; // this is status ok... but 0 bytes were read... } else if ( OWQ_size(owq) + OWQ_offset(owq) > file_length ) { // Finally adjust buffer length OWQ_size(owq) = file_length - OWQ_offset(owq) ; } LEVEL_DEBUG("file_length=%lu offset=%lu size=%lu", (unsigned long) file_length, (unsigned long) OWQ_offset(owq), (unsigned long) OWQ_size(owq)); }
/* Create the Parsename structure and load the relevant fields */ struct one_wire_query * OWQ_create_sibling(const char *sibling, struct one_wire_query *owq_original) { char path[PATH_MAX] ; struct parsedname * pn_original = PN(owq_original) ; int dirlength = pn_original->dirlength ; struct one_wire_query * owq_sib ; strncpy(path, pn_original->path,dirlength) ; strcpy(&path[dirlength],sibling) ; if ( pn_original->selected_filetype == NO_FILETYPE ) { if ( pn_original->subdir == NO_SUBDIR ) { // not a filetype or a subdir return NO_ONE_WIRE_QUERY ; } // Add extension only if original property is aggregate } else if ( pn_original->selected_filetype->ag != NON_AGGREGATE ) { // search for sibling in the filetype array struct filetype * sib_filetype = bsearch(sibling, pn_original->selected_device->filetype_array, (size_t) pn_original->selected_device->count_of_filetypes, sizeof(struct filetype), filetype_cmp) ; // see if sibling is also an aggregate property LEVEL_DEBUG("Path %s is an agggregate",SAFESTRING(pn_original->path)); if ( sib_filetype != NO_FILETYPE && sib_filetype->ag != NON_AGGREGATE ) { char * aggregate_point = path + strlen(path) ; LEVEL_DEBUG("Sibling is also an aggregate",sibling); if (pn_original->extension == EXTENSION_BYTE ) { strcpy( aggregate_point, ".BYTE" ) ; } else if (pn_original->extension == EXTENSION_ALL ) { strcpy( aggregate_point, ".ALL" ) ; } else if (sib_filetype->ag->letters == ag_letters) { UCLIBCLOCK; snprintf(aggregate_point, OW_FULLNAME_MAX, ".%c", pn_original->extension + 'A'); UCLIBCUNLOCK; } else { UCLIBCLOCK; snprintf(aggregate_point, OW_FULLNAME_MAX, ".%d", pn_original->extension ); UCLIBCUNLOCK; } } } LEVEL_DEBUG("Create sibling %s from %s as %s", sibling, pn_original->path,path); owq_sib = OWQ_create_from_path(path) ; if ( owq_sib != NO_ONE_WIRE_QUERY ) { // Sib has no offset OWQ_offset(owq_sib) = 0 ; // Make uncached as restrictive as original // Make unaliased as restrictive as original PN(owq_sib)->state |= (pn_original->state & (ePS_uncached|ePS_unaliased) ) ; return owq_sib ; } return NO_ONE_WIRE_QUERY ; }
static ZERO_OR_ERROR FS_w_screenX(struct one_wire_query *owq) { struct one_wire_query * owq_line ; int extension; struct parsedname *pn = PN(owq); int width = pn->selected_filetype->data.i; int rows = (width == 40) ? 2 : 4; /* max number of rows */ char *start_of_remaining_text = OWQ_buffer(owq); char *pointer_after_all_text = OWQ_buffer(owq) + OWQ_size(owq); if (OWQ_offset(owq)) { return -ERANGE; } if (BAD( OW_clear(pn) ) ) { return -EFAULT; } owq_line = OWQ_create_separate( 0, owq ) ; if ( owq_line == NO_ONE_WIRE_QUERY ) { return -ENOMEM ; } for (extension = 0; extension < rows; ++extension) { char *newline_location = memchr(start_of_remaining_text, '\n', pointer_after_all_text - start_of_remaining_text); OWQ_pn(owq_line).extension = extension; OWQ_buffer(owq_line) = start_of_remaining_text; if ((newline_location != NULL) && (newline_location < start_of_remaining_text + width)) { OWQ_size(owq_line) = newline_location - start_of_remaining_text; start_of_remaining_text = newline_location + 1; /* skip over newline */ } else { char *lineend_location = start_of_remaining_text + width; if (lineend_location > pointer_after_all_text) { lineend_location = pointer_after_all_text; } OWQ_size(owq_line) = lineend_location - start_of_remaining_text; start_of_remaining_text = lineend_location; } if (FS_w_lineX(owq_line)) { OWQ_destroy( owq_line ) ; return -EINVAL; } if (start_of_remaining_text >= pointer_after_all_text) break; } OWQ_destroy( owq_line ) ; return 0; }
void _print_owq(struct one_wire_query *owq) { char c[32]; fprintf(stderr,"OWQ OneWireQuery structure of %s\n", PN(owq)->path); fprintf(stderr," OneWireQuery size=%lu offset=%lu, extension=%d\n", (unsigned long) OWQ_size(owq), (unsigned long) OWQ_offset(owq), (int) OWQ_pn(owq).extension); if ( OWQ_buffer(owq) != NULL ) { Debug_Bytes("OneWireQuery buffer", (BYTE *) OWQ_buffer(owq), OWQ_size(owq)); } fprintf(stderr," Cleanup = %.4X",OWQ_cleanup(owq)); fprintf(stderr," OneWireQuery I=%d U=%u F=%G Y=%d D=%s\n", OWQ_I(owq), OWQ_U(owq), OWQ_F(owq), OWQ_Y(owq), SAFESTRING(ctime_r(&OWQ_D(owq), c))); fprintf(stderr,"--- OneWireQuery done\n"); }
static ZERO_OR_ERROR FS_redefchar(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if ( OWQ_size(owq) != LCD_REDEFCHAR_LENGTH ) { return -ERANGE ; } if ( OWQ_offset(owq) != 0 ) { return -ERANGE ; } return GB_to_Z_OR_E( OW_redefchar( OWQ_buffer(owq), pn ) ) ; }
void OWQ_assign_write_buffer(const char *buffer, size_t size, off_t offset, struct one_wire_query *owq) { // OWQ_buffer used for both read (non-const) and write (const) #if ( __GNUC__ > 4 ) || (__GNUC__ == 4 && __GNUC_MINOR__ > 4 ) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" OWQ_buffer(owq) = (char *) buffer; #pragma GCC diagnostic pop #else OWQ_buffer(owq) = (char *) buffer; #endif OWQ_size(owq) = size; OWQ_offset(owq) = offset; }
static ZERO_OR_ERROR FS_w_port_raw(struct one_wire_query *owq) { BYTE *buf = (BYTE *) OWQ_buffer(owq); size_t len = OWQ_size(owq); if (OWQ_offset(owq) != 0) return -EINVAL; /* ignore? */ // Hack for testing, otherwise we'll not be able to clear a port using owwrite. if(len == 1 && (*buf == '0' || *buf == '1')) { *buf -= '0'; } return GB_to_Z_OR_E( OW_w_std( buf,len, M_PORT,OWQ_pn(owq).extension, PN(owq)) ) ; }
/* No CRC -- 0xF0 code */ GOOD_OR_BAD COMMON_read_memory_F0(struct one_wire_query *owq, size_t page, size_t pagesize) { off_t offset = OWQ_offset(owq) + page * pagesize; BYTE p[3] = { _1W_READ_F0, LOW_HIGH_ADDRESS(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE3(p), TRXN_READ((BYTE *) OWQ_buffer(owq), OWQ_size(owq)), TRXN_END, }; Set_OWQ_length(owq); return BUS_transaction(t, PN(owq)); }
/* Higher level add of a one-wire-query object */ GOOD_OR_BAD OWQ_Cache_Add(const struct one_wire_query *owq) { const struct parsedname *pn = PN(owq); if (pn->extension == EXTENSION_ALL) { switch (pn->selected_filetype->format) { case ft_ascii: case ft_vascii: case ft_alias: case ft_binary: return gbBAD; // cache of string arrays not supported case ft_integer: case ft_unsigned: case ft_yesno: case ft_date: case ft_float: case ft_pressure: case ft_temperature: case ft_tempgap: LEVEL_DEBUG("Adding data for %s", SAFESTRING(pn->path) ); return Cache_Add(OWQ_array(owq), (pn->selected_filetype->ag->elements) * sizeof(union value_object), pn); default: return gbBAD; } } else { switch (pn->selected_filetype->format) { case ft_ascii: case ft_vascii: case ft_alias: case ft_binary: if (OWQ_offset(owq) > 0) { return gbBAD; } LEVEL_DEBUG("Adding data for %s", SAFESTRING(pn->path) ); return Cache_Add(OWQ_buffer(owq), OWQ_length(owq), pn); case ft_integer: case ft_unsigned: case ft_yesno: case ft_date: case ft_float: case ft_pressure: case ft_temperature: case ft_tempgap: LEVEL_DEBUG("Adding data for %s", SAFESTRING(pn->path) ); return Cache_Add(&OWQ_val(owq), sizeof(union value_object), pn); default: return gbBAD; } } }
static ZERO_OR_ERROR FS_redefchar_hex(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); BYTE data[LCD_REDEFCHAR_LENGTH] ; if ( OWQ_size(owq) != LCD_REDEFCHAR_LENGTH * 2 ) { return -ERANGE ; } if ( OWQ_offset(owq) != 0 ) { return -ERANGE ; } string2bytes( OWQ_buffer(owq), data, LCD_REDEFCHAR_LENGTH ) ; return GB_to_Z_OR_E( OW_redefchar( OWQ_buffer(owq), pn ) ) ; }
// Handles: ALL static ZERO_OR_ERROR FS_write_in_parts( struct one_wire_query *owq_all ) { struct one_wire_query * owq_part = OWQ_create_separate( 0, owq_all ) ; struct parsedname *pn = PN(owq_all); size_t elements = pn->selected_filetype->ag->elements; size_t extension ; char *buffer_pointer; ZERO_OR_ERROR z_or_e = 0 ; // Create a "single" OWQ copy to iterate with if ( owq_part == NO_ONE_WIRE_QUERY ) { return -ENOENT ; } // create a buffer for certain types // point to 0th element's buffer first buffer_pointer = OWQ_buffer(owq_all); OWQ_size(owq_part) = FileLength(PN(owq_part)); OWQ_offset(owq_part) = 0; // loop through all eloements for (extension = 0; extension < elements; ++extension) { ZERO_OR_ERROR single_write; switch (pn->selected_filetype->format) { case ft_ascii: case ft_vascii: case ft_alias: case ft_binary: OWQ_length(owq_part) = OWQ_array_length(owq_all,extension) ; OWQ_buffer(owq_part) = buffer_pointer; buffer_pointer += OWQ_length(owq_part); break; default: memcpy(&OWQ_val(owq_part), &OWQ_array(owq_all)[extension], sizeof(union value_object)); break; } OWQ_pn(owq_part).extension = extension; single_write = FS_write_owq(owq_part); if (single_write != 0) { z_or_e = single_write ; } } return z_or_e; }
ZERO_OR_ERROR FS_read_tester(struct one_wire_query *owq) { switch (OWQ_pn(owq).extension) { case EXTENSION_ALL: /* array */ if (OWQ_offset(owq)) { return 0; } if (OWQ_size(owq) < FullFileLength(PN(owq))) { return -ERANGE; } return FS_read_tester_array(owq); case EXTENSION_BYTE: /* bitfield */ default: return FS_read_tester_single(owq); } }
static ZERO_OR_ERROR FS_w_PS(struct one_wire_query *owq) { int ret = -EINVAL ; enum pressure_type pindex ; if (OWQ_size(owq) < 2 || OWQ_offset(owq) > 0) { return -EINVAL ; /* do nothing */ } for ( pindex = 0 ; pindex < pressure_end_mark ; ++pindex ) { if ( strncasecmp( OWQ_buffer(owq), PressureScaleName(pindex), 2 ) == 0 ) { Globals.pressure_scale = pindex ; SetLocalControlFlags() ; ret = 0 ; break; } } return ret; }
// create the buffer of size filesize GOOD_OR_BAD OWQ_allocate_read_buffer(struct one_wire_query * owq ) { struct parsedname * pn = PN(owq) ; size_t size = FullFileLength(pn); if ( size > 0 ) { char * buffer = owmalloc(size+1) ; if ( buffer == NULL ) { return gbBAD ; } memset(buffer,0,size+1) ; OWQ_buffer(owq) = buffer ; OWQ_size(owq) = size ; OWQ_offset(owq) = 0 ; OWQ_cleanup(owq) |= owq_cleanup_buffer ; } return gbGOOD; }
static ZERO_OR_ERROR FS_w_page(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); ZERO_OR_ERROR z_or_e ; // Special case for NV1 (page 0) -- need to unlock if ( pn->extension == 0 ) { RETURN_ERROR_IF_BAD( OW_nv1_unlock( pn ) ) ; } z_or_e = OW_w_page((BYTE *) OWQ_buffer(owq), OWQ_size(owq), OWQ_offset(owq) + (pn->extension)*_1W_2436_PAGESIZE, pn) ; // Special case for NV1 (page 0) -- need to relock if ( pn->extension == 0 ) { OW_nv1_lock( pn ) ; } return z_or_e ; }
static ZERO_OR_ERROR FS_w_lineX(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); int width = pn->selected_filetype->data.i; BYTE lcd_line_start[] = { 0x00, 0x40, 0x00 + width, 0x40 + width }; char line[width]; size_t size = OWQ_size(owq); int start = OWQ_offset(owq); if (start >= width) { return -EADDRNOTAVAIL; } if ((int) (start + size) > width) { size = width - start; } memset(line, ' ', width); memcpy(&line[start], OWQ_buffer(owq), size); return GB_to_Z_OR_E(OW_w_screen(lcd_line_start[pn->extension], line, width, pn)) ; }
/* Extra 8 bytes, (for counter) too -- discarded */ GOOD_OR_BAD COMMON_read_memory_toss_counter(struct one_wire_query *owq, size_t page, size_t pagesize) { off_t offset = OWQ_offset(owq) + page * pagesize; BYTE p[3 + pagesize + 8 + 2]; int rest = pagesize - (offset % pagesize); struct transaction_log t[] = { TRXN_START, TRXN_WR_CRC16(p, 3, rest + 8), TRXN_END, }; p[0] = _1W_READ_A5; p[1] = BYTE_MASK(offset); p[2] = BYTE_MASK(offset >> 8); RETURN_BAD_IF_BAD(BUS_transaction(t, PN(owq))) ; memcpy(OWQ_buffer(owq), &p[3], OWQ_size(owq)); Set_OWQ_length(owq); return gbGOOD; }
/* read up to end of page to CRC16 -- 0xA5 code */ static GOOD_OR_BAD OW_r_crc16(BYTE code, struct one_wire_query *owq, size_t page, size_t pagesize) { off_t offset = OWQ_offset(owq) + page * pagesize; size_t size = OWQ_size(owq); BYTE p[3 + pagesize + 2]; int rest = pagesize - (offset % pagesize); struct transaction_log t[] = { TRXN_START, TRXN_WR_CRC16(p, 3, rest), TRXN_END, }; p[0] = code; p[1] = BYTE_MASK(offset); p[2] = BYTE_MASK(offset >> 8); RETURN_BAD_IF_BAD(BUS_transaction(t, PN(owq))) ; memcpy(OWQ_buffer(owq), &p[3], size); Set_OWQ_length(owq); return gbGOOD; }
/* Use an aggregate OWQ as a template for a single element */ struct one_wire_query * OWQ_create_separate( int extension, struct one_wire_query * owq_aggregate ) { int sz = sizeof( struct one_wire_query ) + OWQ_DEFAULT_READ_BUFFER_SIZE; struct one_wire_query * owq_sep = owmalloc( sz ); LEVEL_DEBUG("%s with extension %d", PN(owq_aggregate)->path,extension); if ( owq_sep== NO_ONE_WIRE_QUERY) { LEVEL_DEBUG("No memory to create object for extension %d",extension) ; return NO_ONE_WIRE_QUERY ; } memset(owq_sep, 0, sz); OWQ_cleanup(owq_sep) = owq_cleanup_owq ; memcpy( PN(owq_sep), PN(owq_aggregate), sizeof(struct parsedname) ) ; PN(owq_sep)->extension = extension ; OWQ_buffer(owq_sep) = (char *) (& owq_sep[1]) ; // point just beyond the one_wire_query struct OWQ_size(owq_sep) = OWQ_DEFAULT_READ_BUFFER_SIZE ; OWQ_offset(owq_sep) = 0 ; return owq_sep ; }
static ZERO_OR_ERROR FS_r_page(struct one_wire_query *owq) { size_t pagesize = 32; return GB_to_Z_OR_E( OW_r_page( (BYTE *) OWQ_buffer(owq), OWQ_size(owq), OWQ_offset(owq) + pagesize * PN(owq)->extension, PN(owq) ) ) ; }
static ZERO_OR_ERROR FS_w_console(struct one_wire_query *owq) { if (OWQ_offset(owq) != 0) return -EINVAL; /* ignore? */ return GB_to_Z_OR_E( OW_w_std( (BYTE *) OWQ_buffer(owq), OWQ_size(owq), M_CONSOLE,1, PN(owq)) ) ; }
SIZE_OR_ERROR OWQ_parse_output(struct one_wire_query *owq) { // have to check if offset is beyond the filesize. if (OWQ_offset(owq)) { size_t file_length = 0; file_length = FileLength(PN(owq)); LEVEL_DEBUG("file_length=%lu offset=%lu size=%lu", (unsigned long) file_length, (unsigned long) OWQ_offset(owq), (unsigned long) OWQ_size(owq)); if ((unsigned long) OWQ_offset(owq) >= (unsigned long) file_length) { return 0; // This is data-length } } /* Special case, structure is always ascii */ if (OWQ_pn(owq).type == ePN_structure) { return OWQ_parse_output_ascii(owq); } switch (OWQ_pn(owq).extension) { case EXTENSION_BYTE: return OWQ_parse_output_unsigned(owq); case EXTENSION_ALL: switch (OWQ_pn(owq).selected_filetype->format) { case ft_ascii: case ft_vascii: case ft_alias: return OWQ_parse_output_ascii_array(owq); case ft_binary: return OWQ_parse_output_array_no_commas(owq); default: return OWQ_parse_output_array_with_commas(owq); } default: switch (OWQ_pn(owq).selected_filetype->format) { case ft_integer: return OWQ_parse_output_integer(owq); case ft_yesno: case ft_bitfield: return OWQ_parse_output_yesno(owq); case ft_unsigned: return OWQ_parse_output_unsigned(owq); case ft_pressure: case ft_temperature: case ft_tempgap: case ft_float: return OWQ_parse_output_float(owq); case ft_date: return OWQ_parse_output_date(owq); case ft_vascii: case ft_alias: case ft_ascii: case ft_binary: return OWQ_parse_output_ascii(owq); case ft_directory: case ft_subdir: case ft_unknown: return -ENOENT; } } return -EINVAL; // should never be reached if all the cases are truly covered }