/* Write now that connection is set */ static ZERO_OR_ERROR FS_w_given_bus(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if ( BAD(TestConnection(pn)) ) { return -ECONNABORTED; } else if (KnownBus(pn) && BusIsServer(pn->selected_connection)) { return ServerWrite(owq); } else if (OWQ_pn(owq).type == ePN_real) { ZERO_OR_ERROR write_or_error = DeviceLockGet(pn); if (write_or_error == 0) { write_or_error = FS_w_local(owq); DeviceLockRelease(pn); } else { LEVEL_DEBUG("Cannot lock device for writing") ; } return write_or_error ; } else if ( IsInterfaceDir(pn) ) { ZERO_OR_ERROR write_or_error; BUSLOCK(pn); write_or_error = FS_w_local(owq); BUSUNLOCK(pn); return write_or_error ; } else { return FS_w_local(owq); } }
static ZERO_OR_ERROR FS_r_timeout(struct one_wire_query *owq) { CACHE_RLOCK; OWQ_U(owq) = ((UINT *) OWQ_pn(owq).selected_filetype->data.v)[0]; CACHE_RUNLOCK; return 0; }
static ZERO_OR_ERROR FS_write_owq(struct one_wire_query *owq) { ZERO_OR_ERROR write_error = (OWQ_pn(owq).selected_filetype->write) (owq); OWQ_Cache_Del(owq) ; // Delete anyways LEVEL_DEBUG("Write %s Extension %d Gives result %d",PN(owq)->path,PN(owq)->extension,write_error); return write_error; }
static SIZE_OR_ERROR OWQ_parse_output_float(struct one_wire_query *owq) { /* should only need suglen+1, but uClibc's snprintf() seem to trash 'len' if not increased */ int len; char c[PROPERTY_LENGTH_FLOAT + 2]; _FLOAT F; switch (OWQ_pn(owq).selected_filetype->format) { case ft_pressure: F = Pressure(OWQ_F(owq), PN(owq)); break; case ft_temperature: F = Temperature(OWQ_F(owq), PN(owq)); break; case ft_tempgap: F = TemperatureGap(OWQ_F(owq), PN(owq)); break; default: F = OWQ_F(owq); break; } UCLIBCLOCK; if ( ShouldTrim(PN(owq)) ) { len = snprintf(c, PROPERTY_LENGTH_FLOAT + 1, "%1G", F); } else { len = snprintf(c, PROPERTY_LENGTH_FLOAT + 1, "%*G", PROPERTY_LENGTH_FLOAT, F); } UCLIBCUNLOCK; if ((len < 0) || ((size_t) len > PROPERTY_LENGTH_FLOAT)) { return -EMSGSIZE; } return OWQ_parse_output_offset_and_size(c, len, owq); }
static ZERO_OR_ERROR FS_r_page(struct one_wire_query *owq) { size_t pagesize = 32; if (COMMON_read_memory_F0(owq, OWQ_pn(owq).extension, pagesize)) { return -EINVAL; } return 0; }
// Write a whole aggregate array (treated as a single large value ) // handles ALL static ZERO_OR_ERROR FS_write_all( struct one_wire_query * owq_all ) { // bitfield, convert to .BYTE format and write ( and delete cache ) as BYTE. if ( OWQ_pn(owq_all).selected_filetype->format == ft_bitfield ) { return FS_write_all_bits( owq_all ) ; } return FS_write_owq( owq_all ) ; }
static ZERO_OR_ERROR FS_r_port_raw(struct one_wire_query *owq) { BYTE buf[1]; size_t len = OWQ_size(owq); if(len>sizeof(buf)) len=sizeof(buf); RETURN_ERROR_IF_BAD( OW_r_std(buf,&len, M_PORT, OWQ_pn(owq).extension, PN(owq))); return OWQ_format_output_offset_and_size((const char *)buf, len, owq); }
/* called when pn->extension==EXTENSION_ALL and pn->selected_filetype->ag->combined==ag_separate */ static ZERO_OR_ERROR FS_read_tester_array(struct one_wire_query *owq) { size_t elements = OWQ_pn(owq).selected_filetype->ag->elements; size_t extension; size_t entry_length = FileLength(PN(owq)); for (extension = 0; extension < elements; ++extension) { struct one_wire_query * owq_single = OWQ_create_separate( extension, owq ) ; if ( owq_single == NO_ONE_WIRE_QUERY ) { return -ENOMEM ; } switch (OWQ_pn(owq).selected_filetype->format) { case ft_integer: case ft_yesno: case ft_bitfield: case ft_unsigned: case ft_pressure: case ft_temperature: case ft_tempgap: case ft_float: case ft_date: break; case ft_vascii: case ft_alias: case ft_ascii: case ft_binary: OWQ_assign_read_buffer(&OWQ_buffer(owq)[extension * entry_length],entry_length,0,owq_single) ; break; case ft_directory: case ft_subdir: case ft_unknown: OWQ_destroy(owq_single) ; return -ENOENT; } if (FS_read_tester_single(owq_single)) { OWQ_destroy(owq_single) ; return -EINVAL; } memcpy(&OWQ_array(owq)[extension], &OWQ_val(owq_single), sizeof(union value_object)); OWQ_destroy(owq_single) ; } return 0; }
static SIZE_OR_ERROR OWQ_parse_output_array_no_commas(struct one_wire_query *owq) { size_t extension; size_t total_length = 0; size_t elements = OWQ_pn(owq).selected_filetype->ag->elements; for (extension = 0; extension < elements; ++extension) { total_length += OWQ_array_length(owq, extension); } return total_length; }
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; }
static void Set_OWQ_length(struct one_wire_query *owq) { switch (OWQ_pn(owq).selected_filetype->format) { case ft_binary: case ft_ascii: case ft_vascii: case ft_alias: OWQ_length(owq) = OWQ_size(owq); break; default: break; } }
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 SIZE_OR_ERROR OWQ_parse_output_array_with_commas(struct one_wire_query *owq) { struct one_wire_query owq_single; size_t extension; int len; size_t used_size = 0; size_t remaining_size = OWQ_size(owq); size_t elements = OWQ_pn(owq).selected_filetype->ag->elements; // loop though all array elements for (extension = 0; extension < elements; ++extension) { //printf("OWQ_parse_output_array_with_commas element=%d, size_used=%d, remaining=%d\n",(int)extension,(int)used_size,(int)remaining_size) ; // Prepare a copy of owq that only points to a single element memcpy(&owq_single, owq, sizeof(owq_single)); OWQ_pn(&owq_single).extension = extension; memcpy(&OWQ_val(&owq_single), &OWQ_array(owq)[extension], sizeof(union value_object)); // add the comma first (if not the first element and enough room) if (used_size > 0) { if (remaining_size == 0) { return -EFAULT; } OWQ_buffer(owq)[used_size] = ','; ++used_size; --remaining_size; } // Now process the single element OWQ_buffer(&owq_single) = &OWQ_buffer(owq)[used_size]; OWQ_size(&owq_single) = remaining_size; len = OWQ_parse_output(&owq_single); // any error aborts if (len < 0) { return len; } remaining_size -= len; used_size += len; } return used_size; }
// Handles: .n static ZERO_OR_ERROR FS_write_a_bit(struct one_wire_query *owq_bit) { struct one_wire_query * owq_byte = OWQ_create_separate( EXTENSION_BYTE, owq_bit ) ; ZERO_OR_ERROR z_or_e = -ENOENT ; if ( owq_byte != NO_ONE_WIRE_QUERY ) { if ( FS_read_local( owq_byte ) >= 0 ) { UT_setbit( (BYTE *) &OWQ_U( owq_byte ), OWQ_pn(owq_bit).extension, OWQ_Y(owq_bit) ) ; z_or_e = FS_write_owq( owq_byte ) ; } OWQ_destroy( owq_byte ) ; } return z_or_e ; }
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)) ) ; }
// handles: BYTE static ZERO_OR_ERROR FS_write_as_bits( struct one_wire_query *owq_byte ) { struct one_wire_query * owq_bit = OWQ_create_separate( 0, owq_byte ) ; size_t elements = OWQ_pn(owq_byte).selected_filetype->ag->elements; size_t extension ; ZERO_OR_ERROR z_or_e = 0 ; if ( owq_bit == NO_ONE_WIRE_QUERY ) { return -ENOENT ; } for ( extension = 0 ; extension < elements ; ++extension ) { ZERO_OR_ERROR z ; OWQ_pn(owq_bit).extension = extension ; OWQ_Y(owq_bit) = UT_getbit( (BYTE *) &OWQ_U(owq_byte), extension ) ; z = FS_write_owq( owq_bit ) ; if ( z != 0 ) { z_or_e = z ; } } OWQ_destroy( owq_bit ) ; return z_or_e ; }
/* ALL for aggregate * .n for separate * BYTE bitfield * */ static ZERO_OR_ERROR FS_read_owq(struct one_wire_query *owq) { // Bus and device already locked if ( BAD( OWQ_Cache_Get(owq)) ) { // not found ZERO_OR_ERROR read_error = (OWQ_pn(owq).selected_filetype->read) (owq); LEVEL_DEBUG("Read %s Extension %d Gives result %d",PN(owq)->path,PN(owq)->extension,read_error); if (read_error < 0) { return read_error; } OWQ_Cache_Add(owq); // Only add good attempts } else { LEVEL_DEBUG("Data obtained from cache") ; } return 0; }
// 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 SIZE_OR_ERROR OWQ_parse_output_ascii_array(struct one_wire_query *owq) { size_t extension; size_t elements = OWQ_pn(owq).selected_filetype->ag->elements; size_t total_length = 0; size_t current_offset = OWQ_array_length(owq, 0); for (extension = 0; extension < elements; ++extension) { total_length += OWQ_array_length(owq, extension); } for (extension = 1; extension < elements; ++extension) { memmove(&OWQ_buffer(owq)[current_offset + 1], &OWQ_buffer(owq)[current_offset], total_length - current_offset); OWQ_buffer(owq)[current_offset] = ','; ++total_length; current_offset += 1 + OWQ_array_length(owq, extension); } return total_length; }
// Handles: BYTE static ZERO_OR_ERROR FS_read_all_bits(struct one_wire_query *owq_byte) { struct one_wire_query * owq_bit = OWQ_create_separate( 0, owq_byte ) ; struct parsedname *pn = PN(owq_byte); size_t elements = pn->selected_filetype->ag->elements; size_t extension; if ( owq_bit == NO_ONE_WIRE_QUERY ) { return -ENOENT ; } /* Loop through F_r_single, just to get data */ for (extension = 0; extension < elements; ++extension) { OWQ_pn(owq_bit).extension = extension ; if ( FS_read_owq(owq_bit) < 0 ) { OWQ_destroy(owq_bit); return -EINVAL; } UT_setbit_U( &OWQ_U(owq_byte), extension, OWQ_Y(owq_bit) ) ; } OWQ_destroy(owq_bit); return 0; }
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 }
static ZERO_OR_ERROR FS_r_status(struct one_wire_query *owq) { size_t pagesize = FileLength(PN(owq)) ; return GB_to_Z_OR_E(COMMON_OWQ_readwrite_paged(owq, OWQ_pn(owq).extension, pagesize, COMMON_read_memory_crc16_AA)) ; }
/* write an 8-byte page */ static ZERO_OR_ERROR FS_w_page(struct one_wire_query *owq) { return COMMON_offset_process(FS_w_mem, owq, OWQ_pn(owq).extension*_1W_2450_PAGESIZE) ; }
static ZERO_OR_ERROR FS_r_yesno(struct one_wire_query *owq) { OWQ_Y(owq) = ((UINT *) OWQ_pn(owq).selected_filetype->data.v)[0]; return 0; }
static ZERO_OR_ERROR FS_counter(struct one_wire_query *owq) { size_t pagesize = 32; return GB_to_Z_OR_E(OW_r_counter(owq, OWQ_pn(owq).extension, pagesize)) ; }
static ZERO_OR_ERROR FS_w_yesno(struct one_wire_query *owq) { ((UINT *) OWQ_pn(owq).selected_filetype->data.v)[0] = OWQ_Y(owq); SetLocalControlFlags() ; return 0; }
// Handles: ALL static ZERO_OR_ERROR FS_read_in_parts( struct one_wire_query *owq_all ) { struct parsedname *pn = PN(owq_all); struct filetype * ft = pn->selected_filetype ; struct one_wire_query * owq_part ; size_t elements = pn->selected_filetype->ag->elements; size_t extension; char * buffer_pointer = OWQ_buffer(owq_all) ; size_t buffer_left = OWQ_size(owq_all) ; // single for BYTE or iteration owq_part = OWQ_create_separate( 0, owq_all ) ; if ( owq_part == NO_ONE_WIRE_QUERY ) { return -ENOENT ; } // bitfield if ( ft->format == ft_bitfield ) { OWQ_pn(owq_part).extension = EXTENSION_BYTE ; if ( FS_read_owq(owq_part) < 0 ) { OWQ_destroy( owq_part ) ; return -EINVAL ; } for (extension = 0; extension < elements; ++extension) { OWQ_array_Y(owq_all,extension) = UT_getbit_U( OWQ_U(owq_part), extension ) ; } OWQ_destroy( owq_part ) ; return 0 ; } if ( BAD( OWQ_allocate_read_buffer( owq_part )) ) { LEVEL_DEBUG("Can't allocate buffer space"); OWQ_destroy( owq_part ) ; return -EMSGSIZE ; } /* Loop through get data */ for (extension = 0; extension < elements; ++extension) { size_t part_length ; OWQ_pn(owq_part).extension = extension; if ( FS_read_owq(owq_part) < 0 ) { OWQ_destroy( owq_part ) ; return -EINVAL ; } // Check that there is enough space for the combined message switch ( ft->format ) { case ft_ascii: case ft_vascii: case ft_alias: case ft_binary: part_length = OWQ_length(owq_part) ; if ( buffer_left < part_length ) { OWQ_destroy( owq_part ) ; return -EMSGSIZE ; } memcpy( buffer_pointer, OWQ_buffer(owq_part), part_length ) ; OWQ_array_length(owq_all,extension) = part_length ; buffer_pointer += part_length ; buffer_left -= part_length ; break ; default: // copy object (single to mixed array) memcpy(&OWQ_array(owq_all)[extension], &OWQ_val(owq_part), sizeof(union value_object)); break; } } OWQ_destroy( owq_part ) ; return 0; }
static ZERO_OR_ERROR FS_w_page(struct one_wire_query *owq) { size_t pagesize = 32; return COMMON_offset_process( FS_w_mem, owq, OWQ_pn(owq).extension*pagesize ) ; }
static ZERO_OR_ERROR FS_define(struct one_wire_query *owq) { OWQ_Y(owq) = OWQ_pn(owq).selected_filetype->data.i; return 0; }