1*ac9a0d84SMatthias Ringwald #include "CppUTest/TestHarness.h" 2*ac9a0d84SMatthias Ringwald #include "CppUTest/CommandLineTestRunner.h" 3*ac9a0d84SMatthias Ringwald #include "CppUTestExt/MockSupport.h" 4*ac9a0d84SMatthias Ringwald 5*ac9a0d84SMatthias Ringwald #include "classic/obex.h" 6*ac9a0d84SMatthias Ringwald #include "classic/obex_parser.h" 7*ac9a0d84SMatthias Ringwald #include "classic/obex_message_builder.h" 8*ac9a0d84SMatthias Ringwald #include "btstack_util.h" 9*ac9a0d84SMatthias Ringwald 10*ac9a0d84SMatthias Ringwald static const uint8_t flags = 1 << 1; 11*ac9a0d84SMatthias Ringwald static const uint16_t maximum_obex_packet_length = 0xFFFF; 12*ac9a0d84SMatthias Ringwald static const uint8_t obex_version_number = OBEX_VERSION; 13*ac9a0d84SMatthias Ringwald static const uint8_t target[] = { 1, 2, 3, 4}; 14*ac9a0d84SMatthias Ringwald 15*ac9a0d84SMatthias Ringwald // from parser_callback 16*ac9a0d84SMatthias Ringwald static uint8_t test_header_id; 17*ac9a0d84SMatthias Ringwald static uint8_t test_header_buffer[100]; 18*ac9a0d84SMatthias Ringwald static uint16_t test_header_len; 19*ac9a0d84SMatthias Ringwald 20*ac9a0d84SMatthias Ringwald // mock hci_dump.c 21*ac9a0d84SMatthias Ringwald extern "C" void hci_dump_log(int log_level, const char * format, ...){} 22*ac9a0d84SMatthias Ringwald 23*ac9a0d84SMatthias Ringwald static void parser_callback(void * user_data, uint8_t header_id, uint16_t total_len, uint16_t data_offset, const uint8_t * data_buffer, uint16_t data_len){ 24*ac9a0d84SMatthias Ringwald if (obex_parser_header_store(test_header_buffer, sizeof(test_header_buffer), total_len, data_offset, data_buffer, data_len) == OBEX_PARSER_HEADER_COMPLETE){ 25*ac9a0d84SMatthias Ringwald test_header_len = total_len; 26*ac9a0d84SMatthias Ringwald test_header_id = header_id; 27*ac9a0d84SMatthias Ringwald } 28*ac9a0d84SMatthias Ringwald } 29*ac9a0d84SMatthias Ringwald 30*ac9a0d84SMatthias Ringwald TEST_GROUP(OBEX_PARSER){ 31*ac9a0d84SMatthias Ringwald obex_parser_t parser; 32*ac9a0d84SMatthias Ringwald uint8_t message[300]; 33*ac9a0d84SMatthias Ringwald 34*ac9a0d84SMatthias Ringwald void setup(void){ 35*ac9a0d84SMatthias Ringwald test_header_id = 0; 36*ac9a0d84SMatthias Ringwald test_header_len = 0; 37*ac9a0d84SMatthias Ringwald } 38*ac9a0d84SMatthias Ringwald void teardown(void){ 39*ac9a0d84SMatthias Ringwald } 40*ac9a0d84SMatthias Ringwald void parse_request(void){ 41*ac9a0d84SMatthias Ringwald obex_parser_init_for_request(&parser, &parser_callback, NULL); 42*ac9a0d84SMatthias Ringwald uint16_t message_len = big_endian_read_16(message, 1); 43*ac9a0d84SMatthias Ringwald for (uint16_t i = 0; i < message_len - 1;i++){ 44*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[i], 1); 45*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_INCOMPLETE, parser_state); 46*ac9a0d84SMatthias Ringwald } 47*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[message_len-1], 1); 48*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_COMPLETE, parser_state); 49*ac9a0d84SMatthias Ringwald } 50*ac9a0d84SMatthias Ringwald void parse_response(uint8_t opcode){ 51*ac9a0d84SMatthias Ringwald obex_parser_init_for_response(&parser, opcode, &parser_callback, NULL); 52*ac9a0d84SMatthias Ringwald uint16_t message_len = big_endian_read_16(message, 1); 53*ac9a0d84SMatthias Ringwald for (uint16_t i = 0; i < message_len - 1;i++){ 54*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[i], 1); 55*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_INCOMPLETE, parser_state); 56*ac9a0d84SMatthias Ringwald } 57*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[message_len-1], 1); 58*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_COMPLETE, parser_state); 59*ac9a0d84SMatthias Ringwald } 60*ac9a0d84SMatthias Ringwald }; 61*ac9a0d84SMatthias Ringwald 62*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, RequestOverrun){ 63*ac9a0d84SMatthias Ringwald (void) obex_message_builder_request_create_connect(message, sizeof(message), obex_version_number, flags, maximum_obex_packet_length); 64*ac9a0d84SMatthias Ringwald uint16_t message_len = big_endian_read_16(message, 1); 65*ac9a0d84SMatthias Ringwald for (uint16_t i = 0; i < message_len - 1;i++){ 66*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[i], 1); 67*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_INCOMPLETE, parser_state); 68*ac9a0d84SMatthias Ringwald } 69*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[message_len-1], 1); 70*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_COMPLETE, parser_state); 71*ac9a0d84SMatthias Ringwald parser_state = obex_parser_process_data(&parser, &message[message_len], 1); 72*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_OVERRUN, parser_state); 73*ac9a0d84SMatthias Ringwald } 74*ac9a0d84SMatthias Ringwald 75*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, RequestInvalid){ 76*ac9a0d84SMatthias Ringwald (void) obex_message_builder_request_create_connect(message, sizeof(message), obex_version_number, flags, maximum_obex_packet_length); 77*ac9a0d84SMatthias Ringwald // decrease packet len 78*ac9a0d84SMatthias Ringwald uint16_t message_len = big_endian_read_16(message, 1) - 1; 79*ac9a0d84SMatthias Ringwald big_endian_store_16(message, 1, message_len); 80*ac9a0d84SMatthias Ringwald for (uint16_t i = 0; i < message_len;i++){ 81*ac9a0d84SMatthias Ringwald obex_parser_object_state_t parser_state = obex_parser_process_data(&parser, &message[i], 1); 82*ac9a0d84SMatthias Ringwald if (i < 2){ 83*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_INCOMPLETE, parser_state); 84*ac9a0d84SMatthias Ringwald } else { 85*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_PARSER_OBJECT_STATE_INVALID, parser_state); 86*ac9a0d84SMatthias Ringwald } 87*ac9a0d84SMatthias Ringwald } 88*ac9a0d84SMatthias Ringwald } 89*ac9a0d84SMatthias Ringwald 90*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, ConnectRequest){ 91*ac9a0d84SMatthias Ringwald (void) obex_message_builder_request_create_connect(message, sizeof(message), obex_version_number, flags, maximum_obex_packet_length); 92*ac9a0d84SMatthias Ringwald parse_request(); 93*ac9a0d84SMatthias Ringwald obex_parser_operation_info_t op_info; 94*ac9a0d84SMatthias Ringwald obex_parser_get_operation_info(&parser, &op_info); 95*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_OPCODE_CONNECT, op_info.opcode); 96*ac9a0d84SMatthias Ringwald CHECK_EQUAL(obex_version_number, op_info.obex_version_number); 97*ac9a0d84SMatthias Ringwald CHECK_EQUAL(flags, op_info.flags); 98*ac9a0d84SMatthias Ringwald CHECK_EQUAL(maximum_obex_packet_length, op_info.max_packet_length); 99*ac9a0d84SMatthias Ringwald } 100*ac9a0d84SMatthias Ringwald 101*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, ConnectRequestWithTarget){ 102*ac9a0d84SMatthias Ringwald (void) obex_message_builder_request_create_connect(message, sizeof(message), obex_version_number, flags, maximum_obex_packet_length); 103*ac9a0d84SMatthias Ringwald (void) obex_message_builder_header_add_target(message, sizeof(message), target, sizeof(target)); 104*ac9a0d84SMatthias Ringwald parse_request(); 105*ac9a0d84SMatthias Ringwald obex_parser_operation_info_t op_info; 106*ac9a0d84SMatthias Ringwald obex_parser_get_operation_info(&parser, &op_info); 107*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_HEADER_TARGET, test_header_id); 108*ac9a0d84SMatthias Ringwald CHECK_EQUAL(sizeof(target), test_header_len); 109*ac9a0d84SMatthias Ringwald MEMCMP_EQUAL(target, test_header_buffer, sizeof(target)); 110*ac9a0d84SMatthias Ringwald } 111*ac9a0d84SMatthias Ringwald 112*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, ConnectResponse){ 113*ac9a0d84SMatthias Ringwald // no create response yet, fake it 114*ac9a0d84SMatthias Ringwald (void) obex_message_builder_request_create_connect(message, sizeof(message), obex_version_number, flags, maximum_obex_packet_length); 115*ac9a0d84SMatthias Ringwald message[0] = OBEX_RESP_SUCCESS; 116*ac9a0d84SMatthias Ringwald parse_response(OBEX_OPCODE_CONNECT); 117*ac9a0d84SMatthias Ringwald obex_parser_operation_info_t op_info; 118*ac9a0d84SMatthias Ringwald obex_parser_get_operation_info(&parser, &op_info); 119*ac9a0d84SMatthias Ringwald CHECK_EQUAL(OBEX_RESP_SUCCESS, op_info.response_code); 120*ac9a0d84SMatthias Ringwald CHECK_EQUAL(obex_version_number, op_info.obex_version_number); 121*ac9a0d84SMatthias Ringwald CHECK_EQUAL(flags, op_info.flags); 122*ac9a0d84SMatthias Ringwald CHECK_EQUAL(maximum_obex_packet_length, op_info.max_packet_length); 123*ac9a0d84SMatthias Ringwald } 124*ac9a0d84SMatthias Ringwald 125*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, GetResponseWithSRM){ 126*ac9a0d84SMatthias Ringwald // no get response yet, fake it 127*ac9a0d84SMatthias Ringwald (void) obex_message_builder_request_create_get(message, sizeof(message), 0x1234); 128*ac9a0d84SMatthias Ringwald obex_message_builder_header_add_srm_enable(message, sizeof(message)); 129*ac9a0d84SMatthias Ringwald parse_request(); 130*ac9a0d84SMatthias Ringwald obex_parser_operation_info_t op_info; 131*ac9a0d84SMatthias Ringwald obex_parser_get_operation_info(&parser, &op_info); 132*ac9a0d84SMatthias Ringwald } 133*ac9a0d84SMatthias Ringwald 134*ac9a0d84SMatthias Ringwald TEST(OBEX_PARSER, SetPathResponse){ 135*ac9a0d84SMatthias Ringwald const uint8_t set_path_response_success[] = { 0xa0, 0x00, 0x03}; 136*ac9a0d84SMatthias Ringwald memcpy(message, set_path_response_success, sizeof(set_path_response_success)); 137*ac9a0d84SMatthias Ringwald parse_response(OBEX_OPCODE_SETPATH); 138*ac9a0d84SMatthias Ringwald } 139*ac9a0d84SMatthias Ringwald 140*ac9a0d84SMatthias Ringwald int main (int argc, const char * argv[]){ 141*ac9a0d84SMatthias Ringwald return CommandLineTestRunner::RunAllTests(argc, argv); 142*ac9a0d84SMatthias Ringwald } 143