1 #include "CppUTest/TestHarness.h" 2 #include "CppUTest/CommandLineTestRunner.h" 3 4 #include "btstack_util.h" 5 #include "btstack_debug.h" 6 #include "classic/obex.h" 7 #include "classic/obex_message_builder.h" 8 9 // mock hci_dump.c 10 extern "C" void hci_dump_log(int log_level, const char * format, ...){} 11 12 static const uint8_t service_uuid[] = {0xbb, 0x58, 0x2b, 0x40, 0x42, 0xc, 0x11, 0xdb, 0xb0, 0xde, 0x8, 0x0, 0x20, 0xc, 0x9a, 0x66}; 13 static const uint8_t application_parameters[] = {0x29, 4, 0, 0, 0xFF, 0xFF}; 14 static const char path_element[] = "test"; 15 static const uint8_t flags = 1 << 1; 16 static const uint16_t maximum_obex_packet_length = 0xFFFF; 17 static const uint32_t connection_id = 10; 18 static const uint8_t obex_version_number = OBEX_VERSION; 19 20 21 TEST_GROUP(OBEX_MESSAGE_BUILDER){ 22 uint8_t actual_message[300]; 23 uint16_t actual_message_len; 24 25 void setup(void){ 26 actual_message_len = sizeof(actual_message); 27 memset(actual_message, 0, actual_message_len); 28 } 29 30 void CHECK_EQUAL_ARRAY(const uint8_t * expected, uint8_t * actual, int size){ 31 for (int i=0; i<size; i++){ 32 BYTES_EQUAL(expected[i], actual[i]); 33 } 34 } 35 36 void validate(uint8_t * expected_message, uint16_t expected_len, uint8_t actual_status, uint8_t expected_status){ 37 CHECK_EQUAL(actual_status, expected_status); 38 uint16_t actual_len = big_endian_read_16(actual_message, 1); 39 CHECK_EQUAL(actual_len, expected_len); 40 CHECK_EQUAL_ARRAY(actual_message, expected_message, expected_len); 41 } 42 43 void validate_invalid_parameter(uint8_t * expected_message, uint16_t expected_len, uint8_t actual_status){ 44 validate(expected_message, expected_len, actual_status, ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE); 45 } 46 47 void validate_success(uint8_t * expected_message, uint16_t expected_len, uint8_t actual_status){ 48 validate(expected_message, expected_len, actual_status, ERROR_CODE_SUCCESS); 49 } 50 }; 51 52 TEST(OBEX_MESSAGE_BUILDER, CreateConnect){ 53 uint8_t expected_message[] = {OBEX_OPCODE_CONNECT, 0, 0, obex_version_number, flags, 0, 0}; 54 expected_message[2] = sizeof(expected_message); 55 big_endian_store_16(expected_message, 5, maximum_obex_packet_length); 56 57 uint8_t actual_status = obex_message_builder_request_create_connect(actual_message, actual_message_len, obex_version_number, flags, maximum_obex_packet_length); 58 validate_success(expected_message, expected_message[2], actual_status); 59 } 60 61 TEST(OBEX_MESSAGE_BUILDER, CreateGet){ 62 uint8_t expected_message[] = {OBEX_OPCODE_GET | OBEX_OPCODE_FINAL_BIT_MASK, 0, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0}; 63 expected_message[2] = sizeof(expected_message); 64 big_endian_store_32(expected_message, 4, connection_id); 65 66 uint8_t actual_status = obex_message_builder_request_create_get(actual_message, actual_message_len, connection_id); 67 validate_success(expected_message, expected_message[2], actual_status); 68 } 69 70 TEST(OBEX_MESSAGE_BUILDER, CreateGetInvalidConnectionID){ 71 uint8_t expected_message[] = {OBEX_OPCODE_GET | OBEX_OPCODE_FINAL_BIT_MASK, 0, 0}; 72 expected_message[2] = sizeof(expected_message); 73 74 uint8_t actual_status = obex_message_builder_request_create_get(actual_message, actual_message_len, OBEX_CONNECTION_ID_INVALID); 75 validate_invalid_parameter(expected_message, expected_message[2], actual_status); 76 } 77 78 TEST(OBEX_MESSAGE_BUILDER, CreatePut){ 79 uint8_t expected_message[] = {OBEX_OPCODE_PUT | OBEX_OPCODE_FINAL_BIT_MASK, 0, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0}; 80 expected_message[2] = sizeof(expected_message); 81 big_endian_store_32(expected_message, 4, connection_id); 82 83 uint8_t actual_status = obex_message_builder_request_create_put(actual_message, actual_message_len, connection_id); 84 validate_success(expected_message, expected_message[2], actual_status); 85 } 86 87 TEST(OBEX_MESSAGE_BUILDER, CreateSetPath){ 88 uint8_t expected_message[] = {OBEX_OPCODE_SETPATH, 0, 0, flags, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0}; 89 expected_message[2] = sizeof(expected_message); 90 big_endian_store_32(expected_message, 6, connection_id); 91 92 uint8_t actual_status = obex_message_builder_request_create_set_path(actual_message, actual_message_len, flags, connection_id); 93 validate_success(expected_message, expected_message[2], actual_status); 94 } 95 96 TEST(OBEX_MESSAGE_BUILDER, CreateAbort){ 97 uint8_t expected_message[] = {OBEX_OPCODE_ABORT, 0, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0}; 98 expected_message[2] = sizeof(expected_message); 99 big_endian_store_32(expected_message, 4, connection_id); 100 101 uint8_t actual_status = obex_message_builder_request_create_abort(actual_message, actual_message_len, connection_id); 102 validate_success(expected_message, expected_message[2], actual_status); 103 } 104 105 TEST(OBEX_MESSAGE_BUILDER, CreateDisconnect){ 106 uint8_t expected_message[] = {OBEX_OPCODE_DISCONNECT, 0, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0}; 107 expected_message[2] = sizeof(expected_message); 108 big_endian_store_32(expected_message, 4, connection_id); 109 110 uint8_t actual_status = obex_message_builder_request_create_disconnect(actual_message, actual_message_len, connection_id); 111 validate_success(expected_message, expected_message[2], actual_status); 112 } 113 114 TEST(OBEX_MESSAGE_BUILDER, CreateGetAddHeader){ 115 uint8_t expected_message[] = {OBEX_OPCODE_GET | OBEX_OPCODE_FINAL_BIT_MASK, 0, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0, OBEX_HEADER_SINGLE_RESPONSE_MODE, OBEX_SRM_ENABLE}; 116 expected_message[2] = 8; // only get request 117 big_endian_store_32(expected_message, 4, connection_id); 118 119 uint8_t actual_status = obex_message_builder_request_create_get(actual_message, actual_message_len, connection_id); 120 validate_success(expected_message, expected_message[2], actual_status); 121 122 actual_status = obex_message_builder_header_add_srm_enable(actual_message, actual_message_len); 123 expected_message[2] += 2; 124 validate_success(expected_message, expected_message[2], actual_status); 125 } 126 127 TEST(OBEX_MESSAGE_BUILDER, CreateConnectWithHeaderTarget){ 128 uint8_t expected_message[] = {OBEX_OPCODE_CONNECT, 0, 0, obex_version_number, flags, 0, 0, 129 // service UUID 130 OBEX_HEADER_TARGET, 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 131 }; 132 int header_len = 3 + sizeof(service_uuid); 133 expected_message[2] = 7; 134 big_endian_store_16(expected_message, 5, maximum_obex_packet_length); 135 big_endian_store_16(expected_message, 8, header_len); 136 memcpy(expected_message + 10, service_uuid, sizeof(service_uuid)); 137 138 uint8_t actual_status = obex_message_builder_request_create_connect(actual_message, actual_message_len, obex_version_number, flags, maximum_obex_packet_length); 139 validate_success(expected_message, expected_message[2], actual_status); 140 141 actual_status = obex_message_builder_header_add_target(actual_message, actual_message_len, service_uuid, sizeof(service_uuid)); 142 expected_message[2] += header_len; 143 validate_success(expected_message, expected_message[2], actual_status); 144 } 145 146 TEST(OBEX_MESSAGE_BUILDER, CreateConnectWithHeaderApplicationParameters){ 147 uint8_t expected_message[] = {OBEX_OPCODE_CONNECT, 0, 0, obex_version_number, flags, 0, 0, 148 OBEX_HEADER_APPLICATION_PARAMETERS, 0,0, 0,0,0,0,0,0 149 }; 150 int header_len = 3 + sizeof(application_parameters); 151 expected_message[2] = 7; 152 big_endian_store_16(expected_message, 5, maximum_obex_packet_length); 153 big_endian_store_16(expected_message, 8, header_len); 154 memcpy(expected_message + 10, application_parameters, sizeof(application_parameters)); 155 156 uint8_t actual_status = obex_message_builder_request_create_connect(actual_message, actual_message_len, obex_version_number, flags, maximum_obex_packet_length); 157 validate_success(expected_message, expected_message[2], actual_status); 158 159 actual_status = obex_message_builder_header_add_application_parameters(actual_message, actual_message_len, &application_parameters[0], sizeof(application_parameters)); 160 expected_message[2] += header_len; 161 validate_success(expected_message, expected_message[2], actual_status); 162 } 163 164 TEST(OBEX_MESSAGE_BUILDER, CreateSetPathWithName){ 165 uint8_t expected_message[] = {OBEX_OPCODE_SETPATH, 0, 0, flags, 0, OBEX_HEADER_CONNECTION_ID, 0, 0, 0, 0, OBEX_HEADER_NAME, 0x00, 0x0D, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00}; 166 expected_message[2] = 10; 167 big_endian_store_32(expected_message, 6, connection_id); 168 169 uint8_t actual_status = obex_message_builder_request_create_set_path(actual_message, actual_message_len, flags, connection_id); 170 validate_success(expected_message, expected_message[2], actual_status); 171 172 expected_message[2] += 13; 173 actual_status = obex_message_builder_header_add_name(actual_message, actual_message_len, (const char *) path_element); 174 validate_success(expected_message, expected_message[2], actual_status); 175 } 176 177 int main (int argc, const char * argv[]){ 178 return CommandLineTestRunner::RunAllTests(argc, argv); 179 } 180