diff options
Diffstat (limited to 'tinySIGCOMP/src/tcomp_udvm.instructions.c')
-rwxr-xr-x | tinySIGCOMP/src/tcomp_udvm.instructions.c | 2577 |
1 files changed, 1295 insertions, 1282 deletions
diff --git a/tinySIGCOMP/src/tcomp_udvm.instructions.c b/tinySIGCOMP/src/tcomp_udvm.instructions.c index 64b20b5..61724ee 100755 --- a/tinySIGCOMP/src/tcomp_udvm.instructions.c +++ b/tinySIGCOMP/src/tcomp_udvm.instructions.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. * @@ -68,7 +68,7 @@ return tsk_false; \ }\ TCOMP_UDVM_SET_2BYTES_VAL(position, value);\ - + #define GET_2BYTES_VAL(position, ret_val) \ if(((position) + 1) >= TCOMP_UDVM_GET_SIZE()) \ { \ @@ -82,31 +82,30 @@ /** This structure is used to keep index-value pairs after sorting. */ -typedef struct IndexValuePair_s -{ - uint16_t index; - uint16_t value; +typedef struct IndexValuePair_s { + uint16_t index; + uint16_t value; } IndexValuePair_t; //////////////////////////////////////////////////////////////////////////////////////////////////// -/// @brief Predicate to sort integers in ascending order. +/// @brief Predicate to sort integers in ascending order. /// -/// @param [in,out] a First integer. -/// @param [in,out] b Second integer. +/// @param [in,out] a First integer. +/// @param [in,out] b Second integer. /// -/// @retval Zero if @a a == @a b; negative if @a a < @a b and positive otherwise.. +/// @retval Zero if @a a == @a b; negative if @a a < @a b and positive otherwise.. //////////////////////////////////////////////////////////////////////////////////////////////////// static int SortAscendingPredicate(const void *a, const void *b) { - const IndexValuePair_t *el1 = a; - const IndexValuePair_t *el2 = b; - - /* If values are equal the original ordering of the integers must be preserved - * ==> We cannot use normal comparaison because the ANSI C implementation of qsort could swap values even if they are equal. - */ - return (el2->value == el1->value) ? (el1->index - el2->index) : (el1->value - el2->value); + const IndexValuePair_t *el1 = a; + const IndexValuePair_t *el2 = b; + + /* If values are equal the original ordering of the integers must be preserved + * ==> We cannot use normal comparaison because the ANSI C implementation of qsort could swap values even if they are equal. + */ + return (el2->value == el1->value) ? (el1->index - el2->index) : (el1->value - el2->value); } /** @@ -115,21 +114,21 @@ static int SortAscendingPredicate(const void *a, const void *b) //////////////////////////////////////////////////////////////////////////////////////////////////// /// -/// @brief Predicate to sort integers in descending order. -/// @param [in,out] a First integer. -/// @param [in,out] b Second integer. +/// @brief Predicate to sort integers in descending order. +/// @param [in,out] a First integer. +/// @param [in,out] b Second integer. /// /// @retval Zero if @a a == @a b; negative if @a a > @a b and positive otherwise. //////////////////////////////////////////////////////////////////////////////////////////////////// static int SortDescendingPredicate(const void *a, const void *b) { - const IndexValuePair_t *el1 = a; - const IndexValuePair_t *el2 = b; + const IndexValuePair_t *el1 = a; + const IndexValuePair_t *el2 = b; - /* If values are equal the original ordering of the integers must be preserved. - * ==> We cannot use normal comparaison because the ANSI C implementation of qsort could swap values even if they are equal. - */ - return (el2->value == el1->value) ? (el1->index - el2->index) : (el2->value - el1->value); + /* If values are equal the original ordering of the integers must be preserved. + * ==> We cannot use normal comparaison because the ANSI C implementation of qsort could swap values even if they are equal. + */ + return (el2->value == el1->value) ? (el1->index - el2->index) : (el2->value - el1->value); }; @@ -142,15 +141,15 @@ static int SortDescendingPredicate(const void *a, const void *b) /// cannot successfully decompress the message (e.g., by using the CRC instruction). -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__DECOMPRESSION_FAILURE(tcomp_udvm_t *udvm) { - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_USER_REQUESTED].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_USER_REQUESTED); - return tsk_false; + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_USER_REQUESTED].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_USER_REQUESTED); + return tsk_false; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -158,26 +157,26 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__DECOMPRESSION_FAILURE(tcomp_udvm_t *udvm) /// /// @brief AND ($operand_1, %operand_2) /// Reference: RFC3320 Section 9.1.1 -/// Formula: [operand_1 := operand_1 & operand_2]. +/// Formula: [operand_1 := operand_1 & operand_2]. -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. -/// @param operand_2 The second operand. +/// this operand is overwritten with the result. +/// @param operand_2 The second operand. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__AND(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; + + CONSUME_CYCLES(1); - CONSUME_CYCLES(1); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL( operand_1, (_2bytes & operand_2) ); - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL( operand_1, (_2bytes & operand_2) ); - - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -185,26 +184,26 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__AND(tcomp_udvm_t *udvm, uint32_t operand_1, uin /// /// @brief OR ($operand_1, %operand_2) /// Reference: RFC3320 Section 9.1.1 -/// Formula: [operand_1 := operand_1 | operand_2]. +/// Formula: [operand_1 := operand_1 | operand_2]. -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. -/// @param operand_2 The second operand. +/// this operand is overwritten with the result. +/// @param operand_2 The second operand. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__OR(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL( operand_1, (_2bytes | operand_2) ); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL( operand_1, (_2bytes | operand_2) ); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -214,23 +213,23 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__OR(tcomp_udvm_t *udvm, uint32_t operand_1, uint /// Reference: RFC3320 Section 9.1.1<br> /// Formula: [operand_1 := ~operand_1]. <br> -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. +/// this operand is overwritten with the result. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__NOT(tcomp_udvm_t *udvm, uint32_t operand_1) { - uint16_t _2bytes; + uint16_t _2bytes; - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL( operand_1, ~( _2bytes ) ); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL( operand_1, ~( _2bytes ) ); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -240,27 +239,27 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__NOT(tcomp_udvm_t *udvm, uint32_t operand_1) /// Reference: RFC3320 Section 9.1.1<br> /// Formula: [LSHIFT (m, n) := m * 2^n (modulo 2^16)]. <br> -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. -/// @param operand_2 2-byte value encoded by the operand. +/// this operand is overwritten with the result. +/// @param operand_2 2-byte value encoded by the operand. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__LSHIFT(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - // (m * 2^n) == (m<<n) - // (2^16) === 65536 + // (m * 2^n) == (m<<n) + // (2^16) === 65536 - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL( operand_1, (_2bytes << operand_2) ); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL( operand_1, (_2bytes << operand_2) ); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -270,25 +269,25 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__LSHIFT(tcomp_udvm_t *udvm, uint32_t operand_1, /// Reference: RFC3320 Section 9.1.1<br> /// Formula: [RSHIFT (m, n) := floor(m / 2^n)]. <br> -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -// this operand is overwritten with the result. -/// @param operand_2 2-byte value encoded by the operand. +// this operand is overwritten with the result. +/// @param operand_2 2-byte value encoded by the operand. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__RSHIFT(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; + + CONSUME_CYCLES(1); - CONSUME_CYCLES(1); - - // floor(m / 2^n) == (m>>n) - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL(operand_1, (_2bytes >> operand_2) ); + // floor(m / 2^n) == (m>>n) + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL(operand_1, (_2bytes >> operand_2) ); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -299,23 +298,23 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__RSHIFT(tcomp_udvm_t *udvm, uint32_t operand_1, /// Formula: [ADD (m, n) := m + n (modulo 2^16)]<br> /// /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. -/// @param operand_2 2-byte value encoded by the operand. +/// this operand is overwritten with the result. +/// @param operand_2 2-byte value encoded by the operand. /// /// @retval True if succeed, otherwise return false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__ADD(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; + + CONSUME_CYCLES(1); - CONSUME_CYCLES(1); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL(operand_1, (_2bytes + operand_2) ); - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL(operand_1, (_2bytes + operand_2) ); - - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -325,7 +324,7 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__ADD(tcomp_udvm_t *udvm, uint32_t operand_1, uin /// Reference: RFC3320 Section 9.1.2<br> /// Formula: [SUBTRACT (m, n) := m - n (modulo 2^16)]<br> /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by /// this operand is overwritten with the result. /// @param operand_2 2-byte value encoded by the operand. @@ -334,14 +333,14 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__ADD(tcomp_udvm_t *udvm, uint32_t operand_1, uin //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__SUBTRACT(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL(operand_1, (_2bytes - operand_2) ); - - return tsk_true; + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL(operand_1, (_2bytes - operand_2) ); + + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -351,23 +350,23 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__SUBTRACT(tcomp_udvm_t *udvm, uint32_t operand_1 /// Reference: RFC3320 Section 9.1.2<br> /// Formula: [MULTIPLY (m, n) := m * n (modulo 2^16)]<br> /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. -/// @param operand_2 2-byte value encoded by the operand. +/// this operand is overwritten with the result. +/// @param operand_2 2-byte value encoded by the operand. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__MULTIPLY(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; + + CONSUME_CYCLES(1); - CONSUME_CYCLES(1); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL(operand_1, (_2bytes * operand_2) ); - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL(operand_1, (_2bytes * operand_2) ); - - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -378,29 +377,29 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__MULTIPLY(tcomp_udvm_t *udvm, uint32_t operand_1 /// Formula: [DIVIDE (m, n) := floor(m / n)]<br> /// /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by /// this operand is overwritten with the result. -/// @param operand_2 2-byte value encoded by the operand. Decompression failure occurs if this operand is zero. +/// @param operand_2 2-byte value encoded by the operand. Decompression failure occurs if this operand is zero. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__DIVIDE(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; + uint16_t _2bytes; - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - if(!operand_2){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_DIV_BY_ZERO].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_DIV_BY_ZERO); - return tsk_false; - } + if(!operand_2) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_DIV_BY_ZERO].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_DIV_BY_ZERO); + return tsk_false; + } - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL(operand_1, (_2bytes / operand_2) ); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL(operand_1, (_2bytes / operand_2) ); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -411,28 +410,28 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__DIVIDE(tcomp_udvm_t *udvm, uint32_t operand_1, /// Formula: [REMAINDER (m, n) := m - n * floor(m / n)]<br> /// /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param operand_1 2-byte value encoded by the operand. After the operation is complete, the 2-byte word at the memory address specified by -/// this operand is overwritten with the result. +/// this operand is overwritten with the result. /// @param operand_2 2-byte value encoded by the operand. Decompression failure occurs if this operand is zero. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__REMAINDER(tcomp_udvm_t *udvm, uint32_t operand_1, uint32_t operand_2) { - uint16_t _2bytes; - CONSUME_CYCLES(1); + uint16_t _2bytes; + CONSUME_CYCLES(1); - if(!operand_2){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_DIV_BY_ZERO].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_DIV_BY_ZERO); - return tsk_false; - } + if(!operand_2) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_DIV_BY_ZERO].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_DIV_BY_ZERO); + return tsk_false; + } - GET_2BYTES_VAL(operand_1, _2bytes); - SET_2BYTES_VAL(operand_1, (_2bytes % operand_2) ); + GET_2BYTES_VAL(operand_1, _2bytes); + SET_2BYTES_VAL(operand_1, (_2bytes % operand_2) ); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -443,66 +442,71 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__REMAINDER(tcomp_udvm_t *udvm, uint32_t operand_ /// /// This instruction sort lists of 2-byte words in ascending order. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param start The starting memory address of the block of data to be sorted. -/// @param n Number of lists. -/// @param k Lists length (2-byte words). +/// @param [in,out] udvm The udvm state machine entity. +/// @param start The starting memory address of the block of data to be sorted. +/// @param n Number of lists. +/// @param k Lists length (2-byte words). /// /// @retval True if succeed, otherwise return false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__SORT_ASCENDING(tcomp_udvm_t *udvm, uint32_t start, uint32_t n, uint32_t k) { - tsk_bool_t segfault = tsk_false; - uint16_t* list_temp = tsk_null; - IndexValuePair_t *list1_values = tsk_null; - uint32_t list_index, list_el; - uint32_t j, pos; - - CONSUME_CYCLES(( 1 + k *(CEILLINGLOG2(k) + n) )); /* 1 + k * (ceiling(log2(k)) + n) */ - - if(TCOMP_UDVM_GET_SIZE() <= (tsk_size_t)(start+(n*k*2)) ){ - segfault = tsk_true; - goto __SEGFAULT; - }; - - // - // Create FirstList with key-value pairs - // - list1_values = (IndexValuePair_t*)tsk_calloc(k, sizeof(IndexValuePair_t)); - if(!list1_values) { segfault = tsk_true; goto __SEGFAULT; }; - for(j=0, pos=0; pos<k; j+=2,pos++){ - list1_values[pos].index = pos; - GET_2BYTES_VAL((start+j), list1_values[pos].value); - } - - /* - * Sort Fisrt List Values - */ - qsort(list1_values, k, sizeof(IndexValuePair_t), SortAscendingPredicate); - - /* Sort all lists */ - list_temp = tsk_calloc(k, sizeof(uint32_t)); - if(!list1_values) { segfault = tsk_true; goto __SEGFAULT; }; - for(list_index = 0; list_index < n; list_index++){ - uint16_t* list_start = (uint16_t*)TCOMP_UDVM_GET_BUFFER_AT( start + (list_index*k*2) ); - memcpy(list_temp, list_start, k*2); - for(list_el=0; list_el<k; list_el++){ - list_start[(list_el)] = list_temp[ list1_values[list_el].index ]; - } - } + tsk_bool_t segfault = tsk_false; + uint16_t* list_temp = tsk_null; + IndexValuePair_t *list1_values = tsk_null; + uint32_t list_index, list_el; + uint32_t j, pos; + + CONSUME_CYCLES(( 1 + k *(CEILLINGLOG2(k) + n) )); /* 1 + k * (ceiling(log2(k)) + n) */ + + if(TCOMP_UDVM_GET_SIZE() <= (tsk_size_t)(start+(n*k*2)) ) { + segfault = tsk_true; + goto __SEGFAULT; + }; + + // + // Create FirstList with key-value pairs + // + list1_values = (IndexValuePair_t*)tsk_calloc(k, sizeof(IndexValuePair_t)); + if(!list1_values) { + segfault = tsk_true; + goto __SEGFAULT; + }; + for(j=0, pos=0; pos<k; j+=2,pos++) { + list1_values[pos].index = pos; + GET_2BYTES_VAL((start+j), list1_values[pos].value); + } + + /* + * Sort Fisrt List Values + */ + qsort(list1_values, k, sizeof(IndexValuePair_t), SortAscendingPredicate); + + /* Sort all lists */ + list_temp = tsk_calloc(k, sizeof(uint32_t)); + if(!list1_values) { + segfault = tsk_true; + goto __SEGFAULT; + }; + for(list_index = 0; list_index < n; list_index++) { + uint16_t* list_start = (uint16_t*)TCOMP_UDVM_GET_BUFFER_AT( start + (list_index*k*2) ); + memcpy(list_temp, list_start, k*2); + for(list_el=0; list_el<k; list_el++) { + list_start[(list_el)] = list_temp[ list1_values[list_el].index ]; + } + } __SEGFAULT: - TSK_FREE(list_temp); - TSK_FREE(list1_values); - - if(segfault) - { - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } + TSK_FREE(list_temp); + TSK_FREE(list1_values); + + if(segfault) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -513,61 +517,70 @@ __SEGFAULT: /// /// This instruction sort lists of 2-byte words in descending order. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param start The starting memory address of the block of data to be sorted. -/// @param n Number of lists. -/// @param k Lists length (2-byte words). +/// @param [in,out] udvm The udvm state machine entity. +/// @param start The starting memory address of the block of data to be sorted. +/// @param n Number of lists. +/// @param k Lists length (2-byte words). /// /// @retval True if succeed, otherwise return false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__SORT_DESCENDING(tcomp_udvm_t *udvm, uint32_t start, uint32_t n, uint32_t k) { - tsk_bool_t segfault = tsk_false; - uint16_t* list_temp = tsk_null; - IndexValuePair_t *list1_values = tsk_null; - uint32_t list_index, list_el; - uint32_t j, pos; - - CONSUME_CYCLES(( 1 + k *(CEILLINGLOG2(k) + n) )); // 1 + k * (ceiling(log2(k)) + n) - - if(TCOMP_UDVM_GET_SIZE() <= (tsk_size_t)(start+(n*k*2)) ){ segfault = tsk_true; goto __SEGFAULT; }; - - // - // Create FirstList with key-value pairs. - // - list1_values = (IndexValuePair_t*)tsk_calloc(k, sizeof(IndexValuePair_t)); - if(!list1_values) { segfault = tsk_true; goto __SEGFAULT; }; - for(j=0, pos=0; pos<k; j+=2,pos++){ - list1_values[pos].index = pos; - GET_2BYTES_VAL((start+j), list1_values[pos].value); - } - - // Sort Fisrt List Values. - qsort(list1_values, k, sizeof(IndexValuePair_t), SortDescendingPredicate); - - - // Sort all lists - list_temp = tsk_calloc(k, sizeof(uint16_t)); - if(!list1_values) { segfault = tsk_true; goto __SEGFAULT; }; - for(list_index = 0; list_index < n; list_index++){ - uint16_t* list_start = (uint16_t*)TCOMP_UDVM_GET_BUFFER_AT(start + (list_index*k*2)); - memcpy(list_temp, list_start, k*2); - for(list_el=0; list_el<k; list_el++){ - list_start[(list_el)] = list_temp[ list1_values[list_el].index ]; - } - } + tsk_bool_t segfault = tsk_false; + uint16_t* list_temp = tsk_null; + IndexValuePair_t *list1_values = tsk_null; + uint32_t list_index, list_el; + uint32_t j, pos; + + CONSUME_CYCLES(( 1 + k *(CEILLINGLOG2(k) + n) )); // 1 + k * (ceiling(log2(k)) + n) + + if(TCOMP_UDVM_GET_SIZE() <= (tsk_size_t)(start+(n*k*2)) ) { + segfault = tsk_true; + goto __SEGFAULT; + }; + + // + // Create FirstList with key-value pairs. + // + list1_values = (IndexValuePair_t*)tsk_calloc(k, sizeof(IndexValuePair_t)); + if(!list1_values) { + segfault = tsk_true; + goto __SEGFAULT; + }; + for(j=0, pos=0; pos<k; j+=2,pos++) { + list1_values[pos].index = pos; + GET_2BYTES_VAL((start+j), list1_values[pos].value); + } + + // Sort Fisrt List Values. + qsort(list1_values, k, sizeof(IndexValuePair_t), SortDescendingPredicate); + + + // Sort all lists + list_temp = tsk_calloc(k, sizeof(uint16_t)); + if(!list1_values) { + segfault = tsk_true; + goto __SEGFAULT; + }; + for(list_index = 0; list_index < n; list_index++) { + uint16_t* list_start = (uint16_t*)TCOMP_UDVM_GET_BUFFER_AT(start + (list_index*k*2)); + memcpy(list_temp, list_start, k*2); + for(list_el=0; list_el<k; list_el++) { + list_start[(list_el)] = list_temp[ list1_values[list_el].index ]; + } + } __SEGFAULT: - TSK_FREE(list_temp); - TSK_FREE(list1_values); + TSK_FREE(list_temp); + TSK_FREE(list1_values); - if(segfault){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } + if(segfault) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -577,7 +590,7 @@ __SEGFAULT: /// Reference: RFC3320 Section 9.1.4<br> /// This instruction calculates a 20-byte SHA-1 hash [RFC-3174] over the specified area of UDVM memory. /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param position The starting memory address. /// @param length The length of the byte string over which the SHA-1 hash is calculated. /// @param destination The starting address to which the resulting 20-byte hash will be copied. @@ -586,56 +599,56 @@ __SEGFAULT: //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__SHA_1(tcomp_udvm_t *udvm, uint32_t position, uint32_t length, uint32_t destination) { - tsk_bool_t ok = tsk_false; - tsk_sha1context_t sha; - int32_t err; - uint8_t Message_Digest[TSK_SHA1_DIGEST_SIZE]; - - // only check length - // (destination + length) could be > sizeof(udvm_memory) as copying is done byte by byte and could wrap - if(!length){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - goto bail; - } - - CONSUME_CYCLES(1 + length); - - // The SHA-1 instruction calculates a 20-byte SHA-1 hash [RFC-3174] over the specified area of UDVM memory - if(udvm->tmp_buff.size < length){ - if(!(udvm->tmp_buff.ptr = tsk_realloc(udvm->tmp_buff.ptr, length))){ - udvm->tmp_buff.size = 0; - goto bail; - } - udvm->tmp_buff.size = length; - } - - if(!(ok = tcomp_udvm_bytecopy_from(udvm, udvm->tmp_buff.ptr, position, length))){ - goto bail; - } - - // Compute SHA-1 - if(!(ok = ((err = tsk_sha1reset(&sha)) == 0))){ - TSK_DEBUG_ERROR("%s: %d", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc, err); - tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); - goto bail; - } - if(!(ok = ((err = tsk_sha1input(&sha, udvm->tmp_buff.ptr, length)) == 0))){ - TSK_DEBUG_ERROR("%s : %d", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc, err); - tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); - goto bail; - } - if(!(ok = ((err = tsk_sha1result(&sha, (uint8_t*)Message_Digest)) == 0))){ - TSK_DEBUG_ERROR("%s : %d", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc, ok); - tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); - goto bail; - } - - //Copy sha1 result to udvm memory - ok &= tcomp_udvm_bytecopy_to(udvm, destination, Message_Digest, TSK_SHA1_DIGEST_SIZE); + tsk_bool_t ok = tsk_false; + tsk_sha1context_t sha; + int32_t err; + uint8_t Message_Digest[TSK_SHA1_DIGEST_SIZE]; + + // only check length + // (destination + length) could be > sizeof(udvm_memory) as copying is done byte by byte and could wrap + if(!length) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + goto bail; + } + + CONSUME_CYCLES(1 + length); + + // The SHA-1 instruction calculates a 20-byte SHA-1 hash [RFC-3174] over the specified area of UDVM memory + if(udvm->tmp_buff.size < length) { + if(!(udvm->tmp_buff.ptr = tsk_realloc(udvm->tmp_buff.ptr, length))) { + udvm->tmp_buff.size = 0; + goto bail; + } + udvm->tmp_buff.size = length; + } + + if(!(ok = tcomp_udvm_bytecopy_from(udvm, udvm->tmp_buff.ptr, position, length))) { + goto bail; + } + + // Compute SHA-1 + if(!(ok = ((err = tsk_sha1reset(&sha)) == 0))) { + TSK_DEBUG_ERROR("%s: %d", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc, err); + tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); + goto bail; + } + if(!(ok = ((err = tsk_sha1input(&sha, udvm->tmp_buff.ptr, length)) == 0))) { + TSK_DEBUG_ERROR("%s : %d", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc, err); + tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); + goto bail; + } + if(!(ok = ((err = tsk_sha1result(&sha, (uint8_t*)Message_Digest)) == 0))) { + TSK_DEBUG_ERROR("%s : %d", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc, ok); + tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); + goto bail; + } + + //Copy sha1 result to udvm memory + ok &= tcomp_udvm_bytecopy_to(udvm, destination, Message_Digest, TSK_SHA1_DIGEST_SIZE); bail: - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -646,25 +659,25 @@ bail: /// This instruction sets a 2-byte word to a certain specified value /// As usual, MSBs are stored before LSBs in the UDVM memory. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param address Specifies the starting address of a 2-byte word. -/// @param value Specifies the value to be loaded into this word. +/// @param [in,out] udvm The udvm state machine entity. +/// @param address Specifies the starting address of a 2-byte word. +/// @param value Specifies the value to be loaded into this word. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__LOAD(tcomp_udvm_t *udvm, uint32_t address, uint32_t value) { - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - if( address >= TCOMP_UDVM_GET_SIZE() ){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } + if( address >= TCOMP_UDVM_GET_SIZE() ) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } - SET_2BYTES_VAL(address, value); + SET_2BYTES_VAL(address, value); - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -676,21 +689,21 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__LOAD(tcomp_udvm_t *udvm, uint32_t address, uint /// value_0 through to value_n-1 specify the values to load into these words (in the same order as /// they appear in the instruction). /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param address Starting address of the contiguous 2-byte words. -/// @param n Number of 2-bytes values to load. +/// @param [in,out] udvm The udvm state machine entity. +/// @param address Starting address of the contiguous 2-byte words. +/// @param n Number of 2-bytes values to load. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__MULTILOAD(tcomp_udvm_t *udvm, uint32_t address, uint32_t n) { - uint32_t index, _address; - uint32_t overlap_start = udvm->last_memory_address_of_instruction; - #define overlap_end udvm->executionPointer - uint32_t write_start = address; - uint32_t write_end = (address + (n << 1)); + uint32_t index, _address; + uint32_t overlap_start = udvm->last_memory_address_of_instruction; +#define overlap_end udvm->executionPointer + uint32_t write_start = address; + uint32_t write_end = (address + (n << 1)); - CONSUME_CYCLES(1 + n); + CONSUME_CYCLES(1 + n); #define CHECK_MULTILOAD_OVERWRITTEN(__start, __address, __end) \ if(( (__start) <= (__address) && (__address) <= (__end) ) || ( (__start) <= ((__address) + 1) && ((__address) + 1) <= (__end) )){ \ @@ -699,18 +712,18 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__MULTILOAD(tcomp_udvm_t *udvm, uint32_t address, return tsk_false; \ } - // tcomp_udvm_opget_multitype_param() will move the execPtr => make the test before the for loop - CHECK_MULTILOAD_OVERWRITTEN(overlap_start, address, overlap_end); - CHECK_MULTILOAD_OVERWRITTEN(write_start, udvm->executionPointer, write_end); - - for(index = 0, _address = address; index < n; index++ , _address += 2){ - uint32_t value_n = tcomp_udvm_opget_multitype_param(udvm); - CHECK_MULTILOAD_OVERWRITTEN(overlap_start, _address, overlap_end); - CHECK_MULTILOAD_OVERWRITTEN(write_start, udvm->executionPointer, write_end); - SET_2BYTES_VAL(_address, value_n); - } + // tcomp_udvm_opget_multitype_param() will move the execPtr => make the test before the for loop + CHECK_MULTILOAD_OVERWRITTEN(overlap_start, address, overlap_end); + CHECK_MULTILOAD_OVERWRITTEN(write_start, udvm->executionPointer, write_end); + + for(index = 0, _address = address; index < n; index++ , _address += 2) { + uint32_t value_n = tcomp_udvm_opget_multitype_param(udvm); + CHECK_MULTILOAD_OVERWRITTEN(overlap_start, _address, overlap_end); + CHECK_MULTILOAD_OVERWRITTEN(write_start, udvm->executionPointer, write_end); + SET_2BYTES_VAL(_address, value_n); + } - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -718,41 +731,41 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__MULTILOAD(tcomp_udvm_t *udvm, uint32_t address, /// /// @brief <i>PUSH (%value)</i><br><br> /// Reference: RFC3320 Section 9.2.3<br> -/// This instruction pushes the value specified by its operand on the stack.. +/// This instruction pushes the value specified by its operand on the stack.. /// /// @date 11/27/2009 /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param value 2-byte word to push. +/// @param [in,out] udvm The udvm state machine entity. +/// @param value 2-byte word to push. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__PUSH(tcomp_udvm_t *udvm, int16_t value) { - tsk_bool_t callback = (value>=0); - uint32_t stack_location, stack_fill; - if(!callback){ - value = tcomp_udvm_opget_multitype_param(udvm); - } + tsk_bool_t callback = (value>=0); + uint32_t stack_location, stack_fill; + if(!callback) { + value = tcomp_udvm_opget_multitype_param(udvm); + } - CONSUME_CYCLES(callback ? 0 : 1); + CONSUME_CYCLES(callback ? 0 : 1); - - GET_2BYTES_VAL(TCOMP_UDVM_HEADER_STACK_LOCATION_INDEX, stack_location); - GET_2BYTES_VAL(stack_location, stack_fill); - /* - * copying the value to stack[stack_fill] - * stack[n] = stack_location+2*n+2 - */ - SET_2BYTES_VAL((stack_location+(2*stack_fill)+2), value); + GET_2BYTES_VAL(TCOMP_UDVM_HEADER_STACK_LOCATION_INDEX, stack_location); + GET_2BYTES_VAL(stack_location, stack_fill); - /* increasing stack_fill by 1*/ - SET_2BYTES_VAL(stack_location, (stack_fill+1)); + /* + * copying the value to stack[stack_fill] + * stack[n] = stack_location+2*n+2 + */ + SET_2BYTES_VAL((stack_location+(2*stack_fill)+2), value); - return tsk_true; + /* increasing stack_fill by 1*/ + SET_2BYTES_VAL(stack_location, (stack_fill+1)); + + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -760,57 +773,57 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__PUSH(tcomp_udvm_t *udvm, int16_t value) /// /// @brief <i>POP (%address)</i><br><br> /// Reference: RFC3320 Section 9.2.3<br> -/// This instruction pops a value from the stack and then copies the value to the specified memory address.. +/// This instruction pops a value from the stack and then copies the value to the specified memory address.. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param [in,out] value 2-byte word to pop from the stack. +/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] value 2-byte word to pop from the stack. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__POP(tcomp_udvm_t *udvm, uint32_t* value) { - uint32_t address; - uint32_t stack_location, stack_fill, _value = 0; - - tsk_bool_t callback = (value != 0); - - CONSUME_CYCLES(callback?0:1); - - address = callback ? 0 : tcomp_udvm_opget_multitype_param(udvm); - - GET_2BYTES_VAL(TCOMP_UDVM_HEADER_STACK_LOCATION_INDEX, stack_location); - GET_2BYTES_VAL(stack_location, stack_fill); - - /* - * Decompression failure occurs if stack_fill is - * zero at the commencement of a popping operation. POP and RETURN pop - * values from the stack. - */ - if(stack_fill == 0){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - _value = 0; - goto end; - } - - /* - * "Popping" a value from the stack is an abbreviation for decreasing - * stack_fill by 1, and then using the value stored in stack[stack_fill]. - */ - --stack_fill; - SET_2BYTES_VAL(stack_location, stack_fill); - /* stack[n] = stack_location+2*n+2 */ - GET_2BYTES_VAL((stack_location + (2*stack_fill) + 2), _value); + uint32_t address; + uint32_t stack_location, stack_fill, _value = 0; + + tsk_bool_t callback = (value != 0); + + CONSUME_CYCLES(callback?0:1); + + address = callback ? 0 : tcomp_udvm_opget_multitype_param(udvm); + + GET_2BYTES_VAL(TCOMP_UDVM_HEADER_STACK_LOCATION_INDEX, stack_location); + GET_2BYTES_VAL(stack_location, stack_fill); + + /* + * Decompression failure occurs if stack_fill is + * zero at the commencement of a popping operation. POP and RETURN pop + * values from the stack. + */ + if(stack_fill == 0) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + _value = 0; + goto end; + } + + /* + * "Popping" a value from the stack is an abbreviation for decreasing + * stack_fill by 1, and then using the value stored in stack[stack_fill]. + */ + --stack_fill; + SET_2BYTES_VAL(stack_location, stack_fill); + /* stack[n] = stack_location+2*n+2 */ + GET_2BYTES_VAL((stack_location + (2*stack_fill) + 2), _value); end: - if(callback){ - *value = _value; - } - else{ - SET_2BYTES_VAL(address, _value); - } - - return tsk_true; + if(callback) { + *value = _value; + } + else { + SET_2BYTES_VAL(address, _value); + } + + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -820,32 +833,32 @@ end: /// Reference: RFC3320 Section 9.2.4<br> /// This instruction is used to copy a string of bytes from one part of the UDVM memory to another. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param position Specifies the memory address of the first byte in the string to be copied. -/// @param length Specifies the number of bytes to be copied. -/// @param destination Gives the address to which the first byte in the string will be copied. +/// @param [in,out] udvm The udvm state machine entity. +/// @param position Specifies the memory address of the first byte in the string to be copied. +/// @param length Specifies the number of bytes to be copied. +/// @param destination Gives the address to which the first byte in the string will be copied. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__COPY(tcomp_udvm_t *udvm, uint32_t position, uint32_t length, uint32_t destination) { - tsk_bool_t ok = tsk_true; - - CONSUME_CYCLES(1+length); - - if( (position + length) > (int32_t)TCOMP_UDVM_GET_SIZE() || (destination + length) > (int32_t)TCOMP_UDVM_GET_SIZE() ){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } + tsk_bool_t ok = tsk_true; + + CONSUME_CYCLES(1+length); + + if( (position + length) > (int32_t)TCOMP_UDVM_GET_SIZE() || (destination + length) > (int32_t)TCOMP_UDVM_GET_SIZE() ) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } - /* - * The COPY instruction is used to copy a string of bytes from one part - * of the UDVM memory to another. - */ - ok &= tcomp_udvm_bytecopy_self(udvm, &destination, position, length); + /* + * The COPY instruction is used to copy a string of bytes from one part + * of the UDVM memory to another. + */ + ok &= tcomp_udvm_bytecopy_self(udvm, &destination, position, length); - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -855,30 +868,30 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__COPY(tcomp_udvm_t *udvm, uint32_t position, uin /// Reference: RFC3320 Section 9.2.5<br> /// The COPY-LITERAL instruction behaves as a COPY instruction except /// that after copying is completed, the value of the destination operand -/// is replaced by the address to which the next byte of data would be copied.. +/// is replaced by the address to which the next byte of data would be copied.. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param position Specifies the memory address of the first byte in the string to be copied. -/// @param length Specifies the number of bytes to be copied. -/// @param destination Gives the address to which the first byte in the string will be copied. +/// @param [in,out] udvm The udvm state machine entity. +/// @param position Specifies the memory address of the first byte in the string to be copied. +/// @param length Specifies the number of bytes to be copied. +/// @param destination Gives the address to which the first byte in the string will be copied. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__COPY_LITERAL(tcomp_udvm_t *udvm, uint32_t position, uint32_t length, uint32_t destination) { - tsk_bool_t ok; - uint32_t destination_index; - - CONSUME_CYCLES(1+length); - - GET_2BYTES_VAL(destination, destination_index); - ok = tcomp_udvm_bytecopy_self(udvm, &destination_index, position, length); - if(ok){ - /* set next byte */ - SET_2BYTES_VAL(destination, destination_index); - } - - return ok; + tsk_bool_t ok; + uint32_t destination_index; + + CONSUME_CYCLES(1+length); + + GET_2BYTES_VAL(destination, destination_index); + ok = tcomp_udvm_bytecopy_self(udvm, &destination_index, position, length); + if(ok) { + /* set next byte */ + SET_2BYTES_VAL(destination, destination_index); + } + + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -887,90 +900,90 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__COPY_LITERAL(tcomp_udvm_t *udvm, uint32_t posit /// @brief <i>COPY-OFFSET(%offset, %length, $destination)</i><br><br> /// Reference: RFC3320 Section 9.2.6<br> /// This instruction behaves as a COPY-LITERAL instruction -/// except that an offset operand is given instead of a position operand.. +/// except that an offset operand is given instead of a position operand.. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param offset The offset value. -/// @param length Specifies the number of bytes to be copied. -/// @param destination Gives the address to which the first byte in the string will be copied. +/// @param [in,out] udvm The udvm state machine entity. +/// @param offset The offset value. +/// @param length Specifies the number of bytes to be copied. +/// @param destination Gives the address to which the first byte in the string will be copied. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__COPY_OFFSET(tcomp_udvm_t *udvm, uint32_t offset, uint32_t length, uint32_t destination) { - uint32_t DEST, LEFT, RIGTH; - int32_t position = -1; - uint32_t destination_index; - - int32_t D, T; - int32_t O; - - CONSUME_CYCLES(1+length); - - GET_2BYTES_VAL(destination, DEST); - GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_LEFT_INDEX, LEFT); - GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_RIGHT_INDEX, RIGTH); - - /* - DEST: ses - D: distance between LEFT and DEST - O: offset - T: total size between LEFT and RIGTH - - [***** - case 1: - -----LEFT--------DEST------------RIGTH---- - <-----D----> - <--O-> - <---------------T------------> - ****] - [***** - case 2: - -----LEFT--------DEST------------RIGTH---- - <-----D----> - <--------O--------> - <---------------T------------> - ****] - [***** - case 3: - -------DEST-----LEFT-------------RIGTH---- - ****] - */ - D = (DEST - LEFT); - T = (RIGTH - LEFT); - O = offset; - - if( D>=0 && O<=D ){ - /* case 1: easy case */ - position = (DEST-O); - } - else if( D>=0 && O>D ){ - /* case 2: */ - double PAD = (D + ((ceil(((double)O-(double)D)/(double)T))*T))-O; - position = LEFT+(int32_t)PAD; - } - else if( D<0 ){ - /* case 3: */ - position = DEST-O; - } - - /* Check position */ - if(position<0){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } - - /* EXEC_INST__COPY_LITERAL */ - GET_2BYTES_VAL(destination, destination_index); - if(tcomp_udvm_bytecopy_self(udvm, &destination_index, position, length) == tsk_true){ - SET_2BYTES_VAL(destination, destination_index); - } - else{ - return tsk_false; - } - - return tsk_true; + uint32_t DEST, LEFT, RIGTH; + int32_t position = -1; + uint32_t destination_index; + + int32_t D, T; + int32_t O; + + CONSUME_CYCLES(1+length); + + GET_2BYTES_VAL(destination, DEST); + GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_LEFT_INDEX, LEFT); + GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_RIGHT_INDEX, RIGTH); + + /* + DEST: ses + D: distance between LEFT and DEST + O: offset + T: total size between LEFT and RIGTH + + [***** + case 1: + -----LEFT--------DEST------------RIGTH---- + <-----D----> + <--O-> + <---------------T------------> + ****] + [***** + case 2: + -----LEFT--------DEST------------RIGTH---- + <-----D----> + <--------O--------> + <---------------T------------> + ****] + [***** + case 3: + -------DEST-----LEFT-------------RIGTH---- + ****] + */ + D = (DEST - LEFT); + T = (RIGTH - LEFT); + O = offset; + + if( D>=0 && O<=D ) { + /* case 1: easy case */ + position = (DEST-O); + } + else if( D>=0 && O>D ) { + /* case 2: */ + double PAD = (D + ((ceil(((double)O-(double)D)/(double)T))*T))-O; + position = LEFT+(int32_t)PAD; + } + else if( D<0 ) { + /* case 3: */ + position = DEST-O; + } + + /* Check position */ + if(position<0) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } + + /* EXEC_INST__COPY_LITERAL */ + GET_2BYTES_VAL(destination, destination_index); + if(tcomp_udvm_bytecopy_self(udvm, &destination_index, position, length) == tsk_true) { + SET_2BYTES_VAL(destination, destination_index); + } + else { + return tsk_false; + } + + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -984,46 +997,46 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__COPY_OFFSET(tcomp_udvm_t *udvm, uint32_t offset /// @date 11/27/2009 /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param address The destination address. -/// @param length The number of 1-byte values to set. -/// @param start_value The starting value. -/// @param offset The offset used for computation. +/// @param [in,out] udvm The udvm state machine entity. +/// @param address The destination address. +/// @param length The number of 1-byte values to set. +/// @param start_value The starting value. +/// @param offset The offset used for computation. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__MEMSET(tcomp_udvm_t *udvm, uint32_t address, uint32_t length, uint32_t start_value, uint32_t offset) { - uint8_t* seqs_temp; - uint32_t n; - tsk_bool_t ok; - - CONSUME_CYCLES(1+length); - - /* - * The values Seq[0] to Seq[length - 1] inclusive are each interpreted - * as a single byte, and then concatenated to form a byte string where - * the first byte has value Seq[0], the second byte has value Seq[1] and - * so on up to the last byte which has value Seq[length - 1]. - */ - seqs_temp = tsk_calloc(length, sizeof(uint8_t)); - if(!seqs_temp){ - return tsk_false; - } - - for(n=0; n < length; n++){ - seqs_temp[n] = (start_value + n * offset)%256; - } - /* - * The string is then byte copied into the UDVM memory beginning at the - * memory address specified as an operand to the MEMSET instruction, - * obeying the rules of Section 8.4. - */ - ok = tcomp_udvm_bytecopy_to(udvm, address, seqs_temp, length); - - TSK_FREE(seqs_temp); - - return ok; + uint8_t* seqs_temp; + uint32_t n; + tsk_bool_t ok; + + CONSUME_CYCLES(1+length); + + /* + * The values Seq[0] to Seq[length - 1] inclusive are each interpreted + * as a single byte, and then concatenated to form a byte string where + * the first byte has value Seq[0], the second byte has value Seq[1] and + * so on up to the last byte which has value Seq[length - 1]. + */ + seqs_temp = tsk_calloc(length, sizeof(uint8_t)); + if(!seqs_temp) { + return tsk_false; + } + + for(n=0; n < length; n++) { + seqs_temp[n] = (start_value + n * offset)%256; + } + /* + * The string is then byte copied into the UDVM memory beginning at the + * memory address specified as an operand to the MEMSET instruction, + * obeying the rules of Section 8.4. + */ + ok = tcomp_udvm_bytecopy_to(udvm, address, seqs_temp, length); + + TSK_FREE(seqs_temp); + + return ok; } /** @@ -1032,27 +1045,27 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__MEMSET(tcomp_udvm_t *udvm, uint32_t address, ui * This instruction moves program execution to the specified memory address. * Decompression failure occurs if the value of the address operand lies * beyond the overall UDVM memory size. -* @param [in,out] udvm The udvm state machine entity. +* @param [in,out] udvm The udvm state machine entity. * @param address defines the address to jump to * @retval 1 if succeed, otherwise returns 0 */ tsk_bool_t TCOMP_UDVM_EXEC_INST__JUMP(tcomp_udvm_t *udvm, int16_t address) { - int callback = (address >=0 ); - CONSUME_CYCLES(callback?0:1); + int callback = (address >=0 ); + CONSUME_CYCLES(callback?0:1); - if(!callback){ - address = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction); - } - - if(address > (int32_t)TCOMP_UDVM_GET_SIZE()){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } - udvm->executionPointer = address; + if(!callback) { + address = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction); + } + + if(address > (int32_t)TCOMP_UDVM_GET_SIZE()) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } + udvm->executionPointer = address; - return tsk_true; + return tsk_true; } @@ -1060,45 +1073,45 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__JUMP(tcomp_udvm_t *udvm, int16_t address) * * @brief <i>COMPARE(%value_1, %value_2, \@address_1, \@address_2, \@address_3)</i><br><br> * Reference: RFC3320 Section 9.3.2<br> - * + * * This instruction compares two operands and then jumps to one of three specified * memory addresses depending on the result.<br> * if(value_1 < value_2) --> address_1<br> * elif(value_1 = value_2) --> address_2<br> - * elif(value_1 > value_2) --> address_3. <br> + * elif(value_1 > value_2) --> address_3. <br> * * - * @param [in,out] udvm The udvm state machine entity. - * @param value_1 The first value to compare. - * @param value_2 The second value to compare. - * @param address_1 The address to jump to if (value_1 < value_2). - * @param address_2 The address to jump to if (value_1 = value_2). - * @param address_3 address to jump to if (value_1 > value_2). + * @param [in,out] udvm The udvm state machine entity. + * @param value_1 The first value to compare. + * @param value_2 The second value to compare. + * @param address_1 The address to jump to if (value_1 < value_2). + * @param address_2 The address to jump to if (value_1 = value_2). + * @param address_3 address to jump to if (value_1 > value_2). * @retval 1 if succeed, otherwise returns 0. **/ tsk_bool_t TCOMP_UDVM_EXEC_INST__COMPARE(tcomp_udvm_t *udvm, uint32_t value_1, uint32_t value_2, uint32_t address_1, uint32_t address_2, uint32_t address_3) { - tsk_bool_t ok = 1; + tsk_bool_t ok = 1; - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - if(value_1 < value_2){ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address_1); - goto end; - } + if(value_1 < value_2) { + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address_1); + goto end; + } - if(value_1 == value_2){ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address_2); - goto end; - } + if(value_1 == value_2) { + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address_2); + goto end; + } - if(value_1 > value_2){ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address_3); - goto end; - } + if(value_1 > value_2) { + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address_3); + goto end; + } end: - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1106,21 +1119,21 @@ end: /// /// @brief <i>CALL(\@address)</i><br><br> /// Reference: RFC3320 Section 9.3.3<br> -/// This instruction finds the memory address of the instruction immediately following -/// the CALL instruction and pushes this 2-byte value on the stack, ready for later retrieval. -/// It then continues instruction execution at the memory address specified by the address operand.. +/// This instruction finds the memory address of the instruction immediately following +/// the CALL instruction and pushes this 2-byte value on the stack, ready for later retrieval. +/// It then continues instruction execution at the memory address specified by the address operand.. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param address The next address. +/// @param [in,out] udvm The udvm state machine entity. +/// @param address The next address. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__CALL(tcomp_udvm_t *udvm, uint32_t address) { - CONSUME_CYCLES(1); + CONSUME_CYCLES(1); - return TCOMP_UDVM_EXEC_INST__PUSH(udvm, udvm->executionPointer) - && TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); + return TCOMP_UDVM_EXEC_INST__PUSH(udvm, udvm->executionPointer) + && TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1128,25 +1141,25 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__CALL(tcomp_udvm_t *udvm, uint32_t address) /// /// @brief <i>RETURN</i><br><br> /// Reference: RFC3320 Section 9.3.3<br> -/// This instruction pops a value from the stack and then continues instruction -/// execution at the memory address just popped.. +/// This instruction pops a value from the stack and then continues instruction +/// execution at the memory address just popped.. /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// -/// @retval True if succeed, otherwise return false . +/// @retval True if succeed, otherwise return false . //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__RETURN(tcomp_udvm_t *udvm) { - uint32_t value = 0; - tsk_bool_t ok = tsk_true; + uint32_t value = 0; + tsk_bool_t ok = tsk_true; - CONSUME_CYCLES(1); - - if( (ok = TCOMP_UDVM_EXEC_INST__POP(udvm, &value)) ){ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, value); - } + CONSUME_CYCLES(1); + + if( (ok = TCOMP_UDVM_EXEC_INST__POP(udvm, &value)) ) { + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, value); + } - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1156,40 +1169,40 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__RETURN(tcomp_udvm_t *udvm) /// Reference: RFC3320 Section 9.3.4<br> /// This instruction performs a conditional jump based on the value of one of its operands. /// Decompression failure occurs if j specifies a value of n or more, or -/// if the address lies beyond the overall UDVM memory size.. +/// if the address lies beyond the overall UDVM memory size.. -/// @param [in,out] udvm The udvm state machine entity. -/// @param n The number of possibilities. -/// @param j The possibility. +/// @param [in,out] udvm The udvm state machine entity. +/// @param n The number of possibilities. +/// @param j The possibility. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__SWITCH(tcomp_udvm_t *udvm, uint32_t n, uint32_t j) { - uint32_t next = 0; - tsk_bool_t ok = tsk_true; + uint32_t next = 0; + tsk_bool_t ok = tsk_true; - CONSUME_CYCLES(1+n); + CONSUME_CYCLES(1+n); - /* Decompression failure occurs if j specifies a value of n or more. */ - if(j >= n){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SWITCH_VALUE_TOO_HIGH].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SWITCH_VALUE_TOO_HIGH); - ok = tsk_false; - goto end; - } + /* Decompression failure occurs if j specifies a value of n or more. */ + if(j >= n) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SWITCH_VALUE_TOO_HIGH].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SWITCH_VALUE_TOO_HIGH); + ok = tsk_false; + goto end; + } - do{ - next = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction); - } - while(j--); + do { + next = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction); + } + while(j--); end: - if(ok){ - ok = TCOMP_UDVM_EXEC_INST__JUMP(udvm, next); - } + if(ok) { + ok = TCOMP_UDVM_EXEC_INST__JUMP(udvm, next); + } - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1198,9 +1211,9 @@ end: /// @brief <i>CRC(%value, %position, %length, \@address)</i><br><br> /// Reference: RFC3320 Section 9.3.5<br> /// This instruction verifies a string of bytes using a 2-byte CRC. -/// The CRC value is computed exactly as defined for the 16-bit FCS calculation in [RFC-1662].. +/// The CRC value is computed exactly as defined for the 16-bit FCS calculation in [RFC-1662].. /// -/// @param [in,out] udvm The udvm state machine entity. +/// @param [in,out] udvm The udvm state machine entity. /// @param value Contains the expected integer value of the 2-byte CRC. /// @param position Defines the position of the string of bytes over which the CRC is evaluated. /// @param length Defines the length of the string of bytes over which the CRC is evaluated. @@ -1210,42 +1223,42 @@ end: //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__CRC(tcomp_udvm_t *udvm, uint32_t value, uint32_t position, uint32_t length, uint32_t address) { - uint32_t crc_value; - - CONSUME_CYCLES(1 + length); - - if(udvm->tmp_buff.size < length){ - if(!(udvm->tmp_buff.ptr = tsk_realloc(udvm->tmp_buff.ptr, length))){ - udvm->tmp_buff.size = 0; - tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc); - return tsk_false; - } - udvm->tmp_buff.size = length; - } - - /* copy data */ - if(!tcomp_udvm_bytecopy_from(udvm, udvm->tmp_buff.ptr, position, length)){ - return tsk_false; - } - - /* - * The CRC value is computed exactly as defined for the 16-bit FCS - * calculation in [RFC-1662] - */ - crc_value = tsk_pppfcs16(TSK_PPPINITFCS16, udvm->tmp_buff.ptr, length); - - /* - * If the calculated CRC matches the expected value then the UDVM - * continues instruction execution at the following instruction. - * Otherwise the UDVM jumps to the memory address specified by the - * address operand. - */ - if(value != crc_value){ - TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); - } - - return tsk_true; + uint32_t crc_value; + + CONSUME_CYCLES(1 + length); + + if(udvm->tmp_buff.size < length) { + if(!(udvm->tmp_buff.ptr = tsk_realloc(udvm->tmp_buff.ptr, length))) { + udvm->tmp_buff.size = 0; + tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc); + return tsk_false; + } + udvm->tmp_buff.size = length; + } + + /* copy data */ + if(!tcomp_udvm_bytecopy_from(udvm, udvm->tmp_buff.ptr, position, length)) { + return tsk_false; + } + + /* + * The CRC value is computed exactly as defined for the 16-bit FCS + * calculation in [RFC-1662] + */ + crc_value = tsk_pppfcs16(TSK_PPPINITFCS16, udvm->tmp_buff.ptr, length); + + /* + * If the calculated CRC matches the expected value then the UDVM + * continues instruction execution at the following instruction. + * Otherwise the UDVM jumps to the memory address specified by the + * address operand. + */ + if(value != crc_value) { + TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); + } + + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1253,51 +1266,51 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__CRC(tcomp_udvm_t *udvm, uint32_t value, uint32_ /// /// @brief <i>INPUT-BYTES (%length, %destination, \@address)</i><br><br> /// Reference: RFC3320 Section 9.4.2<br> -/// This instruction requests a certain number of bytes of compressed data from the decompressor dispatcher. +/// This instruction requests a certain number of bytes of compressed data from the decompressor dispatcher. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param length Indicates the requested number of bytes of compressed data. -/// @param destination Specifies the starting memory address to which they should be copied. -/// @param address Defines the address to jump to if the instruction requests data that lies beyond the end of the SigComp message. +/// @param [in,out] udvm The udvm state machine entity. +/// @param length Indicates the requested number of bytes of compressed data. +/// @param destination Specifies the starting memory address to which they should be copied. +/// @param address Defines the address to jump to if the instruction requests data that lies beyond the end of the SigComp message. /// /// @retval True if succeed, otherwise return false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__INPUT_BYTES(tcomp_udvm_t *udvm, uint32_t length, uint32_t destination, uint32_t address) { - tsk_bool_t ok = tsk_true; - const uint8_t* compressedDataAddress; - uint8_t* destinationAddress; - - CONSUME_CYCLES(1+length); - - /* - * If the INPUT-BYTES is encountered after an INPUT-BITS or an INPUT- - * HUFFMAN instruction has been used, and the dispatcher currently holds - * a fraction of a byte, then the fraction MUST be discarded before any - * data is passed to the UDVM. The first byte to be passed is the byte - * immediately following the discarded data. - */ - tcomp_buffer_discardBits(udvm->sigCompMessage->remaining_sigcomp_buffer); - - compressedDataAddress = tcomp_buffer_readBytes(udvm->sigCompMessage->remaining_sigcomp_buffer, length); - destinationAddress = TCOMP_UDVM_GET_BUFFER_AT(destination); - if(compressedDataAddress){ - ok &= tcomp_udvm_bytecopy_to(udvm, destination, compressedDataAddress, length); - if(ok){ - /* FIXME: (8 * n + 1000) * cycles_per_bit */ - udvm->maximum_UDVM_cycles += ((8 * length /*+ 1000*/) * udvm->stateHandler->sigcomp_parameters->cpbValue); - } - } - else{ - /* - * If the instruction requests data that lies beyond the end of the - * SigComp message, no data is returned. Instead the UDVM moves program - * execution to the address specified by the address operand. - */ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); - } - - return ok; + tsk_bool_t ok = tsk_true; + const uint8_t* compressedDataAddress; + uint8_t* destinationAddress; + + CONSUME_CYCLES(1+length); + + /* + * If the INPUT-BYTES is encountered after an INPUT-BITS or an INPUT- + * HUFFMAN instruction has been used, and the dispatcher currently holds + * a fraction of a byte, then the fraction MUST be discarded before any + * data is passed to the UDVM. The first byte to be passed is the byte + * immediately following the discarded data. + */ + tcomp_buffer_discardBits(udvm->sigCompMessage->remaining_sigcomp_buffer); + + compressedDataAddress = tcomp_buffer_readBytes(udvm->sigCompMessage->remaining_sigcomp_buffer, length); + destinationAddress = TCOMP_UDVM_GET_BUFFER_AT(destination); + if(compressedDataAddress) { + ok &= tcomp_udvm_bytecopy_to(udvm, destination, compressedDataAddress, length); + if(ok) { + /* FIXME: (8 * n + 1000) * cycles_per_bit */ + udvm->maximum_UDVM_cycles += ((8 * length /*+ 1000*/) * udvm->stateHandler->sigcomp_parameters->cpbValue); + } + } + else { + /* + * If the instruction requests data that lies beyond the end of the + * SigComp message, no data is returned. Instead the UDVM moves program + * execution to the address specified by the address operand. + */ + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); + } + + return ok; } /** @@ -1308,7 +1321,7 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__INPUT_BYTES(tcomp_udvm_t *udvm, uint32_t length * compressed data from the decompressor dispatcher. * * - * @param [in,out] udvm The udvm state machine entity. + * @param [in,out] udvm The udvm state machine entity. * @param length The length operand indicates the requested number of bits. Decompression failure occurs if this operand does not lie between 0 and 16 inclusive. @@ -1317,109 +1330,109 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__INPUT_BYTES(tcomp_udvm_t *udvm, uint32_t length interpreted as a 2-byte integer ranging from 0 to 2^length - 1, as explained in Section 8.2. - * @param address The address of the destination. + * @param address The address of the destination. * - * @retval 1 if succeed, otherwise returns 0. + * @retval 1 if succeed, otherwise returns 0. **/ tsk_bool_t TCOMP_UDVM_EXEC_INST__INPUT_BITS(tcomp_udvm_t *udvm, uint32_t length, uint32_t destination, uint32_t address) { - tsk_bool_t ok = tsk_true; - uint32_t input_bit_order, reserved; - uint8_t F_BIT, P_BIT; - uint8_t* old_P_BIT; - - /* - The input_bit_order register contains the following three flags: - 0 7 8 15 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | reserved |F|H|P| 68 - 69 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - CONSUME_CYCLES(1); - - GET_2BYTES_VAL(TCOMP_UDVM_HEADER_INPUT_BIT_ORDER_INDEX, input_bit_order); - reserved = (input_bit_order & 0xf8); - /* - * Decompression failure occurs if an INPUT-BITS or an INPUT-HUFFMAN - * instruction is encountered and the input_bit_order register does not - * lie between 0 and 7 inclusive. - */ - if(reserved){ - /* MUST BE ZEROS --> Only 3bits --> [0-7] */ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_BAD_INPUT_BITORDER].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_BAD_INPUT_BITORDER); - return tsk_false; - } - - /* F and P BITS */ - F_BIT = (input_bit_order & 0x0004) ? 1 : 0; - P_BIT = (input_bit_order & 0x0001); - - /* - * Decompression failure occurs if this operand (length) does not lie between 0 - * and 16 inclusive. - */ - if(/*length<0 ||*/ length>16){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_OPERAND].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPERAND); - return tsk_false; - } - - /* - * P:The P-bit controls the order in which bits are passed from the - * dispatcher to the INPUT instructions - * P=0 --> MSB_TO_LSB - * P=1 --> LSB_TO_MSB - */ - old_P_BIT = tcomp_buffer_getP_BIT(udvm->sigCompMessage->remaining_sigcomp_buffer); - if(*old_P_BIT != P_BIT){ - /* - * If the P-bit has changed since the last INPUT instruction, any fraction of a - * byte still held by the dispatcher MUST be discarded (even if the - * INPUT instruction requests zero bits) - */ - tcomp_buffer_discardBits(udvm->sigCompMessage->remaining_sigcomp_buffer); - *old_P_BIT = P_BIT; - } - - /* - * If the instruction requests data that lies beyond the end of the - * SigComp message, no data is returned. Instead the UDVM moves program - * execution to the address specified by the address operand. - */ - if( (length) > tcomp_buffer_getRemainingBits(udvm->sigCompMessage->remaining_sigcomp_buffer) ){ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); - goto end; - } - - /* - * If the F-bit is set to 0, the INPUT-BITS instruction interprets the - * received bits as arriving MSBs first, and if it is set to 1, it interprets the bits as arriving LSBs first. - * F=0 --> MSB_TO_LSB - * F=1 --> LSB_TO_MSB - */ - if(P_BIT == TCOMP_P_BIT_MSB_TO_LSB){ - /* MSB_TO_LSB */ - uint32_t value = tcomp_buffer_readMsbToLsb(udvm->sigCompMessage->remaining_sigcomp_buffer, length); - if(F_BIT == F_BIT_LSB_TO_MSB){ - value = (TSK_BINARY_REVERSE_2BYTE(value)>>(16-length)); - } - SET_2BYTES_VAL(destination, value); - } - else{ - /* LSB_TO_MSB */ - uint32_t value = tcomp_buffer_readLsbToMsb(udvm->sigCompMessage->remaining_sigcomp_buffer, length); - if(F_BIT == F_BIT_LSB_TO_MSB) { - value = (TSK_BINARY_REVERSE_2BYTE(value)>>(16-length)); - } - SET_2BYTES_VAL(destination, value); - } + tsk_bool_t ok = tsk_true; + uint32_t input_bit_order, reserved; + uint8_t F_BIT, P_BIT; + uint8_t* old_P_BIT; + + /* + The input_bit_order register contains the following three flags: + 0 7 8 15 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | reserved |F|H|P| 68 - 69 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + CONSUME_CYCLES(1); + + GET_2BYTES_VAL(TCOMP_UDVM_HEADER_INPUT_BIT_ORDER_INDEX, input_bit_order); + reserved = (input_bit_order & 0xf8); + /* + * Decompression failure occurs if an INPUT-BITS or an INPUT-HUFFMAN + * instruction is encountered and the input_bit_order register does not + * lie between 0 and 7 inclusive. + */ + if(reserved) { + /* MUST BE ZEROS --> Only 3bits --> [0-7] */ + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_BAD_INPUT_BITORDER].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_BAD_INPUT_BITORDER); + return tsk_false; + } + + /* F and P BITS */ + F_BIT = (input_bit_order & 0x0004) ? 1 : 0; + P_BIT = (input_bit_order & 0x0001); + + /* + * Decompression failure occurs if this operand (length) does not lie between 0 + * and 16 inclusive. + */ + if(/*length<0 ||*/ length>16) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_OPERAND].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPERAND); + return tsk_false; + } + + /* + * P:The P-bit controls the order in which bits are passed from the + * dispatcher to the INPUT instructions + * P=0 --> MSB_TO_LSB + * P=1 --> LSB_TO_MSB + */ + old_P_BIT = tcomp_buffer_getP_BIT(udvm->sigCompMessage->remaining_sigcomp_buffer); + if(*old_P_BIT != P_BIT) { + /* + * If the P-bit has changed since the last INPUT instruction, any fraction of a + * byte still held by the dispatcher MUST be discarded (even if the + * INPUT instruction requests zero bits) + */ + tcomp_buffer_discardBits(udvm->sigCompMessage->remaining_sigcomp_buffer); + *old_P_BIT = P_BIT; + } + + /* + * If the instruction requests data that lies beyond the end of the + * SigComp message, no data is returned. Instead the UDVM moves program + * execution to the address specified by the address operand. + */ + if( (length) > tcomp_buffer_getRemainingBits(udvm->sigCompMessage->remaining_sigcomp_buffer) ) { + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); + goto end; + } + + /* + * If the F-bit is set to 0, the INPUT-BITS instruction interprets the + * received bits as arriving MSBs first, and if it is set to 1, it interprets the bits as arriving LSBs first. + * F=0 --> MSB_TO_LSB + * F=1 --> LSB_TO_MSB + */ + if(P_BIT == TCOMP_P_BIT_MSB_TO_LSB) { + /* MSB_TO_LSB */ + uint32_t value = tcomp_buffer_readMsbToLsb(udvm->sigCompMessage->remaining_sigcomp_buffer, length); + if(F_BIT == F_BIT_LSB_TO_MSB) { + value = (TSK_BINARY_REVERSE_2BYTE(value)>>(16-length)); + } + SET_2BYTES_VAL(destination, value); + } + else { + /* LSB_TO_MSB */ + uint32_t value = tcomp_buffer_readLsbToMsb(udvm->sigCompMessage->remaining_sigcomp_buffer, length); + if(F_BIT == F_BIT_LSB_TO_MSB) { + value = (TSK_BINARY_REVERSE_2BYTE(value)>>(16-length)); + } + SET_2BYTES_VAL(destination, value); + } end: - - udvm->maximum_UDVM_cycles += (length * udvm->stateHandler->sigcomp_parameters->cpbValue); - return ok; + + udvm->maximum_UDVM_cycles += (length * udvm->stateHandler->sigcomp_parameters->cpbValue); + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1427,170 +1440,170 @@ end: /// /// @brief <i>INPUT-HUFFMAN(%destination, \@address, \#n, %bits_1, %lower_bound_1, %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n, %upper_bound_n, %uncompressed_n)</i><br><br> /// Reference: RFC3320 Section 9.4.4<br> -/// +/// /// This instruction requests a variable number of bits of compressed data from the decompressor dispatcher. The instruction /// initially requests a small number of bits and compares the result against a certain criterion; if the criterion is not met, then -/// additional bits are requested until the criterion is achieved. +/// additional bits are requested until the criterion is achieved. /// -/// @param [in,out] udvm The udvm state machine entity. -/// @param destination The udvm destination address. -/// @param address Address to jump to if data is requested that lies beyond the end of the SigComp message. -/// @param n Additional sets of operands count. +/// @param [in,out] udvm The udvm state machine entity. +/// @param destination The udvm destination address. +/// @param address Address to jump to if data is requested that lies beyond the end of the SigComp message. +/// @param n Additional sets of operands count. /// -/// @retval True if succeed, otherwise return false. +/// @retval True if succeed, otherwise return false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__INPUT_HUFFMAN(tcomp_udvm_t *udvm, uint32_t destination, uint32_t address, uint32_t n) { - /* - The input_bit_order register contains the following three flags: - 0 7 8 15 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | reserved |F|H|P| 68 - 69 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - tsk_bool_t ok = tsk_true; - uint32_t input_bit_order, reserved; - uint8_t H_BIT, P_BIT, *old_P_BIT; - - uint32_t bits_j, lower_bound_j, upper_bound_j, uncompressed_j; - uint32_t bits_total = 0, k = 0, H, J; - tsk_bool_t criterion_ok = tsk_false; - - CONSUME_CYCLES(1+n); - - /*Note that if n = 0 then the INPUT-HUFFMAN instruction is ignored and - program execution resumes at the following instruction.*/ - if(n == 0){ - //goto end; - return ok; - } - - GET_2BYTES_VAL(TCOMP_UDVM_HEADER_INPUT_BIT_ORDER_INDEX, input_bit_order); - reserved = (input_bit_order & 0xf8); - /* - * Decompression failure occurs if an INPUT-BITS or an INPUT-HUFFMAN - * instruction is encountered and the input_bit_order register does not - * lie between 0 and 7 inclusive. - */ - if(reserved){ - /* MUST BE ZEROS --> Only 3bits --> [0-7] */ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_BAD_INPUT_BITORDER].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_BAD_INPUT_BITORDER); - return tsk_false; - } - - /* H and P */ - H_BIT = (input_bit_order & 0x0002)?1:0; - P_BIT = (input_bit_order & 0x0001); - - /* - * P:The P-bit controls the order in which bits are passed from the - * dispatcher to the INPUT instructions - * P=0 --> MSB_TO_LSB - * P=1 --> LSB_TO_MSB - */ - old_P_BIT = tcomp_buffer_getP_BIT(udvm->sigCompMessage->remaining_sigcomp_buffer); - if( *old_P_BIT != P_BIT ){ - /* - * If the P-bit has changed since the last INPUT instruction, any fraction of a - * byte still held by the dispatcher MUST be discarded (even if the - * INPUT instruction requests zero bits) - */ - tcomp_buffer_discardBits(udvm->sigCompMessage->remaining_sigcomp_buffer); - *old_P_BIT = P_BIT; - } - - /* - * HUFFMAN COMPUTATION - */ - - /* 1. Set j := 1 and set H := 0. */ - for(J = 1, H = 0; J<=n; J++){ - /* - * Request bits_j compressed bits. Interpret the returned bits as an - * integer k from 0 to 2^bits_j - 1, as explained in Section 8.2. - */ - bits_j = tcomp_udvm_opget_multitype_param(udvm); - lower_bound_j = tcomp_udvm_opget_multitype_param(udvm); - upper_bound_j = tcomp_udvm_opget_multitype_param(udvm); - uncompressed_j = tcomp_udvm_opget_multitype_param(udvm); - bits_total += bits_j; - - /*Decompression failure occurs if (bits_1 + ... + bits_n) > 16.*/ - if(bits_total > 16){ - ok = tsk_false; - // FIXME: DECOMPRESSION failure TOO_MANY_BITS_REQUESTED - goto end; - } - - if(criterion_ok){ - continue; - } + /* + The input_bit_order register contains the following three flags: + 0 7 8 15 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | reserved |F|H|P| 68 - 69 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + tsk_bool_t ok = tsk_true; + uint32_t input_bit_order, reserved; + uint8_t H_BIT, P_BIT, *old_P_BIT; + + uint32_t bits_j, lower_bound_j, upper_bound_j, uncompressed_j; + uint32_t bits_total = 0, k = 0, H, J; + tsk_bool_t criterion_ok = tsk_false; + + CONSUME_CYCLES(1+n); + + /*Note that if n = 0 then the INPUT-HUFFMAN instruction is ignored and + program execution resumes at the following instruction.*/ + if(n == 0) { + //goto end; + return ok; + } + + GET_2BYTES_VAL(TCOMP_UDVM_HEADER_INPUT_BIT_ORDER_INDEX, input_bit_order); + reserved = (input_bit_order & 0xf8); + /* + * Decompression failure occurs if an INPUT-BITS or an INPUT-HUFFMAN + * instruction is encountered and the input_bit_order register does not + * lie between 0 and 7 inclusive. + */ + if(reserved) { + /* MUST BE ZEROS --> Only 3bits --> [0-7] */ + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_BAD_INPUT_BITORDER].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_BAD_INPUT_BITORDER); + return tsk_false; + } + + /* H and P */ + H_BIT = (input_bit_order & 0x0002)?1:0; + P_BIT = (input_bit_order & 0x0001); + + /* + * P:The P-bit controls the order in which bits are passed from the + * dispatcher to the INPUT instructions + * P=0 --> MSB_TO_LSB + * P=1 --> LSB_TO_MSB + */ + old_P_BIT = tcomp_buffer_getP_BIT(udvm->sigCompMessage->remaining_sigcomp_buffer); + if( *old_P_BIT != P_BIT ) { + /* + * If the P-bit has changed since the last INPUT instruction, any fraction of a + * byte still held by the dispatcher MUST be discarded (even if the + * INPUT instruction requests zero bits) + */ + tcomp_buffer_discardBits(udvm->sigCompMessage->remaining_sigcomp_buffer); + *old_P_BIT = P_BIT; + } + + /* + * HUFFMAN COMPUTATION + */ + + /* 1. Set j := 1 and set H := 0. */ + for(J = 1, H = 0; J<=n; J++) { + /* + * Request bits_j compressed bits. Interpret the returned bits as an + * integer k from 0 to 2^bits_j - 1, as explained in Section 8.2. + */ + bits_j = tcomp_udvm_opget_multitype_param(udvm); + lower_bound_j = tcomp_udvm_opget_multitype_param(udvm); + upper_bound_j = tcomp_udvm_opget_multitype_param(udvm); + uncompressed_j = tcomp_udvm_opget_multitype_param(udvm); + bits_total += bits_j; + + /*Decompression failure occurs if (bits_1 + ... + bits_n) > 16.*/ + if(bits_total > 16) { + ok = tsk_false; + // FIXME: DECOMPRESSION failure TOO_MANY_BITS_REQUESTED + goto end; + } + + if(criterion_ok) { + continue; + } //==step_4: - /* - * 4.If data is requested that lies beyond the end of the SigComp - * message, terminate the INPUT-HUFFMAN instruction and move program - * execution to the memory address specified by the address operand. - */ - if( (bits_j) > tcomp_buffer_getRemainingBits(udvm->sigCompMessage->remaining_sigcomp_buffer) ){ - ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); - goto end; - } + /* + * 4.If data is requested that lies beyond the end of the SigComp + * message, terminate the INPUT-HUFFMAN instruction and move program + * execution to the memory address specified by the address operand. + */ + if( (bits_j) > tcomp_buffer_getRemainingBits(udvm->sigCompMessage->remaining_sigcomp_buffer) ) { + ok &= TCOMP_UDVM_EXEC_INST__JUMP(udvm, address); + goto end; + } //==step_2: - /* - * 2. Request bits_j compressed bits. Interpret the returned bits as an - * integer k from 0 to 2^bits_j - 1, as explained in Section 8.2. - */ - if(P_BIT == TCOMP_P_BIT_MSB_TO_LSB){ - k = tcomp_buffer_readMsbToLsb(udvm->sigCompMessage->remaining_sigcomp_buffer, bits_j); - if(H_BIT == H_BIT_LSB_TO_MSB) { - k = (TSK_BINARY_REVERSE_2BYTE(k)>>(16-bits_j)); - } - } - else{ - k = tcomp_buffer_readLsbToMsb(udvm->sigCompMessage->remaining_sigcomp_buffer, bits_j); - if(H_BIT == H_BIT_LSB_TO_MSB){ - k = (TSK_BINARY_REVERSE_2BYTE(k)>>(16-bits_j)); - } - } + /* + * 2. Request bits_j compressed bits. Interpret the returned bits as an + * integer k from 0 to 2^bits_j - 1, as explained in Section 8.2. + */ + if(P_BIT == TCOMP_P_BIT_MSB_TO_LSB) { + k = tcomp_buffer_readMsbToLsb(udvm->sigCompMessage->remaining_sigcomp_buffer, bits_j); + if(H_BIT == H_BIT_LSB_TO_MSB) { + k = (TSK_BINARY_REVERSE_2BYTE(k)>>(16-bits_j)); + } + } + else { + k = tcomp_buffer_readLsbToMsb(udvm->sigCompMessage->remaining_sigcomp_buffer, bits_j); + if(H_BIT == H_BIT_LSB_TO_MSB) { + k = (TSK_BINARY_REVERSE_2BYTE(k)>>(16-bits_j)); + } + } //==step_3: - /* 3. Set H := H * 2^bits_j + k */ - H = H * (uint32_t)pow(2.0, bits_j) + k; + /* 3. Set H := H * 2^bits_j + k */ + H = H * (uint32_t)pow(2.0, bits_j) + k; //==step_5: - /* - * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1. - * Then go back to Step 2, unless j > n in which case decompression - * failure occurs. - */ - if( (H < lower_bound_j) || (H > upper_bound_j) ){ - continue; - //goto step_2; - } - else{ - /* - * Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the - * memory address specified by the destination operand. - */ - H = (H + uncompressed_j - lower_bound_j) % 65536; - criterion_ok = 1; - } - } - - if(!criterion_ok){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_HUFFMAN_NO_MATCH].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_HUFFMAN_NO_MATCH); - ok = tsk_false; - goto end; - } - else if(ok){ - SET_2BYTES_VAL(destination, H); - udvm->maximum_UDVM_cycles += (bits_total * udvm->stateHandler->sigcomp_parameters->cpbValue); - } + /* + * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1. + * Then go back to Step 2, unless j > n in which case decompression + * failure occurs. + */ + if( (H < lower_bound_j) || (H > upper_bound_j) ) { + continue; + //goto step_2; + } + else { + /* + * Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the + * memory address specified by the destination operand. + */ + H = (H + uncompressed_j - lower_bound_j) % 65536; + criterion_ok = 1; + } + } + + if(!criterion_ok) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_HUFFMAN_NO_MATCH].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_HUFFMAN_NO_MATCH); + ok = tsk_false; + goto end; + } + else if(ok) { + SET_2BYTES_VAL(destination, H); + udvm->maximum_UDVM_cycles += (bits_total * udvm->stateHandler->sigcomp_parameters->cpbValue); + } end: - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1598,119 +1611,119 @@ end: /// /// @brief <i>STATE-ACCESS(%partial_identifier_start, %partial_identifier_length, %state_begin, %state_length, %state_address, %state_instruction)</i><br><br> /// Reference: RFC3320 Section 9.4.5<br> -/// This instruction retrieves some previously stored state information.. +/// This instruction retrieves some previously stored state information.. -/// @param [in,out] udvm If non-null, the udvm. -/// @param partial_identifier_start Specifies the location of the partial state identifier used to retrieve the state information. -/// @param partial_identifier_length Specifies the length of the partial state identifier used to retrieve the state information. -/// @param state_begin Defines the starting byte to copy from the state_value contained in the returned item of state. -/// @param state_length Defines the number of bytes to copy from the state_value contained in the returned item of state. -/// @param state_address Contains a UDVM memory address. -/// @param state_instruction Next instruction to jump to. +/// @param [in,out] udvm If non-null, the udvm. +/// @param partial_identifier_start Specifies the location of the partial state identifier used to retrieve the state information. +/// @param partial_identifier_length Specifies the length of the partial state identifier used to retrieve the state information. +/// @param state_begin Defines the starting byte to copy from the state_value contained in the returned item of state. +/// @param state_length Defines the number of bytes to copy from the state_value contained in the returned item of state. +/// @param state_address Contains a UDVM memory address. +/// @param state_instruction Next instruction to jump to. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__STATE_ACCESS(tcomp_udvm_t *udvm, uint32_t partial_identifier_start, uint32_t partial_identifier_length, uint32_t state_begin, uint32_t state_length, uint32_t state_address, uint32_t state_instruction) { - tcomp_state_t* lpState = NULL; - tcomp_buffer_handle_t* partial_id; - uint32_t match_count; - - /* - * Decompression failure occurs if partial_identifier_length does not - * lie between 6 and 20 inclusive. - */ - if(partial_identifier_length<6 || partial_identifier_length>20){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_STATE_ID_LENGTH].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_ID_LENGTH); - return tsk_false; - } - /* - * decompression failure will always occur if the state_length operand - * is set to 0 but the state_begin operand is non-zero. - */ - if(!state_length && state_begin){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_STATE_PROBE].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_PROBE); - return tsk_false; - } - - /* - * Find matching state - */ - partial_id = tcomp_buffer_create_null(); - tcomp_buffer_referenceBuff(partial_id, TCOMP_UDVM_GET_BUFFER_AT(partial_identifier_start), partial_identifier_length); - match_count = tcomp_statehandler_findState(udvm->stateHandler, partial_id, &lpState); - - /* - * Decompression failure occurs if no state item matching the partial state identifier can be found, if - * more than one state item matches the partial identifier. - */ - if(!lpState || match_count != 1){ - int32_t nack_code = (match_count > 1) ? NACK_ID_NOT_UNIQUE : NACK_STATE_NOT_FOUND; - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[nack_code].desc); - tcomp_udvm_createNackInfo3(udvm, nack_code, partial_id); - TSK_OBJECT_SAFE_FREE(partial_id); - return tsk_false; - } - else if(partial_identifier_length < lpState->minimum_access_length){ - /* - * Decompression failure occurs if partial_identifier_length is less than the minimum_access_length of - * the matched state item. - */ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_STATE_NOT_FOUND].desc); - tcomp_udvm_createNackInfo3(udvm, NACK_STATE_NOT_FOUND, partial_id); - TSK_OBJECT_SAFE_FREE(partial_id); - return tsk_false; - } - TSK_OBJECT_SAFE_FREE(partial_id); - - /* - * If any of the operands state_address, state_instruction or - * state_length is set to 0 then its value is taken from the returned - * item of state instead. - */ - if(!state_address) { - state_address = lpState->address; - } - if(!state_instruction) { - state_instruction = lpState->instruction; - } - if(!state_length) { - state_length = lpState->length; - } - - CONSUME_CYCLES(1+state_length); - - /* Decompression failure occurs if bytes are copied from beyond the end of the state_value. */ - if((tsk_size_t)(state_begin + state_length) > tcomp_buffer_getSize(lpState->value)){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_STATE_TOO_SHORT].desc); - tcomp_udvm_createNackInfo3(udvm, NACK_STATE_TOO_SHORT, partial_id); - return tsk_false; - } - - /* - * The state_address operand contains a UDVM memory address. The - * requested portion of the state_value is byte copied to this memory - * address using the rules of Section 8.4. - */ - if(tcomp_udvm_bytecopy_to(udvm, state_address, tcomp_buffer_getBufferAtPos(lpState->value, state_begin), state_length) != tsk_true){ - return tsk_false; - } - - /* - * Program execution then resumes at the memory address specified by - * state_instruction, unless this address is 0 in which case program - * execution resumes at the next instruction following the STATE-ACCESS - * instruction. - */ - if(state_instruction){ - if(!TCOMP_UDVM_EXEC_INST__JUMP(udvm, state_instruction)){ - return tsk_false; - } - } - - return tsk_true; + tcomp_state_t* lpState = NULL; + tcomp_buffer_handle_t* partial_id; + uint32_t match_count; + + /* + * Decompression failure occurs if partial_identifier_length does not + * lie between 6 and 20 inclusive. + */ + if(partial_identifier_length<6 || partial_identifier_length>20) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_STATE_ID_LENGTH].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_ID_LENGTH); + return tsk_false; + } + /* + * decompression failure will always occur if the state_length operand + * is set to 0 but the state_begin operand is non-zero. + */ + if(!state_length && state_begin) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_STATE_PROBE].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_PROBE); + return tsk_false; + } + + /* + * Find matching state + */ + partial_id = tcomp_buffer_create_null(); + tcomp_buffer_referenceBuff(partial_id, TCOMP_UDVM_GET_BUFFER_AT(partial_identifier_start), partial_identifier_length); + match_count = tcomp_statehandler_findState(udvm->stateHandler, partial_id, &lpState); + + /* + * Decompression failure occurs if no state item matching the partial state identifier can be found, if + * more than one state item matches the partial identifier. + */ + if(!lpState || match_count != 1) { + int32_t nack_code = (match_count > 1) ? NACK_ID_NOT_UNIQUE : NACK_STATE_NOT_FOUND; + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[nack_code].desc); + tcomp_udvm_createNackInfo3(udvm, nack_code, partial_id); + TSK_OBJECT_SAFE_FREE(partial_id); + return tsk_false; + } + else if(partial_identifier_length < lpState->minimum_access_length) { + /* + * Decompression failure occurs if partial_identifier_length is less than the minimum_access_length of + * the matched state item. + */ + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_STATE_NOT_FOUND].desc); + tcomp_udvm_createNackInfo3(udvm, NACK_STATE_NOT_FOUND, partial_id); + TSK_OBJECT_SAFE_FREE(partial_id); + return tsk_false; + } + TSK_OBJECT_SAFE_FREE(partial_id); + + /* + * If any of the operands state_address, state_instruction or + * state_length is set to 0 then its value is taken from the returned + * item of state instead. + */ + if(!state_address) { + state_address = lpState->address; + } + if(!state_instruction) { + state_instruction = lpState->instruction; + } + if(!state_length) { + state_length = lpState->length; + } + + CONSUME_CYCLES(1+state_length); + + /* Decompression failure occurs if bytes are copied from beyond the end of the state_value. */ + if((tsk_size_t)(state_begin + state_length) > tcomp_buffer_getSize(lpState->value)) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_STATE_TOO_SHORT].desc); + tcomp_udvm_createNackInfo3(udvm, NACK_STATE_TOO_SHORT, partial_id); + return tsk_false; + } + + /* + * The state_address operand contains a UDVM memory address. The + * requested portion of the state_value is byte copied to this memory + * address using the rules of Section 8.4. + */ + if(tcomp_udvm_bytecopy_to(udvm, state_address, tcomp_buffer_getBufferAtPos(lpState->value, state_begin), state_length) != tsk_true) { + return tsk_false; + } + + /* + * Program execution then resumes at the memory address specified by + * state_instruction, unless this address is 0 in which case program + * execution resumes at the next instruction following the STATE-ACCESS + * instruction. + */ + if(state_instruction) { + if(!TCOMP_UDVM_EXEC_INST__JUMP(udvm, state_instruction)) { + return tsk_false; + } + } + + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1718,30 +1731,30 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__STATE_ACCESS(tcomp_udvm_t *udvm, uint32_t parti /// /// @brief <i>STATE-CREATE (%state_length, %state_address, %state_instruction, %minimum_access_length, %state_retention_priority)</i><br><br> /// Reference: RFC3320 Section 9.4.6<br> -/// This instruction requests the creation of a state item at the receiving endpoint.. +/// This instruction requests the creation of a state item at the receiving endpoint.. -/// @param [in,out] udvm If non-null, the udvm. -/// @param state_length Defines the length of the state to create. -/// @param state_address Defines the udvm address of the state to create. -/// @param state_instruction Defines the state instruction. -/// @param minimum_access_length Defines the minimun access length. -/// @param state_retention_priority Defines the state retenion priority. +/// @param [in,out] udvm If non-null, the udvm. +/// @param state_length Defines the length of the state to create. +/// @param state_address Defines the udvm address of the state to create. +/// @param state_instruction Defines the state instruction. +/// @param minimum_access_length Defines the minimun access length. +/// @param state_retention_priority Defines the state retenion priority. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__STATE_CREATE(tcomp_udvm_t *udvm, uint32_t state_length, uint32_t state_address, uint32_t state_instruction, uint32_t minimum_access_length, uint32_t state_retention_priority) { - CONSUME_CYCLES(1 + state_length); - - /* - * Create temporary state? - */ - if(!tcomp_udvm_createTempState(udvm, state_length, state_address, state_instruction, - minimum_access_length, state_retention_priority, 0)){ - return tsk_false; - } + CONSUME_CYCLES(1 + state_length); + + /* + * Create temporary state? + */ + if(!tcomp_udvm_createTempState(udvm, state_length, state_address, state_instruction, + minimum_access_length, state_retention_priority, 0)) { + return tsk_false; + } - return tsk_true; + return tsk_true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1749,86 +1762,86 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__STATE_CREATE(tcomp_udvm_t *udvm, uint32_t state /// /// @brief <i>STATE-FREE(%partial_identifier_start, %partial_identifier_length)</i><br><br> /// Reference: RFC3320 Section 9.4.7<br> -/// This instruction informs the receiving endpoint that the sender no longer wishes to use a particular state item.. +/// This instruction informs the receiving endpoint that the sender no longer wishes to use a particular state item.. -/// @param [in,out] udvm If non-null, the udvm. -/// @param partial_identifier_start Defines the first byte address of partial start identifier. -/// @param partial_identifier_length Defines the partial identifier length. +/// @param [in,out] udvm If non-null, the udvm. +/// @param partial_identifier_start Defines the first byte address of partial start identifier. +/// @param partial_identifier_length Defines the partial identifier length. /// -/// @retval True if succeed, otherwise return false . +/// @retval True if succeed, otherwise return false . //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__STATE_FREE(tcomp_udvm_t *udvm, uint32_t partial_identifier_start, uint32_t partial_identifier_length) { - tcomp_tempstate_to_free_t *lpDesc; - - CONSUME_CYCLES(1); - - /* - * Decompression failure MUST occur if more than four state free - * requests are made before the END-MESSAGE instruction is encountered. - */ - if(tcomp_result_getTempStatesToFreeSize(udvm->lpResult) >=4){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_TOO_MANY_STATE_REQUESTS].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_TOO_MANY_STATE_REQUESTS); - return tsk_false; - } - - /* - * Decompression failure also occurs if partial_identifier_length does - * not lie between 6 and 20 inclusive. - */ - if(partial_identifier_length<6 || partial_identifier_length>20){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_STATE_ID_LENGTH].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_ID_LENGTH); - return tsk_false; - } - - lpDesc = tcomp_tempstate_to_free_create(); - lpDesc->partial_identifier_length = partial_identifier_length; - lpDesc->partial_identifier_start = partial_identifier_start; - tcomp_result_addTempStateToFree(udvm->lpResult, lpDesc); - - /*** Do not ByteCopy data, wait for END_MESSAGE --> see RFC 3320 subclause 9.4.9 **/ - - return tsk_true; + tcomp_tempstate_to_free_t *lpDesc; + + CONSUME_CYCLES(1); + + /* + * Decompression failure MUST occur if more than four state free + * requests are made before the END-MESSAGE instruction is encountered. + */ + if(tcomp_result_getTempStatesToFreeSize(udvm->lpResult) >=4) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_TOO_MANY_STATE_REQUESTS].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_TOO_MANY_STATE_REQUESTS); + return tsk_false; + } + + /* + * Decompression failure also occurs if partial_identifier_length does + * not lie between 6 and 20 inclusive. + */ + if(partial_identifier_length<6 || partial_identifier_length>20) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INVALID_STATE_ID_LENGTH].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_STATE_ID_LENGTH); + return tsk_false; + } + + lpDesc = tcomp_tempstate_to_free_create(); + lpDesc->partial_identifier_length = partial_identifier_length; + lpDesc->partial_identifier_start = partial_identifier_start; + tcomp_result_addTempStateToFree(udvm->lpResult, lpDesc); + + /*** Do not ByteCopy data, wait for END_MESSAGE --> see RFC 3320 subclause 9.4.9 **/ + + return tsk_true; } /** * @brief <i>OUTPUT (%output_start, %output_length)</i><br><br> * Reference: RFC3320 Section 9.4.8<br> * This instruction provides successfully decompressed data to the dispatcher. -* @param [in,out] udvm The udvm state machine entity. +* @param [in,out] udvm The udvm state machine entity. * @param output_start defines the starting memory address of the byte string to be provided to the dispatcher * @param output_length defines the length of the byte string to be provided to the dispatcher * @retval 1 if succeed, otherwise returns 0 */ tsk_bool_t TCOMP_UDVM_EXEC_INST__OUTPUT(tcomp_udvm_t *udvm, uint32_t output_start, uint32_t output_length) { - tsk_bool_t ok; - tsk_size_t *outputbuffer_size; - - CONSUME_CYCLES(1+output_length); - - outputbuffer_size = tcomp_buffer_getIndexBytes(udvm->lpResult->output_buffer); - if( (*outputbuffer_size + output_length) > 65536 ){ - /* - * Decompression failure occurs if the cumulative number of bytes - * provided to the dispatcher exceeds 65536 bytes. - */ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_OUTPUT_OVERFLOW].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_OUTPUT_OVERFLOW); - return tsk_false; - } - - // FIXME: do it once? - if((ok = tcomp_udvm_bytecopy_from(udvm, tcomp_buffer_getBufferAtPos(udvm->lpResult->output_buffer, *outputbuffer_size), output_start, output_length))){ - *outputbuffer_size += output_length; - } + tsk_bool_t ok; + tsk_size_t *outputbuffer_size; + + CONSUME_CYCLES(1+output_length); + + outputbuffer_size = tcomp_buffer_getIndexBytes(udvm->lpResult->output_buffer); + if( (*outputbuffer_size + output_length) > 65536 ) { + /* + * Decompression failure occurs if the cumulative number of bytes + * provided to the dispatcher exceeds 65536 bytes. + */ + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_OUTPUT_OVERFLOW].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_OUTPUT_OVERFLOW); + return tsk_false; + } + + // FIXME: do it once? + if((ok = tcomp_udvm_bytecopy_from(udvm, tcomp_buffer_getBufferAtPos(udvm->lpResult->output_buffer, *outputbuffer_size), output_start, output_length))) { + *outputbuffer_size += output_length; + } #if DEBUG || _DEBUG - //tcomp_buffer_nprint(udvm->lpResult->output_buffer, *outputbuffer_size); + //tcomp_buffer_nprint(udvm->lpResult->output_buffer, *outputbuffer_size); #endif - return ok; + return ok; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1840,171 +1853,171 @@ tsk_bool_t TCOMP_UDVM_EXEC_INST__OUTPUT(tcomp_udvm_t *udvm, uint32_t output_star /// handler together with any supplied feedback data. /// /// @param [in,out] udvm Defines the requested feedback location. -/// @param requested_feedback_location The requested feedback location. +/// @param requested_feedback_location The requested feedback location. /// @param returned_parameters_location Defines the returned parameters location which contains remote party capabilities. /// @param state_length Length of the state to create. /// @param state_address UDVM memory address of the state to create. /// @param state_instruction Defines the state instruction. /// @param minimum_access_length Defines the state's minimum access length. -/// @param state_retention_priority Determines the order in which state will be deleted when the compartment exceeds its allocated state memory. +/// @param state_retention_priority Determines the order in which state will be deleted when the compartment exceeds its allocated state memory. /// -/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. +/// @retval @a tsk_true if succeed, otherwise returns @a tsk_false. //////////////////////////////////////////////////////////////////////////////////////////////////// tsk_bool_t TCOMP_UDVM_EXEC_INST__END_MESSAGE(tcomp_udvm_t *udvm, uint32_t requested_feedback_location, uint32_t returned_parameters_location, uint32_t state_length, uint32_t state_address, uint32_t state_instruction, uint32_t minimum_access_length, uint32_t state_retention_priority) { - tsk_size_t udvm_size; - - CONSUME_CYCLES(1+state_length); - - udvm_size = TCOMP_UDVM_GET_SIZE(); - - /* - * Create temporary state provided by END_MESSAGE? - */ - if(!tcomp_udvm_createTempState(udvm, state_length, state_address, state_instruction, minimum_access_length, state_retention_priority, 1)){ - return tsk_false; - } - - /* - * Byte copy all waiting STATE-FREE/STATE-CREATE/END-MESSAGE states - */ - if(!tcomp_udvm_byteCopy_TempStates(udvm)){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); - return tsk_false; - } - - /* - * Feedback has been requested? - */ - if(requested_feedback_location){ - uint8_t r_f_l; - if(requested_feedback_location >= udvm_size){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } - /* - 0 1 2 3 4 5 6 7 - +---+---+---+---+---+---+---+---+ - | reserved | Q | S | I | requested_feedback_location - +---+---+---+---+---+---+---+---+ - | | - : requested feedback item : if Q = 1 - | | - +---+---+---+---+---+---+---+---+ - */ - r_f_l = *TCOMP_UDVM_GET_BUFFER_AT(requested_feedback_location); - udvm->lpResult->req_feedback->I = (r_f_l & 0x01); - udvm->lpResult->req_feedback->S = (r_f_l & 0x02) ? 1 : 0; - udvm->lpResult->req_feedback->Q = (r_f_l & 0x04) ? 1 : 0; - - requested_feedback_location++; /* skip 1-byte header */ - if(udvm->lpResult->req_feedback->Q){ - /* we have a requested feedback item */ - uint8_t r_f_i = *TCOMP_UDVM_GET_BUFFER_AT(requested_feedback_location); - uint8_t length = 1; /* [1-128] */ - if(r_f_i & 0x80){ - /* case 2 */ - length += (r_f_i & 0x7f); /* seven last bits */ - } - - if(requested_feedback_location >= TCOMP_UDVM_GET_SIZE()){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } - /* copy from udvm */ - // FIXME: use realloc - tcomp_buffer_freeBuff(udvm->lpResult->req_feedback->item); - tcomp_buffer_allocBuff(udvm->lpResult->req_feedback->item, length); - if(!tcomp_udvm_bytecopy_from(udvm, tcomp_buffer_getBuffer(udvm->lpResult->req_feedback->item), requested_feedback_location, length)){ - return tsk_false; - } - } - } - - // - // SigComp parameters have been returned? - // - if(returned_parameters_location){ - uint8_t r_p_l, SigComp_version; - uint32_t index; - tcomp_buffer_handle_t *partial_id; - - /* - 0 1 2 3 4 5 6 7 - +---+---+---+---+---+---+---+---+ - | cpb | dms | sms | returned_parameters_location - +---+---+---+---+---+---+---+---+ - | SigComp_version | - +---+---+---+---+---+---+---+---+ - | length_of_partial_state_ID_1 | - +---+---+---+---+---+---+---+---+ - | | - : partial_state_identifier_1 : - | | - +---+---+---+---+---+---+---+---+ - : : - +---+---+---+---+---+---+---+---+ - | length_of_partial_state_ID_n | - +---+---+---+---+---+---+---+---+ - | | - : partial_state_identifier_n : - | | - +---+---+---+---+---+---+---+---+ - */ - - if(returned_parameters_location >= udvm_size){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } - - /* cpb+dms+sms */ - r_p_l = *TCOMP_UDVM_GET_BUFFER_AT(returned_parameters_location); - returned_parameters_location++; - if(r_p_l){ - tcomp_params_setCpbCode(udvm->lpResult->remote_parameters, ((r_p_l & 0xc0)>>6)); - tcomp_params_setDmsCode(udvm->lpResult->remote_parameters, ((r_p_l & 0x38)>>3)); - tcomp_params_setSmsCode(udvm->lpResult->remote_parameters, (r_p_l & 0x07)); - } - /* sigcomp version */ - SigComp_version = *TCOMP_UDVM_GET_BUFFER_AT(returned_parameters_location); - returned_parameters_location++; - if(SigComp_version){ - udvm->lpResult->remote_parameters->SigComp_version = SigComp_version; - } - /* state items */ - for(index = returned_parameters_location; index <(udvm_size-1); ){ - uint8_t length, *length_ptr = TCOMP_UDVM_GET_BUFFER_AT(index); - if(!length_ptr){ - return tsk_false; - } - length = *length_ptr; // 1-byte - if(length<6 || length>20){ - break; - } - index++; - if((index+length) >= (uint32_t)udvm_size){ - TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); - tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); - return tsk_false; - } - partial_id = tcomp_buffer_create_null(); - tcomp_buffer_allocBuff(partial_id, length); - if(!tcomp_udvm_bytecopy_from(udvm, tcomp_buffer_getBuffer(partial_id), index, length)){ - return tsk_false; - } - if(!udvm->lpResult->remote_parameters->returnedStates){ - udvm->lpResult->remote_parameters->returnedStates = tsk_list_create(); - } - tsk_list_push_back_data(udvm->lpResult->remote_parameters->returnedStates, (void**)&partial_id); - index += length; - } - } - - return tsk_true; + tsk_size_t udvm_size; + + CONSUME_CYCLES(1+state_length); + + udvm_size = TCOMP_UDVM_GET_SIZE(); + + /* + * Create temporary state provided by END_MESSAGE? + */ + if(!tcomp_udvm_createTempState(udvm, state_length, state_address, state_instruction, minimum_access_length, state_retention_priority, 1)) { + return tsk_false; + } + + /* + * Byte copy all waiting STATE-FREE/STATE-CREATE/END-MESSAGE states + */ + if(!tcomp_udvm_byteCopy_TempStates(udvm)) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_INTERNAL_ERROR].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_INTERNAL_ERROR); + return tsk_false; + } + + /* + * Feedback has been requested? + */ + if(requested_feedback_location) { + uint8_t r_f_l; + if(requested_feedback_location >= udvm_size) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } + /* + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | reserved | Q | S | I | requested_feedback_location + +---+---+---+---+---+---+---+---+ + | | + : requested feedback item : if Q = 1 + | | + +---+---+---+---+---+---+---+---+ + */ + r_f_l = *TCOMP_UDVM_GET_BUFFER_AT(requested_feedback_location); + udvm->lpResult->req_feedback->I = (r_f_l & 0x01); + udvm->lpResult->req_feedback->S = (r_f_l & 0x02) ? 1 : 0; + udvm->lpResult->req_feedback->Q = (r_f_l & 0x04) ? 1 : 0; + + requested_feedback_location++; /* skip 1-byte header */ + if(udvm->lpResult->req_feedback->Q) { + /* we have a requested feedback item */ + uint8_t r_f_i = *TCOMP_UDVM_GET_BUFFER_AT(requested_feedback_location); + uint8_t length = 1; /* [1-128] */ + if(r_f_i & 0x80) { + /* case 2 */ + length += (r_f_i & 0x7f); /* seven last bits */ + } + + if(requested_feedback_location >= TCOMP_UDVM_GET_SIZE()) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } + /* copy from udvm */ + // FIXME: use realloc + tcomp_buffer_freeBuff(udvm->lpResult->req_feedback->item); + tcomp_buffer_allocBuff(udvm->lpResult->req_feedback->item, length); + if(!tcomp_udvm_bytecopy_from(udvm, tcomp_buffer_getBuffer(udvm->lpResult->req_feedback->item), requested_feedback_location, length)) { + return tsk_false; + } + } + } + + // + // SigComp parameters have been returned? + // + if(returned_parameters_location) { + uint8_t r_p_l, SigComp_version; + uint32_t index; + tcomp_buffer_handle_t *partial_id; + + /* + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | cpb | dms | sms | returned_parameters_location + +---+---+---+---+---+---+---+---+ + | SigComp_version | + +---+---+---+---+---+---+---+---+ + | length_of_partial_state_ID_1 | + +---+---+---+---+---+---+---+---+ + | | + : partial_state_identifier_1 : + | | + +---+---+---+---+---+---+---+---+ + : : + +---+---+---+---+---+---+---+---+ + | length_of_partial_state_ID_n | + +---+---+---+---+---+---+---+---+ + | | + : partial_state_identifier_n : + | | + +---+---+---+---+---+---+---+---+ + */ + + if(returned_parameters_location >= udvm_size) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } + + /* cpb+dms+sms */ + r_p_l = *TCOMP_UDVM_GET_BUFFER_AT(returned_parameters_location); + returned_parameters_location++; + if(r_p_l) { + tcomp_params_setCpbCode(udvm->lpResult->remote_parameters, ((r_p_l & 0xc0)>>6)); + tcomp_params_setDmsCode(udvm->lpResult->remote_parameters, ((r_p_l & 0x38)>>3)); + tcomp_params_setSmsCode(udvm->lpResult->remote_parameters, (r_p_l & 0x07)); + } + /* sigcomp version */ + SigComp_version = *TCOMP_UDVM_GET_BUFFER_AT(returned_parameters_location); + returned_parameters_location++; + if(SigComp_version) { + udvm->lpResult->remote_parameters->SigComp_version = SigComp_version; + } + /* state items */ + for(index = returned_parameters_location; index <(udvm_size-1); ) { + uint8_t length, *length_ptr = TCOMP_UDVM_GET_BUFFER_AT(index); + if(!length_ptr) { + return tsk_false; + } + length = *length_ptr; // 1-byte + if(length<6 || length>20) { + break; + } + index++; + if((index+length) >= (uint32_t)udvm_size) { + TSK_DEBUG_ERROR("%s", TCOMP_NACK_DESCRIPTIONS[NACK_SEGFAULT].desc); + tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT); + return tsk_false; + } + partial_id = tcomp_buffer_create_null(); + tcomp_buffer_allocBuff(partial_id, length); + if(!tcomp_udvm_bytecopy_from(udvm, tcomp_buffer_getBuffer(partial_id), index, length)) { + return tsk_false; + } + if(!udvm->lpResult->remote_parameters->returnedStates) { + udvm->lpResult->remote_parameters->returnedStates = tsk_list_create(); + } + tsk_list_push_back_data(udvm->lpResult->remote_parameters->returnedStates, (void**)&partial_id); + index += length; + } + } + + return tsk_true; } |