summaryrefslogtreecommitdiffstats
path: root/tinySIGCOMP/src/tcomp_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinySIGCOMP/src/tcomp_message.c')
-rwxr-xr-xtinySIGCOMP/src/tcomp_message.c541
1 files changed, 272 insertions, 269 deletions
diff --git a/tinySIGCOMP/src/tcomp_message.c b/tinySIGCOMP/src/tcomp_message.c
index 6cecb79..2048c3f 100755
--- a/tinySIGCOMP/src/tcomp_message.c
+++ b/tinySIGCOMP/src/tcomp_message.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -54,109 +54,108 @@ static void initStateful(tcomp_message_t *message, uint8_t** start_ptr, uint8_t*
static void initStateless(tcomp_message_t *message, uint8_t** start_ptr, uint8_t* end_ptr, int32_t *nack_code);
static void initNack(tcomp_message_t *message, uint8_t** start_ptr, uint8_t* end_ptr, int32_t* nack_code);
-/*
+/*
Creates new SigComp message.
*/
tcomp_message_t* tcomp_message_create(const void* input_ptr, tsk_size_t input_size, tsk_bool_t stream, int32_t* nack_code)
{
- tcomp_message_t *message;
-
- if(!nack_code){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if(!input_ptr){
- TSK_DEBUG_ERROR("Invalid parameter");
- *nack_code = NACK_INTERNAL_ERROR;
- return tsk_null;
- }
-
- if(input_size < MIN_LEN){
- TSK_DEBUG_ERROR("MESSAGE_TOO_SHORT");
- *nack_code = NACK_MESSAGE_TOO_SHORT;
- return tsk_null;
- }
-
- if((message = tsk_object_new(tcomp_message_def_t))){
- uint8_t *dummy_ptr, *end_ptr;
- uint8_t state_len;
-
- message->startPtr = input_ptr;
- message->stateId = tcomp_buffer_create_null();
- message->remaining_sigcomp_buffer = tcomp_buffer_create_null();
- message->uploaded_UDVM_buffer = tcomp_buffer_create_null();
- message->ret_feedback_buffer= tcomp_buffer_create_null();
-
- message->isNack = 0;
- dummy_ptr = ((uint8_t*)input_ptr);
- end_ptr = (dummy_ptr + input_size);
-
- //
- message->totalSize = input_size;
- message->stream_based = stream;
- message->bytecodes_destination = 0;
-
- /* Get sigcomp header */
- message->headerSigComp = *dummy_ptr;
- dummy_ptr++;
-
- /* Check message validity --> magic code (11111)? */
- message->isOK = HEADER_IS_VALID(message);
- if(!message->isOK){
- TSK_DEBUG_ERROR("SigComp Message not valid (magic code mismatch)");
- *nack_code = NACK_INTERNAL_ERROR;
- goto bail;
- }
-
- /* Feedback item */
- if((HEADER_GET_T(message)!=0)){
- initFeedbackItem(message, &dummy_ptr);
- if(!message->isOK){
- goto bail;
- }
- }
-
- /*
- * If the len field is non-zero, then the SigComp message contains a state identifier
- * to access a state item at the receiving endpoint.
- */
- state_len = HEADER_GET_STATE_LENGTH( HEADER_GET_LEN(message) );
- if(state_len){
- initStateId(message, &dummy_ptr, state_len);
- initStateful(message, &dummy_ptr, end_ptr);
- TSK_DEBUG_INFO("SigComp - Decompressing stateful message with state id =");
- tcomp_buffer_print(message->stateId);
- }
- else
- {
- if( !*dummy_ptr && !(*(dummy_ptr+1)&0xf0) ){
- // "code_len" field of zero --> it's a nack
- initNack(message, &dummy_ptr, end_ptr, nack_code);
- }
- else{
- initStateless(message, &dummy_ptr, end_ptr, nack_code);
- }
- }
-
- /*
- * The fields (RFC 3320 section 7) except for the "remaining SigComp message" are referred to
- * as the "SigComp header" (note that this may include the uploaded UDVM bytecode).
- */
- if(message->isOK){
- message->header_size = ( message->totalSize - tcomp_buffer_getSize(message->remaining_sigcomp_buffer));
- }
- }
- else{
- TSK_DEBUG_ERROR("Failed to create new SigComp message");
- }
+ tcomp_message_t *message;
+
+ if(!nack_code) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ if(!input_ptr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ *nack_code = NACK_INTERNAL_ERROR;
+ return tsk_null;
+ }
+
+ if(input_size < MIN_LEN) {
+ TSK_DEBUG_ERROR("MESSAGE_TOO_SHORT");
+ *nack_code = NACK_MESSAGE_TOO_SHORT;
+ return tsk_null;
+ }
+
+ if((message = tsk_object_new(tcomp_message_def_t))) {
+ uint8_t *dummy_ptr, *end_ptr;
+ uint8_t state_len;
+
+ message->startPtr = input_ptr;
+ message->stateId = tcomp_buffer_create_null();
+ message->remaining_sigcomp_buffer = tcomp_buffer_create_null();
+ message->uploaded_UDVM_buffer = tcomp_buffer_create_null();
+ message->ret_feedback_buffer= tcomp_buffer_create_null();
+
+ message->isNack = 0;
+ dummy_ptr = ((uint8_t*)input_ptr);
+ end_ptr = (dummy_ptr + input_size);
+
+ //
+ message->totalSize = input_size;
+ message->stream_based = stream;
+ message->bytecodes_destination = 0;
+
+ /* Get sigcomp header */
+ message->headerSigComp = *dummy_ptr;
+ dummy_ptr++;
+
+ /* Check message validity --> magic code (11111)? */
+ message->isOK = HEADER_IS_VALID(message);
+ if(!message->isOK) {
+ TSK_DEBUG_ERROR("SigComp Message not valid (magic code mismatch)");
+ *nack_code = NACK_INTERNAL_ERROR;
+ goto bail;
+ }
+
+ /* Feedback item */
+ if((HEADER_GET_T(message)!=0)) {
+ initFeedbackItem(message, &dummy_ptr);
+ if(!message->isOK) {
+ goto bail;
+ }
+ }
+
+ /*
+ * If the len field is non-zero, then the SigComp message contains a state identifier
+ * to access a state item at the receiving endpoint.
+ */
+ state_len = HEADER_GET_STATE_LENGTH( HEADER_GET_LEN(message) );
+ if(state_len) {
+ initStateId(message, &dummy_ptr, state_len);
+ initStateful(message, &dummy_ptr, end_ptr);
+ TSK_DEBUG_INFO("SigComp - Decompressing stateful message with state id =");
+ tcomp_buffer_print(message->stateId);
+ }
+ else {
+ if( !*dummy_ptr && !(*(dummy_ptr+1)&0xf0) ) {
+ // "code_len" field of zero --> it's a nack
+ initNack(message, &dummy_ptr, end_ptr, nack_code);
+ }
+ else {
+ initStateless(message, &dummy_ptr, end_ptr, nack_code);
+ }
+ }
+
+ /*
+ * The fields (RFC 3320 section 7) except for the "remaining SigComp message" are referred to
+ * as the "SigComp header" (note that this may include the uploaded UDVM bytecode).
+ */
+ if(message->isOK) {
+ message->header_size = ( message->totalSize - tcomp_buffer_getSize(message->remaining_sigcomp_buffer));
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create new SigComp message");
+ }
bail:
- if(message && !message->isOK){
- TSK_OBJECT_SAFE_FREE(message);
- }
+ if(message && !message->isOK) {
+ TSK_OBJECT_SAFE_FREE(message);
+ }
- return message;
+ return message;
}
/*
@@ -164,24 +163,24 @@ Iniatizes the feedback item field.
*/
static void initFeedbackItem(tcomp_message_t *message, uint8_t** start_ptr)
{
- /*
+ /*
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
- +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
- | 0 | returned_feedback_field | | 1 | returned_feedback_length |
- +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
+ +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
+ | 0 | returned_feedback_field | | 1 | returned_feedback_length |
+ +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| |
: returned_feedback_field :
| |
+---+---+---+---+---+---+---+---+
- */
- if((**start_ptr) <= 128){
- tcomp_buffer_referenceBuff(message->ret_feedback_buffer, *start_ptr, 1);
- (void)(*start_ptr++);
- }
- else{
- tcomp_buffer_referenceBuff(message->ret_feedback_buffer, *start_ptr, 1+(**start_ptr&0x7f));
- *start_ptr += tcomp_buffer_getSize(message->ret_feedback_buffer);
- }
+ */
+ if((**start_ptr) <= 128) {
+ tcomp_buffer_referenceBuff(message->ret_feedback_buffer, *start_ptr, 1);
+ (void)(*start_ptr++);
+ }
+ else {
+ tcomp_buffer_referenceBuff(message->ret_feedback_buffer, *start_ptr, 1+(**start_ptr&0x7f));
+ *start_ptr += tcomp_buffer_getSize(message->ret_feedback_buffer);
+ }
}
/*
@@ -189,8 +188,8 @@ Initializes the state identifier field.
*/
static void initStateId(tcomp_message_t *message, uint8_t** start_ptr, uint8_t state_len)
{
- tcomp_buffer_referenceBuff(message->stateId, *start_ptr, state_len);
- *start_ptr += state_len;
+ tcomp_buffer_referenceBuff(message->stateId, *start_ptr, state_len);
+ *start_ptr += state_len;
}
/*
@@ -198,94 +197,97 @@ Initializes a stateful SigComp message.
*/
static void initStateful(tcomp_message_t *message, uint8_t** start_ptr, uint8_t* end_ptr)
{
- /*
- +---+---+---+---+---+---+---+---+
- | |
- : partial state identifier :
- | |
- +---+---+---+---+---+---+---+---+
- | |
- : remaining SigComp message :
- | |
- +---+---+---+---+---+---+---+---+
- */
- message->isOK &= (*start_ptr<=end_ptr);
- if(message->isOK){
- tcomp_buffer_referenceBuff(message->remaining_sigcomp_buffer, *start_ptr,
- ((end_ptr-*start_ptr)));
- }
+ /*
+ +---+---+---+---+---+---+---+---+
+ | |
+ : partial state identifier :
+ | |
+ +---+---+---+---+---+---+---+---+
+ | |
+ : remaining SigComp message :
+ | |
+ +---+---+---+---+---+---+---+---+
+ */
+ message->isOK &= (*start_ptr<=end_ptr);
+ if(message->isOK) {
+ tcomp_buffer_referenceBuff(message->remaining_sigcomp_buffer, *start_ptr,
+ ((end_ptr-*start_ptr)));
+ }
}
-
+
/*
Initializes a stateless SigComp message.
*/
static void initStateless(tcomp_message_t *message, uint8_t** start_ptr, uint8_t* end_ptr, int32_t *nack_code)
{
- int has_bytecode = (HEADER_GET_LEN(message) == 0); // No state ==> message contains udvm bytecode
- message->isOK &= has_bytecode;
- if(!message->isOK) return;
-
- /*
- +---+---+---+---+---+---+---+---+
- | code_len |
- +---+---+---+---+---+---+---+---+
- | code_len | destination |
- +---+---+---+---+---+---+---+---+
- | |
- : uploaded UDVM bytecode :
- | |
- +---+---+---+---+---+---+---+---+
- | |
- : remaining SigComp message :
- | |
- +---+---+---+---+---+---+---+---+
- */
- {
- uint32_t code_len1, bytecodes_len;
- uint8_t code_len2, destination, *bytecodes_uploaded_udvm, *remaining_SigComp_message;
-
- uint8_t* dummy_ptr = ((uint8_t*)*start_ptr);
-
- /* Code_len --> 12bits [8+4] */
- code_len1 = *dummy_ptr; dummy_ptr++; /* skip first code_len 8bits */
- code_len2 = (*dummy_ptr) & 0xf0; /* code_len 4 remaining bits */
- destination = (*dummy_ptr) & 0x0f; /* 4bits after code_len */
- dummy_ptr++; /* skip code_len 4bits + destination 4bits ==> 1-byte */
-
- /* Get bytecodes length (12bits) */
- bytecodes_len = ( (code_len1<<4)|(code_len2>>4) );
-
- /* Starting memory address (code destination address). In UDVM. */
- message->bytecodes_destination = HEADER_GET_DEST_VALUE(destination);
- if((message->bytecodes_destination < 128) || (message->bytecodes_destination > 1024)){
- TSK_DEBUG_ERROR("INVALID_CODE_LOCATION");
- *nack_code = NACK_INVALID_CODE_LOCATION;
- message->isOK = 0;
- return;
- }
-
- /* Uploaded UDVM pointer */
- bytecodes_uploaded_udvm = dummy_ptr; /* SigComp header, feedback_item, code_len and destination have been skipped */
-
- /* Skip uploaded udvm */
- dummy_ptr += bytecodes_len;
-
- /* remaining SigComp message */
- remaining_SigComp_message = dummy_ptr;
-
- /* check that remaining sigcomp message is valide */
- if( !(message->isOK &= (remaining_SigComp_message <= end_ptr )) ){
- TSK_DEBUG_ERROR("MESSAGE_TOO_SHORT");
- *nack_code = NACK_MESSAGE_TOO_SHORT;
- return;
- }
-
- //
- // Setting buffers
- //
- tcomp_buffer_referenceBuff(message->uploaded_UDVM_buffer, bytecodes_uploaded_udvm, bytecodes_len);
- tcomp_buffer_referenceBuff(message->remaining_sigcomp_buffer, remaining_SigComp_message, ((end_ptr-remaining_SigComp_message)));
- }
+ int has_bytecode = (HEADER_GET_LEN(message) == 0); // No state ==> message contains udvm bytecode
+ message->isOK &= has_bytecode;
+ if(!message->isOK) {
+ return;
+ }
+
+ /*
+ +---+---+---+---+---+---+---+---+
+ | code_len |
+ +---+---+---+---+---+---+---+---+
+ | code_len | destination |
+ +---+---+---+---+---+---+---+---+
+ | |
+ : uploaded UDVM bytecode :
+ | |
+ +---+---+---+---+---+---+---+---+
+ | |
+ : remaining SigComp message :
+ | |
+ +---+---+---+---+---+---+---+---+
+ */
+ {
+ uint32_t code_len1, bytecodes_len;
+ uint8_t code_len2, destination, *bytecodes_uploaded_udvm, *remaining_SigComp_message;
+
+ uint8_t* dummy_ptr = ((uint8_t*)*start_ptr);
+
+ /* Code_len --> 12bits [8+4] */
+ code_len1 = *dummy_ptr;
+ dummy_ptr++; /* skip first code_len 8bits */
+ code_len2 = (*dummy_ptr) & 0xf0; /* code_len 4 remaining bits */
+ destination = (*dummy_ptr) & 0x0f; /* 4bits after code_len */
+ dummy_ptr++; /* skip code_len 4bits + destination 4bits ==> 1-byte */
+
+ /* Get bytecodes length (12bits) */
+ bytecodes_len = ( (code_len1<<4)|(code_len2>>4) );
+
+ /* Starting memory address (code destination address). In UDVM. */
+ message->bytecodes_destination = HEADER_GET_DEST_VALUE(destination);
+ if((message->bytecodes_destination < 128) || (message->bytecodes_destination > 1024)) {
+ TSK_DEBUG_ERROR("INVALID_CODE_LOCATION");
+ *nack_code = NACK_INVALID_CODE_LOCATION;
+ message->isOK = 0;
+ return;
+ }
+
+ /* Uploaded UDVM pointer */
+ bytecodes_uploaded_udvm = dummy_ptr; /* SigComp header, feedback_item, code_len and destination have been skipped */
+
+ /* Skip uploaded udvm */
+ dummy_ptr += bytecodes_len;
+
+ /* remaining SigComp message */
+ remaining_SigComp_message = dummy_ptr;
+
+ /* check that remaining sigcomp message is valide */
+ if( !(message->isOK &= (remaining_SigComp_message <= end_ptr )) ) {
+ TSK_DEBUG_ERROR("MESSAGE_TOO_SHORT");
+ *nack_code = NACK_MESSAGE_TOO_SHORT;
+ return;
+ }
+
+ //
+ // Setting buffers
+ //
+ tcomp_buffer_referenceBuff(message->uploaded_UDVM_buffer, bytecodes_uploaded_udvm, bytecodes_len);
+ tcomp_buffer_referenceBuff(message->remaining_sigcomp_buffer, remaining_SigComp_message, ((end_ptr-remaining_SigComp_message)));
+ }
}
/*
@@ -293,55 +295,57 @@ Initializes a NACK message as per RFC 4077.
*/
static void initNack(tcomp_message_t *message, uint8_t** start_ptr, uint8_t* end_ptr, int32_t* nack_code)
{
- /*
- +---+---+---+---+---+---+---+---+
- | code_len = 0 |
- +---+---+---+---+---+---+---+---+
- | code_len = 0 | version = 1 |
- +---+---+---+---+---+---+---+---+
- | Reason Code |
- +---+---+---+---+---+---+---+---+
- | OPCODE of failed instruction |
- +---+---+---+---+---+---+---+---+
- | PC of failed instruction |
- | |
- +---+---+---+---+---+---+---+---+
- | |
- : SHA-1 Hash of failed message :
- | |
- +---+---+---+---+---+---+---+---+
- | |
- : Error Details :
- | |
- +---+---+---+---+---+---+---+---+*/
-
- uint8_t* dummy_ptr;
- message->isNack = 1;
- if( (end_ptr - *start_ptr)<25 ){
- *nack_code = NACK_MESSAGE_TOO_SHORT;
- TSK_DEBUG_ERROR("MESSAGE_TOO_SHORT");
- message->isOK = 0;
- return;
- }
-
- dummy_ptr = ((uint8_t*)*start_ptr);
- dummy_ptr++; /* skip first code_len byte */
- if(!(message->isOK = (*dummy_ptr++ == NACK_VERSION))) {
- return;
- }
-
- if(!message->nack_info){
- message->nack_info = tcomp_nackinfo_create();
- }
-
- message->nack_info->reasonCode = *dummy_ptr++;
- message->nack_info->opcode = *dummy_ptr++;
- message->nack_info->pc = TSK_BINARY_GET_2BYTES(dummy_ptr); dummy_ptr+=2;
- memcpy(message->nack_info->sha1, dummy_ptr, TSK_SHA1_DIGEST_SIZE); dummy_ptr += TSK_SHA1_DIGEST_SIZE;
- if(dummy_ptr < end_ptr){
- /* Has error details */
- tcomp_buffer_appendBuff(message->nack_info->details, dummy_ptr, (end_ptr-dummy_ptr));
- }
+ /*
+ +---+---+---+---+---+---+---+---+
+ | code_len = 0 |
+ +---+---+---+---+---+---+---+---+
+ | code_len = 0 | version = 1 |
+ +---+---+---+---+---+---+---+---+
+ | Reason Code |
+ +---+---+---+---+---+---+---+---+
+ | OPCODE of failed instruction |
+ +---+---+---+---+---+---+---+---+
+ | PC of failed instruction |
+ | |
+ +---+---+---+---+---+---+---+---+
+ | |
+ : SHA-1 Hash of failed message :
+ | |
+ +---+---+---+---+---+---+---+---+
+ | |
+ : Error Details :
+ | |
+ +---+---+---+---+---+---+---+---+*/
+
+ uint8_t* dummy_ptr;
+ message->isNack = 1;
+ if( (end_ptr - *start_ptr)<25 ) {
+ *nack_code = NACK_MESSAGE_TOO_SHORT;
+ TSK_DEBUG_ERROR("MESSAGE_TOO_SHORT");
+ message->isOK = 0;
+ return;
+ }
+
+ dummy_ptr = ((uint8_t*)*start_ptr);
+ dummy_ptr++; /* skip first code_len byte */
+ if(!(message->isOK = (*dummy_ptr++ == NACK_VERSION))) {
+ return;
+ }
+
+ if(!message->nack_info) {
+ message->nack_info = tcomp_nackinfo_create();
+ }
+
+ message->nack_info->reasonCode = *dummy_ptr++;
+ message->nack_info->opcode = *dummy_ptr++;
+ message->nack_info->pc = TSK_BINARY_GET_2BYTES(dummy_ptr);
+ dummy_ptr+=2;
+ memcpy(message->nack_info->sha1, dummy_ptr, TSK_SHA1_DIGEST_SIZE);
+ dummy_ptr += TSK_SHA1_DIGEST_SIZE;
+ if(dummy_ptr < end_ptr) {
+ /* Has error details */
+ tcomp_buffer_appendBuff(message->nack_info->details, dummy_ptr, (end_ptr-dummy_ptr));
+ }
}
@@ -354,37 +358,36 @@ static void initNack(tcomp_message_t *message, uint8_t** start_ptr, uint8_t* end
static tsk_object_t* tcomp_message_ctor(tsk_object_t *self, va_list * app)
{
- tcomp_message_t *message = self;
+ tcomp_message_t *message = self;
- if(message){
- }
+ if(message) {
+ }
- return self;
+ return self;
}
static tsk_object_t* tcomp_message_dtor(tsk_object_t *self)
{
- tcomp_message_t *message = self;
-
- if(message){
- TSK_OBJECT_SAFE_FREE(message->stateId);
- TSK_OBJECT_SAFE_FREE(message->remaining_sigcomp_buffer);
- TSK_OBJECT_SAFE_FREE(message->uploaded_UDVM_buffer);
- TSK_OBJECT_SAFE_FREE(message->ret_feedback_buffer);
- TSK_OBJECT_SAFE_FREE(message->nack_info);
- }
- else{
- TSK_DEBUG_WARN("NULL SigComp message.");
- }
-
- return self;
+ tcomp_message_t *message = self;
+
+ if(message) {
+ TSK_OBJECT_SAFE_FREE(message->stateId);
+ TSK_OBJECT_SAFE_FREE(message->remaining_sigcomp_buffer);
+ TSK_OBJECT_SAFE_FREE(message->uploaded_UDVM_buffer);
+ TSK_OBJECT_SAFE_FREE(message->ret_feedback_buffer);
+ TSK_OBJECT_SAFE_FREE(message->nack_info);
+ }
+ else {
+ TSK_DEBUG_WARN("NULL SigComp message.");
+ }
+
+ return self;
}
-static const tsk_object_def_t tcomp_message_def_s =
-{
- sizeof(tcomp_message_t),
- tcomp_message_ctor,
- tcomp_message_dtor,
- tsk_null
+static const tsk_object_def_t tcomp_message_def_s = {
+ sizeof(tcomp_message_t),
+ tcomp_message_ctor,
+ tcomp_message_dtor,
+ tsk_null
};
const tsk_object_def_t* tcomp_message_def_t = &tcomp_message_def_s;
OpenPOWER on IntegriCloud