xref: /btstack/test/obex/obex_message_builder_test.cpp (revision 98f1394d9d4c33f501ec5dcff54d145a92013c5e)
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