// This function should return number of bytes read... not status. static SIZE_OR_ERROR FS_r_given_bus(struct one_wire_query *owq) { // Device locking occurs here struct parsedname *pn = PN(owq); SIZE_OR_ERROR read_or_error = 0; LEVEL_DEBUG("About to read <%s> extension=%d size=%d offset=%d",SAFESTRING(pn->path),(int) pn->extension,(int) OWQ_size(owq),(int) OWQ_offset(owq)); if (KnownBus(pn) && BusIsServer(pn->selected_connection)) { /* The bus is not local... use a network connection instead */ LEVEL_DEBUG("pid=%ld call ServerRead", pthread_self()); // Read afar -- returns already formatted in buffer read_or_error = ServerRead(owq); LEVEL_DEBUG("back from server"); //printf("FS_r_given_bus pid=%ld r=%d\n",pthread_self(), read_or_error); } else { STAT_ADD1(read_calls); /* statistics */ if (DeviceLockGet(pn) == 0) { read_or_error = FS_r_local(owq); // this returns status DeviceLockRelease(pn); LEVEL_DEBUG("return=%d", read_or_error); if (read_or_error >= 0) { // local success -- now format in buffer read_or_error = OWQ_parse_output(owq); // this returns nr. bytes } } else { LEVEL_DEBUG("Cannot lock bus to perform read") ; read_or_error = -EADDRINUSE; } } LEVEL_DEBUG("After read is performed (bytes or error %d)", read_or_error); Debug_OWQ(owq); return read_or_error; }
/* 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; }
/* Handles 3-peat */ static ZERO_OR_ERROR FS_write_post_stats(struct one_wire_query *owq) { // Parse the data to be written ZERO_OR_ERROR input_or_error = OWQ_parse_input(owq); Debug_OWQ(owq); if (input_or_error < 0) { LEVEL_DEBUG("Error interpreting input value.") ; return input_or_error ; } return FS_write_post_input( owq ) ; }
// This function should return number of bytes read... not status. // Works for all the virtual directories, like statistics, interface, ... // Doesn't need three-peat and bus was already set or not needed. static SIZE_OR_ERROR FS_r_virtual(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); SIZE_OR_ERROR read_status = 0; if (SpecifiedRemoteBus(pn)) { /* The bus is not local... use a network connection instead */ // Read afar -- returns already formatted in buffer read_status = ServerRead(owq); LEVEL_DEBUG("back from server"); Debug_OWQ(owq); } else { /* local bus -- any special locking needs? */ STAT_ADD1(read_calls); /* statistics */ switch (pn->type) { case ePN_structure: read_status = FS_structure(owq); break; case ePN_interface: BUSLOCK(pn); read_status = FS_r_local(owq); // this returns status BUSUNLOCK(pn); break; case ePN_statistics: // reading /statistics/read/tries.ALL // will cause a deadlock since it calls STAT_ADD1(read_array); // Should perhaps create a new mutex for this. // Comment out this STATLOCK until it's solved. // STATLOCK now done at time of actual read in ow_stats.c read_status = FS_r_local(owq); // this returns status break; default: read_status = FS_r_local(owq); // this returns status } if (read_status >= 0) { // local success -- now format in buffer read_status = OWQ_parse_output(owq); // this returns nr. bytes } } LEVEL_DEBUG("return %d", read_status); return read_status; }
static SIZE_OR_ERROR OWQ_parse_output_ascii(struct one_wire_query *owq) { Debug_OWQ(owq); return OWQ_length(owq); }