size_t length;
/**
- * Attribute value or segment
+ * Offset up to which attribute value has been processed
+ */
+ size_t offset;
+
+ /**
+ * Current position of attribute value pointer
*/
chunk_t value;
/**
+ * Contains complete attribute or current segment
+ */
+ chunk_t segment;
+
+ /**
* Noskip flag
*/
bool noskip_flag;
/**
+ * Request ID
+ */
+ uint16_t request_id;
+
+ /**
+ * Measurement Length
+ */
+ uint16_t meas_len;
+
+ /**
+ * Number of Files in attribute
+ */
+ uint64_t count;
+
+ /**
* PTS File Measurements
*/
pts_file_meas_t *measurements;
{
bio_writer_t *writer;
enumerator_t *enumerator;
- u_int64_t number_of_files;
+ u_int64_t count;
u_int16_t request_id;
char *filename;
chunk_t measurement;
{
return;
}
- number_of_files = this->measurements->get_file_count(this->measurements);
+ count = this->measurements->get_file_count(this->measurements);
request_id = this->measurements->get_request_id(this->measurements);
writer = bio_writer_create(PTS_FILE_MEAS_SIZE);
- writer->write_uint64(writer, number_of_files);
+ writer->write_uint64(writer, count);
writer->write_uint16(writer, request_id);
enumerator = this->measurements->create_enumerator(this->measurements);
}
this->value = writer->extract_buf(writer);
+ this->segment = this->value;
this->length = this->value.len;
writer->destroy(writer);
}
private_tcg_pts_attr_file_meas_t *this, u_int32_t *offset)
{
bio_reader_t *reader;
- u_int64_t number_of_files;
- u_int16_t request_id, meas_len;
chunk_t measurement, filename;
- size_t len;
+ status_t status = NEED_MORE;
char buf[BUF_LEN];
- status_t status = FAILED;
-
- *offset = 0;
+ size_t len;
- if (this->value.len < this->length)
- {
- return NEED_MORE;
- }
- if (this->value.len < PTS_FILE_MEAS_SIZE)
+ if (this->offset == 0)
{
- DBG1(DBG_TNC, "insufficient data for PTS file measurement header");
- return FAILED;
+ if (this->length < PTS_FILE_MEAS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ return FAILED;
+ }
+ if (this->value.len < PTS_FILE_MEAS_SIZE)
+ {
+ return NEED_MORE;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint64(reader, &this->count);
+ reader->read_uint16(reader, &this->request_id);
+ reader->read_uint16(reader, &this->meas_len);
+ this->offset = PTS_FILE_MEAS_SIZE;
+ this->value = reader->peek(reader);
+ reader->destroy(reader);
}
+ this->measurements = pts_file_meas_create(this->request_id);
reader = bio_reader_create(this->value);
- reader->read_uint64(reader, &number_of_files);
- reader->read_uint16(reader, &request_id);
- reader->read_uint16(reader, &meas_len);
- *offset = PTS_FILE_MEAS_SIZE;
-
- this->measurements = pts_file_meas_create(request_id);
- while (number_of_files--)
+ while (this->count)
{
- if (!reader->read_data(reader, meas_len, &measurement))
+ if (!reader->read_data(reader, this->meas_len, &measurement) ||
+ !reader->read_data16(reader, &filename))
{
- DBG1(DBG_TNC, "insufficient data for PTS file measurement");
goto end;
}
- *offset += meas_len;
-
- if (!reader->read_data16(reader, &filename))
- {
- DBG1(DBG_TNC, "insufficient data for filename");
- goto end;
- }
- *offset += 2 + filename.len;
+ this->offset += this->value.len - reader->remaining(reader);
+ this->value = reader->peek(reader);
len = min(filename.len, BUF_LEN-1);
memcpy(buf, filename.ptr, len);
buf[len] = '\0';
this->measurements->add(this->measurements, buf, measurement);
+ this->count--;
+ }
+
+ if (this->length != this->offset)
+ {
+ DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ status = FAILED;
}
status = SUCCESS;
METHOD(pa_tnc_attr_t, add_segment, void,
private_tcg_pts_attr_file_meas_t *this, chunk_t segment)
{
- this->value = chunk_cat("mc", this->value, segment);
+ this->value = chunk_cat("cc", this->value, segment);
+ chunk_free(&this->segment);
+ this->segment = this->value;
}
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
if (ref_put(&this->ref))
{
DESTROY_IF(this->measurements);
- free(this->value.ptr);
+ free(this->segment.ptr);
free(this);
}
}
.destroy = _destroy,
},
.get_measurements = _get_measurements,
+ .get_count = _get_count,
},
.type = { PEN_TCG, TCG_PTS_FILE_MEAS },
+ .request_id = measurements->get_request_id(measurements),
+ .count = measurements->get_file_count(measurements),
.measurements = measurements,
.ref = 1,
);
},
.type = { PEN_TCG, TCG_PTS_FILE_MEAS },
.length = length,
- .value = chunk_clone(data),
+ .segment = chunk_clone(data),
.ref = 1,
);
+ /* received either complete attribute value or first segment */
+ this->value = this->segment;
+
return &this->public.pa_tnc_attribute;
}