commit 9bcecbc977a4be7392fcdc1d2e4ffc1c9ad8cab5 Author: michal.szwaj Date: Sun Feb 11 20:36:55 2018 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e47c61 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Add any directories, files, or patterns you don't want to be tracked by version control +lib/ +bin/ +CMakeLists.txt.user \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..66fb5ab --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,81 @@ +cmake_minimum_required(VERSION 3.5.1) +project(aasdk CXX) + +set(base_directory ${CMAKE_CURRENT_SOURCE_DIR}) +set(sources_directory ${base_directory}/src) + +set(include_directory ${base_directory}/include) +set(include_ut_directory ${base_directory}/include_ut) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${base_directory}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${base_directory}/lib) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${base_directory}/bin) +set(EXECUTABLE_OUTPUT_PATH ${base_directory}/bin) + +SET(CMAKE_CXX_STANDARD 14) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake_modules/") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} -fPIC -Wall -pedantic") +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") +set(CMAKE_CXX_FLAGS_RELEASE "-g -O3") + +set(Boost_USE_STATIC_LIBS OFF) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) + +add_definitions(-DBOOST_ALL_DYN_LINK) + +include(ExternalGtest) +add_subdirectory(aasdk_proto) + +find_package(Boost REQUIRED COMPONENTS system log OPTIONAL_COMPONENTS unit_test_framework) +find_package(libusb-1.0 REQUIRED) +find_package(Protobuf REQUIRED) + +set(AASDK_PROTO_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}) +set(AASDK_PROTO_LIBRARIES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libaasdk_proto.a") + +include_directories(${AASDK_PROTO_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${LIBUSB_1_INCLUDE_DIRS} + ${PROTOBUF_INCLUDE_DIR} + ${GTEST_INCLUDE_DIRS} + ${GMOCK_INCLUDE_DIRS} + ${include_directory} + ${include_ut_directory}) + +file(GLOB_RECURSE source_files ${sources_directory}/*.cpp) +file(GLOB_RECURSE include_files ${include_directory}/*.hpp) +file(GLOB_RECURSE tests_source_files ${sources_directory}/*.ut.cpp) +file(GLOB_RECURSE tests_include_files ${include_ut_directory}/*.hpp) + +list(REMOVE_ITEM source_files ${tests_source_files}) + +add_library(aasdk SHARED + ${source_files} + ${include_files}) + +add_dependencies(aasdk aasdk_proto) +target_link_libraries(aasdk + ${AASDK_PROTO_LIBRARIES} + ${Boost_LIBRARIES} + ${LIBUSB_1_LIBRARIES} + ${PROTOBUF_LIBRARIES} + ssl + crypto) + +add_executable(aasdk_ut EXCLUDE_FROM_ALL + ${tests_source_files} + ${tests_include_files}) + +add_dependencies(aasdk_ut aasdk) +target_link_libraries(aasdk_ut + aasdk + ${GMOCK_LIBRARY_PATH} + ${GTEST_LIBRARY_PATH}) + +if(CODE_COVERAGE) + include(CodeCoverage) + append_coverage_compiler_flags() + setup_target_for_coverage(NAME aasdk_coverage EXECUTABLE aasdk_ut DEPENDENCIES aasdk_ut) +endif(CODE_COVERAGE) diff --git a/aasdk_proto/AVChannelData.proto b/aasdk_proto/AVChannelData.proto new file mode 100644 index 0000000..cddb12e --- /dev/null +++ b/aasdk_proto/AVChannelData.proto @@ -0,0 +1,35 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "AVStreamTypeEnum.proto"; +import "AudioTypeEnum.proto"; +import "AudioConfigData.proto"; +import "VideoConfigData.proto"; + +package f1x.aasdk.proto.data; + +message AVChannel +{ + enums.AVStreamType.Enum stream_type = 1; + enums.AudioType.Enum audio_type = 2; + repeated AudioConfig audio_configs = 3; + repeated VideoConfig video_configs = 4; + bool available_while_in_call = 5; +} diff --git a/aasdk_proto/AVChannelMessageIdsEnum.proto b/aasdk_proto/AVChannelMessageIdsEnum.proto new file mode 100644 index 0000000..c3baaa0 --- /dev/null +++ b/aasdk_proto/AVChannelMessageIdsEnum.proto @@ -0,0 +1,39 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.ids; + +message AVChannelMessage +{ + enum Enum + { + AV_MEDIA_WITH_TIMESTAMP_INDICATION = 0x0000; + AV_MEDIA_INDICATION = 0x0001; + SETUP_REQUEST = 0x8000; + START_INDICATION = 0x8001; + STOP_INDICATION = 0x8002; + SETUP_RESPONSE = 0x8003; + AV_MEDIA_ACK_INDICATION = 0x8004; + AV_INPUT_OPEN_REQUEST = 0x8005; + AV_INPUT_OPEN_RESPONSE = 0x8006; + VIDEO_FOCUS_REQUEST = 0x8007; + VIDEO_FOCUS_INDICATION = 0x8008; + } +} diff --git a/aasdk_proto/AVChannelSetupRequestMessage.proto b/aasdk_proto/AVChannelSetupRequestMessage.proto new file mode 100644 index 0000000..34cb585 --- /dev/null +++ b/aasdk_proto/AVChannelSetupRequestMessage.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message AVChannelSetupRequest +{ + uint32 config_index = 1; +} diff --git a/aasdk_proto/AVChannelSetupResponseMessage.proto b/aasdk_proto/AVChannelSetupResponseMessage.proto new file mode 100644 index 0000000..6efec78 --- /dev/null +++ b/aasdk_proto/AVChannelSetupResponseMessage.proto @@ -0,0 +1,30 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +import "AVChannelSetupStatusEnum.proto"; + +package f1x.aasdk.proto.messages; + +message AVChannelSetupResponse +{ + required enums.AVChannelSetupStatus.Enum media_status = 1; + required uint32 max_unacked = 2; + repeated uint32 configs = 3; +} diff --git a/aasdk_proto/AVChannelSetupStatusEnum.proto b/aasdk_proto/AVChannelSetupStatusEnum.proto new file mode 100644 index 0000000..3c56fdd --- /dev/null +++ b/aasdk_proto/AVChannelSetupStatusEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message AVChannelSetupStatus +{ + enum Enum + { + NONE = 0; + FAIL = 1; + OK = 2; + } +} diff --git a/aasdk_proto/AVChannelStartIndicationMessage.proto b/aasdk_proto/AVChannelStartIndicationMessage.proto new file mode 100644 index 0000000..424759d --- /dev/null +++ b/aasdk_proto/AVChannelStartIndicationMessage.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message AVChannelStartIndication +{ + int32 session = 1; + uint32 config = 2; +} diff --git a/aasdk_proto/AVChannelStopIndicationMessage.proto b/aasdk_proto/AVChannelStopIndicationMessage.proto new file mode 100644 index 0000000..4d8a3b6 --- /dev/null +++ b/aasdk_proto/AVChannelStopIndicationMessage.proto @@ -0,0 +1,25 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message AVChannelStopIndication +{ +} diff --git a/aasdk_proto/AVInputChannelData.proto b/aasdk_proto/AVInputChannelData.proto new file mode 100644 index 0000000..5d85432 --- /dev/null +++ b/aasdk_proto/AVInputChannelData.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "AVStreamTypeEnum.proto"; +import "AudioConfigData.proto"; + +package f1x.aasdk.proto.data; + +message AVInputChannel +{ + enums.AVStreamType.Enum stream_type = 1; + AudioConfig audio_config = 2; + bool available_while_in_call = 3; +} diff --git a/aasdk_proto/AVInputOpenRequestMessage.proto b/aasdk_proto/AVInputOpenRequestMessage.proto new file mode 100644 index 0000000..4d9de26 --- /dev/null +++ b/aasdk_proto/AVInputOpenRequestMessage.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message AVInputOpenRequest +{ + bool open = 1; + bool anc = 2; + bool ec = 3; + int32 max_unacked = 4; +} diff --git a/aasdk_proto/AVInputOpenResponseMessage.proto b/aasdk_proto/AVInputOpenResponseMessage.proto new file mode 100644 index 0000000..76a7213 --- /dev/null +++ b/aasdk_proto/AVInputOpenResponseMessage.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +package f1x.aasdk.proto.messages; + +message AVInputOpenResponse +{ + required int32 session = 1; + required uint32 value = 2; +} diff --git a/aasdk_proto/AVMediaAckIndicationMessage.proto b/aasdk_proto/AVMediaAckIndicationMessage.proto new file mode 100644 index 0000000..b3fa43c --- /dev/null +++ b/aasdk_proto/AVMediaAckIndicationMessage.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +package f1x.aasdk.proto.messages; + +message AVMediaAckIndication +{ + required int32 session = 1; + required uint32 value = 2; +} diff --git a/aasdk_proto/AVStreamTypeEnum.proto b/aasdk_proto/AVStreamTypeEnum.proto new file mode 100644 index 0000000..a52fa84 --- /dev/null +++ b/aasdk_proto/AVStreamTypeEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message AVStreamType +{ + enum Enum + { + NONE = 0; + AUDIO = 1; + VIDEO = 3; + } +} diff --git a/aasdk_proto/AbsoluteInputEventData.proto b/aasdk_proto/AbsoluteInputEventData.proto new file mode 100644 index 0000000..1287938 --- /dev/null +++ b/aasdk_proto/AbsoluteInputEventData.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message AbsoluteInputEvent +{ + uint32 scan_code = 1; + int32 value = 2; +} diff --git a/aasdk_proto/AbsoluteInputEventsData.proto b/aasdk_proto/AbsoluteInputEventsData.proto new file mode 100644 index 0000000..0576bd4 --- /dev/null +++ b/aasdk_proto/AbsoluteInputEventsData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "AbsoluteInputEventData.proto"; + +package f1x.aasdk.proto.data; + +message AbsoluteInputEvents +{ + repeated AbsoluteInputEvent absolute_input_events = 1; +} diff --git a/aasdk_proto/AccelData.proto b/aasdk_proto/AccelData.proto new file mode 100644 index 0000000..61fa1cf --- /dev/null +++ b/aasdk_proto/AccelData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Accel +{ + int32 acceleration_x = 1; + int32 acceleration_y = 2; + int32 acceleration_z = 3; +} diff --git a/aasdk_proto/AudioConfigData.proto b/aasdk_proto/AudioConfigData.proto new file mode 100644 index 0000000..2032285 --- /dev/null +++ b/aasdk_proto/AudioConfigData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message AudioConfig +{ + uint32 sample_rate = 1; + uint32 bit_depth = 2; + uint32 channel_count = 3; +} diff --git a/aasdk_proto/AudioFocusRequestMessage.proto b/aasdk_proto/AudioFocusRequestMessage.proto new file mode 100644 index 0000000..0fb91ae --- /dev/null +++ b/aasdk_proto/AudioFocusRequestMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "AudioFocusTypeEnum.proto"; + +package f1x.aasdk.proto.messages; + +message AudioFocusRequest +{ + enums.AudioFocusType.Enum audio_focus_type = 1; +} diff --git a/aasdk_proto/AudioFocusResponseMessage.proto b/aasdk_proto/AudioFocusResponseMessage.proto new file mode 100644 index 0000000..634eb8c --- /dev/null +++ b/aasdk_proto/AudioFocusResponseMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "AudioFocusStateEnum.proto"; + +package f1x.aasdk.proto.messages; + +message AudioFocusResponse +{ + enums.AudioFocusState.Enum audio_focus_state = 1; +} diff --git a/aasdk_proto/AudioFocusStateEnum.proto b/aasdk_proto/AudioFocusStateEnum.proto new file mode 100644 index 0000000..b334fff --- /dev/null +++ b/aasdk_proto/AudioFocusStateEnum.proto @@ -0,0 +1,36 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message AudioFocusState +{ + enum Enum + { + NONE = 0; + GAIN = 1; + GAIN_TRANSIENT = 2; + LOSS = 3; + LOSS_TRANSIENT_CAN_DUCK = 4; + LOSS_TRANSIENT = 5; + GAIN_MEDIA_ONLY = 6; + GAIN_TRANSIENT_GUIDANCE_ONLY = 7; + } +} diff --git a/aasdk_proto/AudioFocusTypeEnum.proto b/aasdk_proto/AudioFocusTypeEnum.proto new file mode 100644 index 0000000..0e6677a --- /dev/null +++ b/aasdk_proto/AudioFocusTypeEnum.proto @@ -0,0 +1,33 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message AudioFocusType +{ + enum Enum + { + NONE = 0; + GAIN = 1; + GAIN_TRANSIENT = 2; + GAIN_NAVI = 3; + RELEASE = 4; + } +} diff --git a/aasdk_proto/AudioTypeEnum.proto b/aasdk_proto/AudioTypeEnum.proto new file mode 100644 index 0000000..44744f4 --- /dev/null +++ b/aasdk_proto/AudioTypeEnum.proto @@ -0,0 +1,33 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message AudioType +{ + enum Enum + { + NONE = 0; + SPEECH = 1; + SYSTEM = 2; + MEDIA = 3; + ALARM = 4; + } +} diff --git a/aasdk_proto/AuthCompleteIndicationMessage.proto b/aasdk_proto/AuthCompleteIndicationMessage.proto new file mode 100644 index 0000000..99c1b1c --- /dev/null +++ b/aasdk_proto/AuthCompleteIndicationMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +import "StatusEnum.proto"; + +package f1x.aasdk.proto.messages; + +message AuthCompleteIndication +{ + required enums.Status.Enum status = 1; +} diff --git a/aasdk_proto/BindingRequestMessage.proto b/aasdk_proto/BindingRequestMessage.proto new file mode 100644 index 0000000..b11c3d4 --- /dev/null +++ b/aasdk_proto/BindingRequestMessage.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message BindingRequest +{ + repeated int32 scan_codes = 1; +} diff --git a/aasdk_proto/BindingResponseMessage.proto b/aasdk_proto/BindingResponseMessage.proto new file mode 100644 index 0000000..2d7088b --- /dev/null +++ b/aasdk_proto/BindingResponseMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +import "StatusEnum.proto"; + +package f1x.aasdk.proto.messages; + +message BindingResponse +{ + required enums.Status.Enum status = 1; +} diff --git a/aasdk_proto/BluetoothChannelData.proto b/aasdk_proto/BluetoothChannelData.proto new file mode 100644 index 0000000..780ea44 --- /dev/null +++ b/aasdk_proto/BluetoothChannelData.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "BluetoothPairingMethodEnum.proto"; + +package f1x.aasdk.proto.data; + +message BluetoothChannel +{ + string adapter_address = 1; + repeated enums.BluetoothPairingMethod.Enum supported_pairing_methods = 2; +} diff --git a/aasdk_proto/BluetoothChannelMessageIdsEnum.proto b/aasdk_proto/BluetoothChannelMessageIdsEnum.proto new file mode 100644 index 0000000..30ac80e --- /dev/null +++ b/aasdk_proto/BluetoothChannelMessageIdsEnum.proto @@ -0,0 +1,33 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.ids; + +message BluetoothChannelMessage +{ + enum Enum + { + NONE = 0x0000; + PAIRING_REQUEST = 0x8001; + PAIRING_RESPONSE = 0x8002; + AUTH_DATA = 0x8003; + } +} + diff --git a/aasdk_proto/BluetoothPairingMethodEnum.proto b/aasdk_proto/BluetoothPairingMethodEnum.proto new file mode 100644 index 0000000..18591d6 --- /dev/null +++ b/aasdk_proto/BluetoothPairingMethodEnum.proto @@ -0,0 +1,33 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message BluetoothPairingMethod +{ + enum Enum + { + NONE = 0; + UNK_1 = 1; + A2DP = 2; + UNK_3 = 3; + HFP = 4; + } +} diff --git a/aasdk_proto/BluetoothPairingRequestMessage.proto b/aasdk_proto/BluetoothPairingRequestMessage.proto new file mode 100644 index 0000000..91bbea7 --- /dev/null +++ b/aasdk_proto/BluetoothPairingRequestMessage.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "BluetoothPairingMethodEnum.proto"; + +package f1x.aasdk.proto.messages; + +message BluetoothPairingRequest +{ + string phone_address = 1; + enums.BluetoothPairingMethod.Enum pairing_method = 2; +} diff --git a/aasdk_proto/BluetoothPairingResponseMessage.proto b/aasdk_proto/BluetoothPairingResponseMessage.proto new file mode 100644 index 0000000..dd90169 --- /dev/null +++ b/aasdk_proto/BluetoothPairingResponseMessage.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "BluetoothPairingStatusEnum.proto"; + +package f1x.aasdk.proto.messages; + +message BluetoothPairingResponse +{ + bool already_paired = 1; + enums.BluetoothPairingStatus.Enum status = 2; +} diff --git a/aasdk_proto/BluetoothPairingStatusEnum.proto b/aasdk_proto/BluetoothPairingStatusEnum.proto new file mode 100644 index 0000000..4d71a34 --- /dev/null +++ b/aasdk_proto/BluetoothPairingStatusEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message BluetoothPairingStatus +{ + enum Enum + { + NONE = 0; + OK = 1; + FAIL = 2; + } +} diff --git a/aasdk_proto/ButtonCodeEnum.proto b/aasdk_proto/ButtonCodeEnum.proto new file mode 100644 index 0000000..63e36bb --- /dev/null +++ b/aasdk_proto/ButtonCodeEnum.proto @@ -0,0 +1,47 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message ButtonCode +{ + enum Enum + { + NONE = 0x00; + MICROPHONE_2 = 0x01; + MENU = 0x02; + HOME = 0x03; + BACK = 0x04; + PHONE = 0x05; + CALL_END = 0x06; + UP = 0x13; + DOWN = 0x14; + LEFT = 0x15; + RIGHT = 0x16; + ENTER = 0x17; + MICROPHONE_1 = 0x54; + TOGGLE_PLAY = 0x55; + NEXT = 0x57; + PREV = 0x58; + PLAY = 0x7E; + PAUSE = 0x7F; + SCROLL_WHEEL = 65536; + } +} diff --git a/aasdk_proto/ButtonEventData.proto b/aasdk_proto/ButtonEventData.proto new file mode 100644 index 0000000..88bc718 --- /dev/null +++ b/aasdk_proto/ButtonEventData.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message ButtonEvent +{ + uint32 scan_code = 1; + bool is_pressed = 2; + uint32 meta = 3; + bool long_press = 4; +} diff --git a/aasdk_proto/ButtonEventsData.proto b/aasdk_proto/ButtonEventsData.proto new file mode 100644 index 0000000..ae26a12 --- /dev/null +++ b/aasdk_proto/ButtonEventsData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "ButtonEventData.proto"; + +package f1x.aasdk.proto.data; + +message ButtonEvents +{ + repeated ButtonEvent button_events = 1; +} diff --git a/aasdk_proto/CMakeLists.txt b/aasdk_proto/CMakeLists.txt new file mode 100644 index 0000000..ae6a901 --- /dev/null +++ b/aasdk_proto/CMakeLists.txt @@ -0,0 +1,9 @@ +include(FindProtobuf) +find_package(Protobuf REQUIRED) +include_directories(${PROTOBUF_INCLUDE_DIR}) + +file(GLOB_RECURSE proto_files ${CMAKE_CURRENT_SOURCE_DIR}/*.proto) +protobuf_generate_cpp(proto_sources proto_headers ${proto_files}) +add_library(aasdk_proto ${proto_headers} ${proto_sources}) +target_link_libraries(aasdk_proto ${PROTOBUF_LIBRARIES}) + diff --git a/aasdk_proto/ChannelDescriptorData.proto b/aasdk_proto/ChannelDescriptorData.proto new file mode 100644 index 0000000..c167c28 --- /dev/null +++ b/aasdk_proto/ChannelDescriptorData.proto @@ -0,0 +1,41 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "SensorChannelData.proto"; +import "AVChannelData.proto"; +import "InputChannelData.proto"; +import "AVInputChannelData.proto"; +import "BluetoothChannelData.proto"; +import "NavigationChannelData.proto"; +import "VendorExtensionChannelData.proto"; + +package f1x.aasdk.proto.data; + +message ChannelDescriptor +{ + uint32 channel_id = 1; + SensorChannel sensor_channel = 2; + AVChannel av_channel = 3; + InputChannel input_channel = 4; + AVInputChannel av_input_channel = 5; + BluetoothChannel bluetooth_channel = 6; + NavigationChannel navigation_channel = 8; + VendorExtensionChannel vendor_extension_channel = 12; +} diff --git a/aasdk_proto/ChannelOpenRequestMessage.proto b/aasdk_proto/ChannelOpenRequestMessage.proto new file mode 100644 index 0000000..f7e8506 --- /dev/null +++ b/aasdk_proto/ChannelOpenRequestMessage.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message ChannelOpenRequest +{ + int32 priority = 1; + int32 channel_id = 2; +} diff --git a/aasdk_proto/ChannelOpenResponseMessage.proto b/aasdk_proto/ChannelOpenResponseMessage.proto new file mode 100644 index 0000000..0b0ece9 --- /dev/null +++ b/aasdk_proto/ChannelOpenResponseMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +import "StatusEnum.proto"; + +package f1x.aasdk.proto.messages; + +message ChannelOpenResponse +{ + required enums.Status.Enum status = 1; +} diff --git a/aasdk_proto/CompassData.proto b/aasdk_proto/CompassData.proto new file mode 100644 index 0000000..3e821de --- /dev/null +++ b/aasdk_proto/CompassData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Compass +{ + int32 bearing =1; + int32 pitch = 2; + int32 roll = 3; +} diff --git a/aasdk_proto/ControlMessageIdsEnum.proto b/aasdk_proto/ControlMessageIdsEnum.proto new file mode 100644 index 0000000..9d527cd --- /dev/null +++ b/aasdk_proto/ControlMessageIdsEnum.proto @@ -0,0 +1,46 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.ids; + +message ControlMessage +{ + enum Enum + { + NONE = 0x0000; + VERSION_REQUEST = 0x0001; + VERSION_RESPONSE = 0x0002; + SSL_HANDSHAKE = 0x0003; + AUTH_COMPLETE = 0x0004; + SERVICE_DISCOVERY_REQUEST = 0x0005; + SERVICE_DISCOVERY_RESPONSE = 0x0006; + CHANNEL_OPEN_REQUEST = 0x0007; + CHANNEL_OPEN_RESPONSE = 0x0008; + PING_REQUEST = 0x000b; + PING_RESPONSE = 0x000c; + NAVIGATION_FOCUS_REQUEST = 0x000d; + NAVIGATION_FOCUS_RESPONSE = 0x000e; + SHUTDOWN_REQUEST = 0x000f; + SHUTDOWN_RESPONSE = 0x0010; + VOICE_SESSION_REQUEST = 0x0011; + AUDIO_FOCUS_REQUEST = 0x0012; + AUDIO_FOCUS_RESPONSE = 0x0013; + } +} diff --git a/aasdk_proto/DiagnosticsData.proto b/aasdk_proto/DiagnosticsData.proto new file mode 100644 index 0000000..cb7e51c --- /dev/null +++ b/aasdk_proto/DiagnosticsData.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Diagnostics +{ + bytes diagnostics = 1; +} diff --git a/aasdk_proto/DoorData.proto b/aasdk_proto/DoorData.proto new file mode 100644 index 0000000..e6f6eac --- /dev/null +++ b/aasdk_proto/DoorData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Door +{ + bool hood_open = 1; + bool boot_open = 2; + repeated bool door_open = 3; +} diff --git a/aasdk_proto/DrivingStatusData.proto b/aasdk_proto/DrivingStatusData.proto new file mode 100644 index 0000000..57d24bb --- /dev/null +++ b/aasdk_proto/DrivingStatusData.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +package f1x.aasdk.proto.data; + +message DrivingStatus +{ + required int32 status = 1; +} diff --git a/aasdk_proto/DrivingStatusEnum.proto b/aasdk_proto/DrivingStatusEnum.proto new file mode 100644 index 0000000..5adf037 --- /dev/null +++ b/aasdk_proto/DrivingStatusEnum.proto @@ -0,0 +1,35 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message DrivingStatus +{ + enum Enum + { + UNRESTRICTED = 0; + NO_VIDEO = 1; + NO_KEYBOARD_INPUT = 2; + NO_VOICE_INPUT = 4; + NO_CONFIG = 8; + LIMIT_MESSAGE_LEN = 16; + FULLY_RESTRICTED = 31; + } +} diff --git a/aasdk_proto/EnvironmentData.proto b/aasdk_proto/EnvironmentData.proto new file mode 100644 index 0000000..b461121 --- /dev/null +++ b/aasdk_proto/EnvironmentData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Environment +{ + int32 temperature =1; + int32 pressure = 2; + int32 rain = 3; +} diff --git a/aasdk_proto/FuelLevelData.proto b/aasdk_proto/FuelLevelData.proto new file mode 100644 index 0000000..f0fe967 --- /dev/null +++ b/aasdk_proto/FuelLevelData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message FuelLevel +{ + int32 fuel_level = 1; + int32 range = 2; + bool low_fuel = 3; +} diff --git a/aasdk_proto/GPSLocationData.proto b/aasdk_proto/GPSLocationData.proto new file mode 100644 index 0000000..1960714 --- /dev/null +++ b/aasdk_proto/GPSLocationData.proto @@ -0,0 +1,32 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message GPSLocation +{ + uint64 timestamp = 1; + int32 latitude = 2; + int32 longitude = 3; + uint32 accuracy = 4; + int32 altitude = 5; + int32 speed = 6; + int32 bearing = 7; +} diff --git a/aasdk_proto/GearData.proto b/aasdk_proto/GearData.proto new file mode 100644 index 0000000..4eb4ca9 --- /dev/null +++ b/aasdk_proto/GearData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "GearEnum.proto"; + +package f1x.aasdk.proto.data; + +message Gear +{ + enums.Gear.Enum gear = 1; +} diff --git a/aasdk_proto/GearEnum.proto b/aasdk_proto/GearEnum.proto new file mode 100644 index 0000000..3f723b6 --- /dev/null +++ b/aasdk_proto/GearEnum.proto @@ -0,0 +1,42 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message Gear +{ + enum Enum + { + NEUTRAL = 0; + FIRST = 1; + SECOND = 2; + THIRD = 3; + FOURTH = 4; + FIFTH = 5; + SIXTH = 6; + SEVENTH = 7; + EIGHTH = 8; + NINTH = 9; + TENTH = 10; + DRIVE = 100; + PARK = 101; + REVERSE = 102; + } +} diff --git a/aasdk_proto/GyroData.proto b/aasdk_proto/GyroData.proto new file mode 100644 index 0000000..ec3835c --- /dev/null +++ b/aasdk_proto/GyroData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Gyro +{ + int32 rotation_speed_x = 1; + int32 rotation_speed_y = 2; + int32 rotation_speed_z = 3; +} diff --git a/aasdk_proto/HVACData.proto b/aasdk_proto/HVACData.proto new file mode 100644 index 0000000..6850a7c --- /dev/null +++ b/aasdk_proto/HVACData.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message HVAC +{ + int32 target_temperature = 1; + int32 current_temperature = 2; +} diff --git a/aasdk_proto/HeadlightStatusEnum.proto b/aasdk_proto/HeadlightStatusEnum.proto new file mode 100644 index 0000000..f930da3 --- /dev/null +++ b/aasdk_proto/HeadlightStatusEnum.proto @@ -0,0 +1,32 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message HeadlightStatus +{ + enum Enum + { + STATE_0 = 0; + STATE_1 = 1; + STATE_2 = 2; + STATE_3 = 3; + } +} diff --git a/aasdk_proto/IndicatorStatusEnum.proto b/aasdk_proto/IndicatorStatusEnum.proto new file mode 100644 index 0000000..ab3e98d --- /dev/null +++ b/aasdk_proto/IndicatorStatusEnum.proto @@ -0,0 +1,32 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message IndicatorStatus +{ + enum Enum + { + STATE_0 = 0; + STATE_1 = 1; + STATE_2 = 2; + STATE_3 = 3; + } +} diff --git a/aasdk_proto/InputChannelData.proto b/aasdk_proto/InputChannelData.proto new file mode 100644 index 0000000..c1b3e59 --- /dev/null +++ b/aasdk_proto/InputChannelData.proto @@ -0,0 +1,30 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "TouchConfigData.proto"; + +package f1x.aasdk.proto.data; + +message InputChannel +{ + repeated uint32 supported_keycodes = 1; + TouchConfig touch_screen_config = 2; + TouchConfig touch_pad_config = 3; +} diff --git a/aasdk_proto/InputChannelMessageIdsEnum.proto b/aasdk_proto/InputChannelMessageIdsEnum.proto new file mode 100644 index 0000000..d4e3a1e --- /dev/null +++ b/aasdk_proto/InputChannelMessageIdsEnum.proto @@ -0,0 +1,32 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.ids; + +message InputChannelMessage +{ + enum Enum + { + NONE = 0x0000; + INPUT_EVENT_INDICATION = 0x8001; + BINDING_REQUEST = 0x8002; + BINDING_RESPONSE = 0x8003; + } +} diff --git a/aasdk_proto/InputEventIndicationMessage.proto b/aasdk_proto/InputEventIndicationMessage.proto new file mode 100644 index 0000000..2cf8cdc --- /dev/null +++ b/aasdk_proto/InputEventIndicationMessage.proto @@ -0,0 +1,36 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "TouchEventData.proto"; +import "ButtonEventsData.proto"; +import "AbsoluteInputEventsData.proto"; +import "RelativeInputEventsData.proto"; + +package f1x.aasdk.proto.messages; + +message InputEventIndication +{ + uint64 timestamp = 1; + int32 disp_channel = 2; + data.TouchEvent touch_event = 3; + data.ButtonEvents button_event = 4; + data.AbsoluteInputEvents absolute_input_event = 5; + data.RelativeInputEvents relative_input_event = 6; +} diff --git a/aasdk_proto/LightData.proto b/aasdk_proto/LightData.proto new file mode 100644 index 0000000..61d75ed --- /dev/null +++ b/aasdk_proto/LightData.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "HeadlightStatusEnum.proto"; +import "IndicatorStatusEnum.proto"; + +package f1x.aasdk.proto.data; + +message Light +{ + enums.HeadlightStatus.Enum headlight = 1; + enums.IndicatorStatus.Enum indicator = 2; + bool hazard_light_on = 3; +} diff --git a/aasdk_proto/NavigationChannelData.proto b/aasdk_proto/NavigationChannelData.proto new file mode 100644 index 0000000..69a08da --- /dev/null +++ b/aasdk_proto/NavigationChannelData.proto @@ -0,0 +1,30 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "NavigationImageOptionsData.proto"; + +package f1x.aasdk.proto.data; + +message NavigationChannel +{ + uint32 minimum_interval_ms = 1; + uint32 type = 2; + NavigationImageOptions image_options = 3; +} diff --git a/aasdk_proto/NavigationFocusRequestMessage.proto b/aasdk_proto/NavigationFocusRequestMessage.proto new file mode 100644 index 0000000..6be2e12 --- /dev/null +++ b/aasdk_proto/NavigationFocusRequestMessage.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message NavigationFocusRequest +{ + uint32 type = 1; +} diff --git a/aasdk_proto/NavigationFocusResponseMessage.proto b/aasdk_proto/NavigationFocusResponseMessage.proto new file mode 100644 index 0000000..3a81039 --- /dev/null +++ b/aasdk_proto/NavigationFocusResponseMessage.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message NavigationFocusResponse +{ + uint32 type = 1; +} diff --git a/aasdk_proto/NavigationImageOptionsData.proto b/aasdk_proto/NavigationImageOptionsData.proto new file mode 100644 index 0000000..0ba4bbf --- /dev/null +++ b/aasdk_proto/NavigationImageOptionsData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message NavigationImageOptions +{ + int32 width = 1; + int32 height = 2; + int32 colour_depth_bits = 3; +} diff --git a/aasdk_proto/NightModeData.proto b/aasdk_proto/NightModeData.proto new file mode 100644 index 0000000..79971ce --- /dev/null +++ b/aasdk_proto/NightModeData.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message NightMode +{ + bool is_night = 1; +} diff --git a/aasdk_proto/OdometerData.proto b/aasdk_proto/OdometerData.proto new file mode 100644 index 0000000..9fd13ff --- /dev/null +++ b/aasdk_proto/OdometerData.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Odometer +{ + int32 total_mileage = 1; + int32 trip_mileage = 2; +} diff --git a/aasdk_proto/ParkingBrakeData.proto b/aasdk_proto/ParkingBrakeData.proto new file mode 100644 index 0000000..a3dfcb1 --- /dev/null +++ b/aasdk_proto/ParkingBrakeData.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message ParkingBrake +{ + bool parking_brake = 1; +} diff --git a/aasdk_proto/PassengerData.proto b/aasdk_proto/PassengerData.proto new file mode 100644 index 0000000..a028c1f --- /dev/null +++ b/aasdk_proto/PassengerData.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Passenger +{ + bool passenger_present = 1; +} diff --git a/aasdk_proto/PingRequestMessage.proto b/aasdk_proto/PingRequestMessage.proto new file mode 100644 index 0000000..d186fb6 --- /dev/null +++ b/aasdk_proto/PingRequestMessage.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message PingRequest +{ + int64 timestamp = 1; +} diff --git a/aasdk_proto/PingResponseMessage.proto b/aasdk_proto/PingResponseMessage.proto new file mode 100644 index 0000000..ebb9229 --- /dev/null +++ b/aasdk_proto/PingResponseMessage.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message PingResponse +{ + int64 timestamp = 1; +} diff --git a/aasdk_proto/RPMData.proto b/aasdk_proto/RPMData.proto new file mode 100644 index 0000000..3aacc40 --- /dev/null +++ b/aasdk_proto/RPMData.proto @@ -0,0 +1,26 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message RPM +{ + int32 rpm = 1; +} diff --git a/aasdk_proto/RelativeInputEventData.proto b/aasdk_proto/RelativeInputEventData.proto new file mode 100644 index 0000000..c8efcd9 --- /dev/null +++ b/aasdk_proto/RelativeInputEventData.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message RelativeInputEvent +{ + uint32 scan_code = 1; + int32 delta = 2; +} diff --git a/aasdk_proto/RelativeInputEventsData.proto b/aasdk_proto/RelativeInputEventsData.proto new file mode 100644 index 0000000..b70fe5c --- /dev/null +++ b/aasdk_proto/RelativeInputEventsData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "RelativeInputEventData.proto"; + +package f1x.aasdk.proto.data; + +message RelativeInputEvents +{ + repeated RelativeInputEvent relative_input_events = 1; +} diff --git a/aasdk_proto/SensorChannelData.proto b/aasdk_proto/SensorChannelData.proto new file mode 100644 index 0000000..976d0dc --- /dev/null +++ b/aasdk_proto/SensorChannelData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "SensorData.proto"; + +package f1x.aasdk.proto.data; + +message SensorChannel +{ + repeated Sensor sensors = 1; +} diff --git a/aasdk_proto/SensorChannelMessageIdsEnum.proto b/aasdk_proto/SensorChannelMessageIdsEnum.proto new file mode 100644 index 0000000..f85d46e --- /dev/null +++ b/aasdk_proto/SensorChannelMessageIdsEnum.proto @@ -0,0 +1,32 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.ids; + +message SensorChannelMessage +{ + enum Enum + { + NONE = 0x0000; + SENSOR_START_REQUEST = 0x8001; + SENSOR_START_RESPONSE = 0x8002; + SENSOR_EVENT_INDICATION = 0x8003; + } +} diff --git a/aasdk_proto/SensorData.proto b/aasdk_proto/SensorData.proto new file mode 100644 index 0000000..b21e485 --- /dev/null +++ b/aasdk_proto/SensorData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "SensorTypeEnum.proto"; + +package f1x.aasdk.proto.data; + +message Sensor +{ + enums.SensorType.Enum type = 1; +} diff --git a/aasdk_proto/SensorEventIndicationMessage.proto b/aasdk_proto/SensorEventIndicationMessage.proto new file mode 100644 index 0000000..0b2cce8 --- /dev/null +++ b/aasdk_proto/SensorEventIndicationMessage.proto @@ -0,0 +1,64 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "GPSLocationData.proto"; +import "CompassData.proto"; +import "SpeedData.proto"; +import "RPMData.proto"; +import "OdometerData.proto"; +import "FuelLevelData.proto"; +import "ParkingBrakeData.proto"; +import "GearData.proto"; +import "DiagnosticsData.proto"; +import "NightModeData.proto"; +import "EnvironmentData.proto"; +import "HVACData.proto"; +import "DrivingStatusData.proto"; +import "SteeringWheelData.proto"; +import "PassengerData.proto"; +import "DoorData.proto"; +import "LightData.proto"; +import "AccelData.proto"; +import "GyroData.proto"; + +package f1x.aasdk.proto.messages; + +message SensorEventIndication +{ + repeated data.GPSLocation gps_location = 1; + repeated data.Compass compass = 2; + repeated data.Speed speed = 3; + repeated data.RPM rpm = 4; + repeated data.Odometer odometer = 5; + repeated data.FuelLevel fuel_level = 6; + repeated data.ParkingBrake parking_brake = 7; + repeated data.Gear gear = 8; + repeated data.Diagnostics diagnostics = 9; + repeated data.NightMode night_mode = 10; + repeated data.Environment enviorment = 11; + repeated data.HVAC hvac = 12; + repeated data.DrivingStatus driving_status = 13; + repeated data.SteeringWheel steering_wheel = 14; + repeated data.Passenger passenger = 15; + repeated data.Door door = 16; + repeated data.Light light = 17; + repeated data.Accel accel = 19; + repeated data.Gyro gyro = 20; +} diff --git a/aasdk_proto/SensorStartRequestMessage.proto b/aasdk_proto/SensorStartRequestMessage.proto new file mode 100644 index 0000000..f9abda1 --- /dev/null +++ b/aasdk_proto/SensorStartRequestMessage.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "SensorTypeEnum.proto"; + +package f1x.aasdk.proto.messages; + +message SensorStartRequestMessage +{ + enums.SensorType.Enum sensor_type = 1; + int64 refresh_interval = 2; +} diff --git a/aasdk_proto/SensorStartResponseMessage.proto b/aasdk_proto/SensorStartResponseMessage.proto new file mode 100644 index 0000000..b37896f --- /dev/null +++ b/aasdk_proto/SensorStartResponseMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto2"; + +import "StatusEnum.proto"; + +package f1x.aasdk.proto.messages; + +message SensorStartResponseMessage +{ + required enums.Status.Enum status = 1; +} diff --git a/aasdk_proto/SensorTypeEnum.proto b/aasdk_proto/SensorTypeEnum.proto new file mode 100644 index 0000000..9001bdf --- /dev/null +++ b/aasdk_proto/SensorTypeEnum.proto @@ -0,0 +1,50 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message SensorType +{ + enum Enum + { + NONE = 0; + LOCATION = 1; + COMPASS = 2; + CAR_SPEED = 3; + RPM = 4; + ODOMETER = 5; + FUEL_LEVEL = 6; + PARKING_BRAKE = 7; + GEAR = 8; + DIAGNOSTICS = 9; + NIGHT_DATA = 10; + ENVIRONMENT = 11; + HVAC = 12; + DRIVING_STATUS = 13; + DEAD_RECONING = 14; + PASSENGER = 15; + DOOR = 16; + LIGHT = 17; + TIRE = 18; + ACCEL = 19; + GYRO = 20; + GPS = 21; + } +} diff --git a/aasdk_proto/ServiceDiscoveryRequestMessage.proto b/aasdk_proto/ServiceDiscoveryRequestMessage.proto new file mode 100644 index 0000000..ee1e313 --- /dev/null +++ b/aasdk_proto/ServiceDiscoveryRequestMessage.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message ServiceDiscoveryRequest +{ + string device_name = 4; + string device_brand = 5; +} diff --git a/aasdk_proto/ServiceDiscoveryResponseMessage.proto b/aasdk_proto/ServiceDiscoveryResponseMessage.proto new file mode 100644 index 0000000..ea11d3f --- /dev/null +++ b/aasdk_proto/ServiceDiscoveryResponseMessage.proto @@ -0,0 +1,39 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "ChannelDescriptorData.proto"; + +package f1x.aasdk.proto.messages; + +message ServiceDiscoveryResponse +{ + repeated data.ChannelDescriptor channels = 1; + string head_unit_name = 2; + string car_model = 3; + string car_year = 4; + string car_serial = 5; + bool left_hand_drive_vehicle = 6; + string headunit_manufacturer = 7; + string headunit_model = 8; + string sw_build = 9; + string sw_version = 10; + bool can_play_native_media_during_vr = 11; + bool hide_clock = 12; +} diff --git a/aasdk_proto/ShutdownReasonEnum.proto b/aasdk_proto/ShutdownReasonEnum.proto new file mode 100644 index 0000000..451174b --- /dev/null +++ b/aasdk_proto/ShutdownReasonEnum.proto @@ -0,0 +1,30 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message ShutdownReason +{ + enum Enum + { + NONE = 0; + QUIT = 1; + } +} diff --git a/aasdk_proto/ShutdownRequestMessage.proto b/aasdk_proto/ShutdownRequestMessage.proto new file mode 100644 index 0000000..ba7696f --- /dev/null +++ b/aasdk_proto/ShutdownRequestMessage.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "ShutdownReasonEnum.proto"; + +package f1x.aasdk.proto.messages; + +message ShutdownRequest +{ + enums.ShutdownReason.Enum reason = 1; +} diff --git a/aasdk_proto/ShutdownResponseMessage.proto b/aasdk_proto/ShutdownResponseMessage.proto new file mode 100644 index 0000000..66c7325 --- /dev/null +++ b/aasdk_proto/ShutdownResponseMessage.proto @@ -0,0 +1,25 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.messages; + +message ShutdownResponse +{ +} diff --git a/aasdk_proto/SpeedData.proto b/aasdk_proto/SpeedData.proto new file mode 100644 index 0000000..304a01b --- /dev/null +++ b/aasdk_proto/SpeedData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message Speed +{ + int32 speed = 1; + bool cruise_engaged = 2; + bool cruise_set_speed = 3; +} diff --git a/aasdk_proto/StatusEnum.proto b/aasdk_proto/StatusEnum.proto new file mode 100644 index 0000000..9bf67ab --- /dev/null +++ b/aasdk_proto/StatusEnum.proto @@ -0,0 +1,30 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message Status +{ + enum Enum + { + OK = 0; + FAIL = 1; + } +} diff --git a/aasdk_proto/SteeringWheelData.proto b/aasdk_proto/SteeringWheelData.proto new file mode 100644 index 0000000..a3a1376 --- /dev/null +++ b/aasdk_proto/SteeringWheelData.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message SteeringWheel +{ + int32 steering_angel = 1; + int32 wheel_speed = 2; +} diff --git a/aasdk_proto/TouchActionEnum.proto b/aasdk_proto/TouchActionEnum.proto new file mode 100644 index 0000000..9a86f7f --- /dev/null +++ b/aasdk_proto/TouchActionEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message TouchAction +{ + enum Enum + { + PRESS = 0; + RELEASE = 1; + DRAG = 2; + } +} diff --git a/aasdk_proto/TouchConfigData.proto b/aasdk_proto/TouchConfigData.proto new file mode 100644 index 0000000..988f52e --- /dev/null +++ b/aasdk_proto/TouchConfigData.proto @@ -0,0 +1,27 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message TouchConfig +{ + uint32 width = 1; + uint32 height = 2; +} diff --git a/aasdk_proto/TouchEventData.proto b/aasdk_proto/TouchEventData.proto new file mode 100644 index 0000000..dc3bfcd --- /dev/null +++ b/aasdk_proto/TouchEventData.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "TouchLocationData.proto"; +import "TouchActionEnum.proto"; + +package f1x.aasdk.proto.data; + +message TouchEvent +{ + repeated data.TouchLocation touch_location = 1; + uint32 action_index = 2; + enums.TouchAction.Enum touch_action = 3; +} diff --git a/aasdk_proto/TouchLocationData.proto b/aasdk_proto/TouchLocationData.proto new file mode 100644 index 0000000..101ca39 --- /dev/null +++ b/aasdk_proto/TouchLocationData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message TouchLocation +{ + uint32 x = 1; + uint32 y = 2; + uint32 pointer_id = 3; +} diff --git a/aasdk_proto/VendorExtensionChannelData.proto b/aasdk_proto/VendorExtensionChannelData.proto new file mode 100644 index 0000000..82a8485 --- /dev/null +++ b/aasdk_proto/VendorExtensionChannelData.proto @@ -0,0 +1,28 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.data; + +message VendorExtensionChannel +{ + string name = 1; + repeated string package_white_list = 2; + bytes data = 3; +} diff --git a/aasdk_proto/VersionResponseStatusEnum.proto b/aasdk_proto/VersionResponseStatusEnum.proto new file mode 100644 index 0000000..efec2fa --- /dev/null +++ b/aasdk_proto/VersionResponseStatusEnum.proto @@ -0,0 +1,30 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message VersionResponseStatus +{ + enum Enum + { + MATCH = 0; + MISMATCH = 0xFFFF; + } +} diff --git a/aasdk_proto/VideoConfigData.proto b/aasdk_proto/VideoConfigData.proto new file mode 100644 index 0000000..98fc3fb --- /dev/null +++ b/aasdk_proto/VideoConfigData.proto @@ -0,0 +1,34 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "VideoResolutionEnum.proto"; +import "VideoFPSEnum.proto"; + +package f1x.aasdk.proto.data; + +message VideoConfig +{ + enums.VideoResolution.Enum video_resolution = 1; + enums.VideoFPS.Enum video_fps = 2; + uint32 margin_width = 3; + uint32 margin_height = 4; + uint32 dpi = 5; + uint32 additional_depth = 6; +} diff --git a/aasdk_proto/VideoFPSEnum.proto b/aasdk_proto/VideoFPSEnum.proto new file mode 100644 index 0000000..734bdf6 --- /dev/null +++ b/aasdk_proto/VideoFPSEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message VideoFPS +{ + enum Enum + { + NONE = 0; + _30 = 1; + _60 = 2; + } +} diff --git a/aasdk_proto/VideoFocusIndicationMessage.proto b/aasdk_proto/VideoFocusIndicationMessage.proto new file mode 100644 index 0000000..91a8ee4 --- /dev/null +++ b/aasdk_proto/VideoFocusIndicationMessage.proto @@ -0,0 +1,29 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "VideoFocusModeEnum.proto"; + +package f1x.aasdk.proto.messages; + +message VideoFocusIndication +{ + enums.VideoFocusMode.Enum focus_mode = 1; + bool unrequested = 2; +} diff --git a/aasdk_proto/VideoFocusModeEnum.proto b/aasdk_proto/VideoFocusModeEnum.proto new file mode 100644 index 0000000..e0f930a --- /dev/null +++ b/aasdk_proto/VideoFocusModeEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message VideoFocusMode +{ + enum Enum + { + NONE = 0; + FOCUSED = 1; + UNFOCUSED = 2; + } +} diff --git a/aasdk_proto/VideoFocusReasonEnum.proto b/aasdk_proto/VideoFocusReasonEnum.proto new file mode 100644 index 0000000..0d20ae5 --- /dev/null +++ b/aasdk_proto/VideoFocusReasonEnum.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message VideoFocusReason +{ + enum Enum + { + NONE = 0; + UNK_1 = 1; + UNK_2 = 2; + } +} diff --git a/aasdk_proto/VideoFocusRequestMessage.proto b/aasdk_proto/VideoFocusRequestMessage.proto new file mode 100644 index 0000000..37c3b8b --- /dev/null +++ b/aasdk_proto/VideoFocusRequestMessage.proto @@ -0,0 +1,31 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +import "VideoFocusModeEnum.proto"; +import "VideoFocusReasonEnum.proto"; + +package f1x.aasdk.proto.messages; + +message VideoFocusRequest +{ + int32 disp_index = 1; + enums.VideoFocusMode.Enum focus_mode = 2; + enums.VideoFocusReason.Enum focus_reason = 3; +} diff --git a/aasdk_proto/VideoResolutionEnum.proto b/aasdk_proto/VideoResolutionEnum.proto new file mode 100644 index 0000000..6e7b9d0 --- /dev/null +++ b/aasdk_proto/VideoResolutionEnum.proto @@ -0,0 +1,32 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +syntax="proto3"; + +package f1x.aasdk.proto.enums; + +message VideoResolution +{ + enum Enum + { + NONE = 0; + _480p = 1; + _720p = 2; + _1080p = 3; + } +} diff --git a/cmake_modules/CodeCoverage.cmake b/cmake_modules/CodeCoverage.cmake new file mode 100755 index 0000000..2527b3c --- /dev/null +++ b/cmake_modules/CodeCoverage.cmake @@ -0,0 +1,238 @@ +# Copyright (c) 2012 - 2017, Lars Bilke +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# CHANGES: +# +# 2012-01-31, Lars Bilke +# - Enable Code Coverage +# +# 2013-09-17, Joakim Söderberg +# - Added support for Clang. +# - Some additional usage instructions. +# +# 2016-02-03, Lars Bilke +# - Refactored functions to use named parameters +# +# 2017-06-02, Lars Bilke +# - Merged with modified version from github.com/ufz/ogs +# +# +# USAGE: +# +# 1. Copy this file into your cmake modules path. +# +# 2. Add the following line to your CMakeLists.txt: +# include(CodeCoverage) +# +# 3. Append necessary compiler flags: +# APPEND_COVERAGE_COMPILER_FLAGS() +# +# 4. If you need to exclude additional directories from the report, specify them +# using the COVERAGE_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE. +# Example: +# set(COVERAGE_EXCLUDES 'dir1/*' 'dir2/*') +# +# 5. Use the functions described below to create a custom make target which +# runs your test executable and produces a code coverage report. +# +# 6. Build a Debug build: +# cmake -DCMAKE_BUILD_TYPE=Debug .. +# make +# make my_coverage_target +# + +include(CMakeParseArguments) + +# Check prereqs +find_program( GCOV_PATH gcov ) +find_program( LCOV_PATH lcov ) +find_program( GENHTML_PATH genhtml ) +find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) +find_program( SIMPLE_PYTHON_EXECUTABLE python ) + +if(NOT GCOV_PATH) + message(FATAL_ERROR "gcov not found! Aborting...") +endif() # NOT GCOV_PATH + +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") + if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3) + message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") + endif() +elseif(NOT CMAKE_COMPILER_IS_GNUCXX) + message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...") +endif() + +set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage -fprofile-arcs -ftest-coverage" + CACHE INTERNAL "") + +set(CMAKE_CXX_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C++ compiler during coverage builds." + FORCE ) +set(CMAKE_C_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C compiler during coverage builds." + FORCE ) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used for linking binaries during coverage builds." + FORCE ) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used by the shared libraries linker during coverage builds." + FORCE ) +mark_as_advanced( + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) + +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") +endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug" + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + link_libraries(gcov) +else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") +endif() + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# SETUP_TARGET_FOR_COVERAGE( +# NAME testrunner_coverage # New target name +# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES testrunner # Dependencies to build first +# ) +function(SETUP_TARGET_FOR_COVERAGE) + + set(options NONE) + set(oneValueArgs NAME) + set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT LCOV_PATH) + message(FATAL_ERROR "lcov not found! Aborting...") + endif() # NOT LCOV_PATH + + if(NOT GENHTML_PATH) + message(FATAL_ERROR "genhtml not found! Aborting...") + endif() # NOT GENHTML_PATH + + # Setup target + add_custom_target(${Coverage_NAME} + + # Cleanup lcov + COMMAND ${LCOV_PATH} --directory . --zerocounters + # Create baseline to make sure untouched files show up in the report + COMMAND ${LCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base + + # Run tests + COMMAND ${Coverage_EXECUTABLE} + + # Capturing lcov counters and generating report + COMMAND ${LCOV_PATH} --directory . --capture --output-file ${Coverage_NAME}.info + # add baseline counters + COMMAND ${LCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.info --output-file ${Coverage_NAME}.total + COMMAND ${LCOV_PATH} --remove ${Coverage_NAME}.total ${COVERAGE_EXCLUDES} --output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned + COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned + COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.info ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned + + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." + ) + +endfunction() # SETUP_TARGET_FOR_COVERAGE + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# SETUP_TARGET_FOR_COVERAGE_COBERTURA( +# NAME ctest_coverage # New target name +# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES executable_target # Dependencies to build first +# ) +function(SETUP_TARGET_FOR_COVERAGE_COBERTURA) + + set(options NONE) + set(oneValueArgs NAME) + set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT SIMPLE_PYTHON_EXECUTABLE) + message(FATAL_ERROR "python not found! Aborting...") + endif() # NOT SIMPLE_PYTHON_EXECUTABLE + + if(NOT GCOVR_PATH) + message(FATAL_ERROR "gcovr not found! Aborting...") + endif() # NOT GCOVR_PATH + + # Combine excludes to several -e arguments + set(COBERTURA_EXCLUDES "") + foreach(EXCLUDE ${COVERAGE_EXCLUDES}) + set(COBERTURA_EXCLUDES "-e ${EXCLUDE} ${COBERTURA_EXCLUDES}") + endforeach() + + add_custom_target(${Coverage_NAME} + + # Run tests + ${Coverage_EXECUTABLE} + + # Running gcovr + COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} ${COBERTURA_EXCLUDES} + -o ${Coverage_NAME}.xml + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + COMMENT "Running gcovr to produce Cobertura code coverage report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml." + ) + +endfunction() # SETUP_TARGET_FOR_COVERAGE_COBERTURA + +function(APPEND_COVERAGE_COMPILER_FLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") +endfunction() # APPEND_COVERAGE_COMPILER_FLAGS diff --git a/cmake_modules/ExternalGtest.cmake b/cmake_modules/ExternalGtest.cmake new file mode 100644 index 0000000..1a33091 --- /dev/null +++ b/cmake_modules/ExternalGtest.cmake @@ -0,0 +1,48 @@ +find_package(Threads REQUIRED) + +include(ExternalProject) +ExternalProject_Add( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + UPDATE_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON) + +ExternalProject_Get_Property(googletest source_dir) +set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include) +set(GMOCK_INCLUDE_DIRS ${source_dir}/googlemock/include) + +ExternalProject_Get_Property(googletest binary_dir) +set(GTEST_LIBRARY_PATH ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a) +set(GTEST_LIBRARY gtest) +add_library(${GTEST_LIBRARY} UNKNOWN IMPORTED) +set_target_properties(${GTEST_LIBRARY} PROPERTIES + IMPORTED_LOCATION ${GTEST_LIBRARY_PATH} + IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +add_dependencies(${GTEST_LIBRARY} googletest) + +set(GTEST_MAIN_LIBRARY_PATH ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main.a) +set(GTEST_MAIN_LIBRARY gtest_main) +add_library(${GTEST_MAIN_LIBRARY} UNKNOWN IMPORTED) +set_target_properties(${GTEST_MAIN_LIBRARY} PROPERTIES + IMPORTED_LOCATION ${GTEST_MAIN_LIBRARY_PATH} + IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +add_dependencies(${GTEST_MAIN_LIBRARY} googletest) + +set(GMOCK_LIBRARY_PATH ${binary_dir}/googlemock/${CMAKE_FIND_LIBRARY_PREFIXES}gmock.a) +set(GMOCK_LIBRARY gmock) +add_library(${GMOCK_LIBRARY} UNKNOWN IMPORTED) +set_target_properties(${GMOCK_LIBRARY} PROPERTIES + IMPORTED_LOCATION ${GMOCK_LIBRARY_PATH} + IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +add_dependencies(${GMOCK_LIBRARY} googletest) + +set(GMOCK_MAIN_LIBRARY_PATH ${binary_dir}/googlemock/${CMAKE_FIND_LIBRARY_PREFIXES}gmock_main.a) +set(GMOCK_MAIN_LIBRARY gmock_main) +add_library(${GMOCK_MAIN_LIBRARY} UNKNOWN IMPORTED) +set_target_properties(${GMOCK_MAIN_LIBRARY} PROPERTIES + IMPORTED_LOCATION ${GMOCK_MAIN_LIBRARY_PATH} + IMPORTED_LINK_INTERFACE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +add_dependencies(${GMOCK_MAIN_LIBRARY} ${GTEST_LIBRARY}) diff --git a/cmake_modules/Findlibusb-1.0.cmake b/cmake_modules/Findlibusb-1.0.cmake new file mode 100644 index 0000000..ec40055 --- /dev/null +++ b/cmake_modules/Findlibusb-1.0.cmake @@ -0,0 +1,98 @@ +# - Try to find libusb-1.0 +# Once done this will define +# +# LIBUSB_1_FOUND - system has libusb +# LIBUSB_1_INCLUDE_DIRS - the libusb include directory +# LIBUSB_1_LIBRARIES - Link these to use libusb +# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb +# +# Adapted from cmake-modules Google Code project +# +# Copyright (c) 2006 Andreas Schneider +# +# (Changes for libusb) Copyright (c) 2008 Kyle Machulis +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# +# CMake-Modules Project New BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the CMake-Modules Project nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) + # in cache already + set(LIBUSB_FOUND TRUE) +else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) + find_path(LIBUSB_1_INCLUDE_DIR + NAMES + libusb.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + PATH_SUFFIXES + libusb-1.0 + ) + + find_library(LIBUSB_1_LIBRARY + NAMES + usb-1.0 usb + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + set(LIBUSB_1_INCLUDE_DIRS + ${LIBUSB_1_INCLUDE_DIR} + ) + set(LIBUSB_1_LIBRARIES + ${LIBUSB_1_LIBRARY} +) + + if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) + set(LIBUSB_1_FOUND TRUE) + endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) + + if (LIBUSB_1_FOUND) + if (NOT libusb_1_FIND_QUIETLY) + message(STATUS "Found libusb-1.0:") + message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}") + message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}") + endif (NOT libusb_1_FIND_QUIETLY) + else (LIBUSB_1_FOUND) + if (libusb_1_FIND_REQUIRED) + message(FATAL_ERROR "Could not find libusb") + endif (libusb_1_FIND_REQUIRED) + endif (LIBUSB_1_FOUND) + + # show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view + mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES) + +endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) diff --git a/include/f1x/aasdk/Channel/AV/AVInputServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/AVInputServiceChannel.hpp new file mode 100644 index 0000000..0bf52f9 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/AVInputServiceChannel.hpp @@ -0,0 +1,59 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class AVInputServiceChannel: public IAVInputServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ +public: + AVInputServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); + + void receive(IAVInputServiceChannelEventHandler::Pointer eventHandler) override; + void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) override; + void sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) override; + void sendAVInputOpenResponse(const proto::messages::AVInputOpenResponse& response, SendPromise::Pointer promise) override; + void sendAVMediaWithTimestampIndication(messenger::Timestamp::ValueType, const common::Data& data, SendPromise::Pointer promise) override; + messenger::ChannelId getId() override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, IAVInputServiceChannelEventHandler::Pointer eventHandler); + void handleAVChannelSetupRequest(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler); + void handleAVInputOpenRequest(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler); + void handleAVMediaAckIndication(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler); + void handleChannelOpenRequest(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/AudioServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/AudioServiceChannel.hpp new file mode 100644 index 0000000..89abdf1 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/AudioServiceChannel.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class AudioServiceChannel: public IAudioServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ +public: + AudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger, messenger::ChannelId channelId); + + void receive(IAudioServiceChannelEventHandler::Pointer eventHandler) override; + void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) override; + void sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) override; + void sendAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication, SendPromise::Pointer promise) override; + messenger::ChannelId getId() override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, IAudioServiceChannelEventHandler::Pointer eventHandler); + void handleAVChannelSetupRequest(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler); + void handleStartIndication(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler); + void handleStopIndication(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler); + void handleChannelOpenRequest(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler); + void handleAVMediaWithTimestampIndication(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/IAVInputServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/IAVInputServiceChannel.hpp new file mode 100644 index 0000000..85ef26b --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/IAVInputServiceChannel.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class IAVInputServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + IAVInputServiceChannel() = default; + virtual ~IAVInputServiceChannel() = default; + + virtual void receive(IAVInputServiceChannelEventHandler::Pointer eventHandler) = 0; + virtual void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendAVMediaWithTimestampIndication(messenger::Timestamp::ValueType, const common::Data& data, SendPromise::Pointer promise) = 0; + virtual void sendAVInputOpenResponse(const proto::messages::AVInputOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual messenger::ChannelId getId() = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/IAVInputServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/AV/IAVInputServiceChannelEventHandler.hpp new file mode 100644 index 0000000..8cd1b2d --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/IAVInputServiceChannelEventHandler.hpp @@ -0,0 +1,54 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class IAVInputServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + IAVInputServiceChannelEventHandler() = default; + virtual ~IAVInputServiceChannelEventHandler() = default; + + virtual void onChannelOpenRequest(const proto::messages::ChannelOpenRequest& request) = 0; + virtual void onAVChannelSetupRequest(const proto::messages::AVChannelSetupRequest& request) = 0; + virtual void onAVInputOpenRequest(const proto::messages::AVInputOpenRequest& request) = 0; + virtual void onAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/IAudioServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/IAudioServiceChannel.hpp new file mode 100644 index 0000000..61ffd25 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/IAudioServiceChannel.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class IAudioServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + IAudioServiceChannel() = default; + virtual ~IAudioServiceChannel() = default; + + virtual void receive(IAudioServiceChannelEventHandler::Pointer eventHandler) = 0; + virtual void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication, SendPromise::Pointer promise) = 0; + virtual messenger::ChannelId getId() = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/IAudioServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/AV/IAudioServiceChannelEventHandler.hpp new file mode 100644 index 0000000..48cd87c --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/IAudioServiceChannelEventHandler.hpp @@ -0,0 +1,59 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class IAudioServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + IAudioServiceChannelEventHandler() = default; + virtual ~IAudioServiceChannelEventHandler() = default; + + virtual void onChannelOpenRequest(const proto::messages::ChannelOpenRequest& request) = 0; + virtual void onAVChannelSetupRequest(const proto::messages::AVChannelSetupRequest& request) = 0; + virtual void onAVChannelStartIndication(const proto::messages::AVChannelStartIndication& indication) = 0; + virtual void onAVChannelStopIndication(const proto::messages::AVChannelStopIndication& indication) = 0; + virtual void onAVMediaWithTimestampIndication(messenger::Timestamp::ValueType, const common::DataConstBuffer& buffer) = 0; + virtual void onAVMediaIndication(const common::DataConstBuffer& buffer) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/IVideoServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/IVideoServiceChannel.hpp new file mode 100644 index 0000000..0432c94 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/IVideoServiceChannel.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class IVideoServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + IVideoServiceChannel() = default; + virtual ~IVideoServiceChannel() = default; + + virtual void receive(IVideoServiceChannelEventHandler::Pointer eventHandler) = 0; + virtual void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendVideoFocusIndication(const proto::messages::VideoFocusIndication& indication, SendPromise::Pointer promise) = 0; + virtual void sendAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication, SendPromise::Pointer promise) = 0; + virtual messenger::ChannelId getId() = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/IVideoServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/AV/IVideoServiceChannelEventHandler.hpp new file mode 100644 index 0000000..72820ad --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/IVideoServiceChannelEventHandler.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class IVideoServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + IVideoServiceChannelEventHandler() = default; + virtual ~IVideoServiceChannelEventHandler() = default; + + virtual void onChannelOpenRequest(const proto::messages::ChannelOpenRequest& request) = 0; + virtual void onAVChannelSetupRequest(const proto::messages::AVChannelSetupRequest& request) = 0; + virtual void onAVChannelStartIndication(const proto::messages::AVChannelStartIndication& indication) = 0; + virtual void onAVMediaWithTimestampIndication(messenger::Timestamp::ValueType, const common::DataConstBuffer& buffer) = 0; + virtual void onAVMediaIndication(const common::DataConstBuffer& buffer) = 0; + virtual void onVideoFocusRequest(const proto::messages::VideoFocusRequest& request) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/MediaAudioServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/MediaAudioServiceChannel.hpp new file mode 100644 index 0000000..e844143 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/MediaAudioServiceChannel.hpp @@ -0,0 +1,41 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class MediaAudioServiceChannel: public AudioServiceChannel +{ +public: + MediaAudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/SpeechAudioServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/SpeechAudioServiceChannel.hpp new file mode 100644 index 0000000..b786960 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/SpeechAudioServiceChannel.hpp @@ -0,0 +1,41 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class SpeechAudioServiceChannel: public AudioServiceChannel +{ +public: + SpeechAudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/SystemAudioServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/SystemAudioServiceChannel.hpp new file mode 100644 index 0000000..4eca9ba --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/SystemAudioServiceChannel.hpp @@ -0,0 +1,41 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class SystemAudioServiceChannel: public AudioServiceChannel +{ +public: + SystemAudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/AV/VideoServiceChannel.hpp b/include/f1x/aasdk/Channel/AV/VideoServiceChannel.hpp new file mode 100644 index 0000000..4e05745 --- /dev/null +++ b/include/f1x/aasdk/Channel/AV/VideoServiceChannel.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +class VideoServiceChannel: public IVideoServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ +public: + VideoServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); + + void receive(IVideoServiceChannelEventHandler::Pointer eventHandler) override; + void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) override; + void sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) override; + void sendVideoFocusIndication(const proto::messages::VideoFocusIndication& indication, SendPromise::Pointer promise) override; + void sendAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication, SendPromise::Pointer promise) override; + messenger::ChannelId getId() override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, IVideoServiceChannelEventHandler::Pointer eventHandler); + void handleAVChannelSetupRequest(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler); + void handleStartIndication(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler); + void handleChannelOpenRequest(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler); + void handleVideoFocusRequest(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler); + void handleAVMediaWithTimestampIndication(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Bluetooth/BluetoothServiceChannel.hpp b/include/f1x/aasdk/Channel/Bluetooth/BluetoothServiceChannel.hpp new file mode 100644 index 0000000..da5d6e4 --- /dev/null +++ b/include/f1x/aasdk/Channel/Bluetooth/BluetoothServiceChannel.hpp @@ -0,0 +1,53 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace bluetooth +{ + +class BluetoothServiceChannel: public IBluetoothServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ +public: + BluetoothServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); + + void receive(IBluetoothServiceChannelEventHandler::Pointer eventHandler) override; + messenger::ChannelId getId() override; + void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) override; + void sendBluetoothPairingResponse(const proto::messages::BluetoothPairingResponse& response, SendPromise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, IBluetoothServiceChannelEventHandler::Pointer eventHandler); + void handleChannelOpenRequest(const common::DataConstBuffer& payload, IBluetoothServiceChannelEventHandler::Pointer eventHandler); + void handleBluetoothPairingRequest(const common::DataConstBuffer& payload, IBluetoothServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Bluetooth/IBluetoothServiceChannel.hpp b/include/f1x/aasdk/Channel/Bluetooth/IBluetoothServiceChannel.hpp new file mode 100644 index 0000000..4758a00 --- /dev/null +++ b/include/f1x/aasdk/Channel/Bluetooth/IBluetoothServiceChannel.hpp @@ -0,0 +1,54 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace bluetooth +{ + +class IBluetoothServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + IBluetoothServiceChannel() = default; + virtual ~IBluetoothServiceChannel() = default; + + virtual void receive(IBluetoothServiceChannelEventHandler::Pointer eventHandler) = 0; + virtual void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendBluetoothPairingResponse(const proto::messages::BluetoothPairingResponse& response, SendPromise::Pointer promise) = 0; + virtual messenger::ChannelId getId() = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Bluetooth/IBluetoothServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/Bluetooth/IBluetoothServiceChannelEventHandler.hpp new file mode 100644 index 0000000..207042f --- /dev/null +++ b/include/f1x/aasdk/Channel/Bluetooth/IBluetoothServiceChannelEventHandler.hpp @@ -0,0 +1,50 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace bluetooth +{ + +class IBluetoothServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + IBluetoothServiceChannelEventHandler() = default; + virtual ~IBluetoothServiceChannelEventHandler() = default; + + virtual void onChannelOpenRequest(const proto::messages::ChannelOpenRequest& request) = 0; + virtual void onBluetoothPairingRequest(const proto::messages::BluetoothPairingRequest& request) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Control/ControlServiceChannel.hpp b/include/f1x/aasdk/Channel/Control/ControlServiceChannel.hpp new file mode 100644 index 0000000..4a239a3 --- /dev/null +++ b/include/f1x/aasdk/Channel/Control/ControlServiceChannel.hpp @@ -0,0 +1,66 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace control +{ + +class ControlServiceChannel: public IControlServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ +public: + ControlServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); + + void receive(IControlServiceChannelEventHandler::Pointer eventHandler) override; + + void sendVersionRequest(SendPromise::Pointer promise) override; + void sendHandshake(common::Data handshakeBuffer, SendPromise::Pointer promise) override; + void sendAuthComplete(const proto::messages::AuthCompleteIndication& response, SendPromise::Pointer promise) override; + void sendServiceDiscoveryResponse(const proto::messages::ServiceDiscoveryResponse& response, SendPromise::Pointer promise) override; + void sendAudioFocusResponse(const proto::messages::AudioFocusResponse& response, SendPromise::Pointer promise) override; + void sendShutdownRequest(const proto::messages::ShutdownRequest& request, SendPromise::Pointer promise) override; + void sendShutdownResponse(const proto::messages::ShutdownResponse& response, SendPromise::Pointer promise) override; + void sendNavigationFocusResponse(const proto::messages::NavigationFocusResponse& respons, SendPromise::Pointer promisee) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, IControlServiceChannelEventHandler::Pointer eventHandler); + + void handleVersionResponse(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler); + void handleServiceDiscoveryRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler); + void handleAudioFocusRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler); + void handleShutdownRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler); + void handleShutdownResponse(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler); + void handleNavigationFocusRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Control/IControlServiceChannel.hpp b/include/f1x/aasdk/Channel/Control/IControlServiceChannel.hpp new file mode 100644 index 0000000..5abcbcd --- /dev/null +++ b/include/f1x/aasdk/Channel/Control/IControlServiceChannel.hpp @@ -0,0 +1,64 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace control +{ + +class IControlServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + IControlServiceChannel() = default; + virtual ~IControlServiceChannel() = default; + + virtual void receive(IControlServiceChannelEventHandler::Pointer eventHandler) = 0; + + virtual void sendVersionRequest(SendPromise::Pointer promise) = 0; + virtual void sendHandshake(common::Data handshakeBuffer, SendPromise::Pointer promise) = 0; + virtual void sendAuthComplete(const proto::messages::AuthCompleteIndication& response, SendPromise::Pointer promise) = 0; + virtual void sendServiceDiscoveryResponse(const proto::messages::ServiceDiscoveryResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendAudioFocusResponse(const proto::messages::AudioFocusResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendShutdownRequest(const proto::messages::ShutdownRequest& request, SendPromise::Pointer promise) = 0; + virtual void sendShutdownResponse(const proto::messages::ShutdownResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendNavigationFocusResponse(const proto::messages::NavigationFocusResponse& response, SendPromise::Pointer promise) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Control/IControlServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/Control/IControlServiceChannelEventHandler.hpp new file mode 100644 index 0000000..dddf605 --- /dev/null +++ b/include/f1x/aasdk/Channel/Control/IControlServiceChannelEventHandler.hpp @@ -0,0 +1,60 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace control +{ + +class IControlServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + IControlServiceChannelEventHandler() = default; + virtual ~IControlServiceChannelEventHandler() = default; + + virtual void onVersionResponse(uint16_t majorCode, uint16_t minorCode, proto::enums::VersionResponseStatus::Enum status) = 0; + virtual void onHandshake(const common::DataConstBuffer& payload) = 0; + virtual void onServiceDiscoveryRequest(const proto::messages::ServiceDiscoveryRequest& request) = 0; + virtual void onAudioFocusRequest(const proto::messages::AudioFocusRequest& request) = 0; + virtual void onShutdownRequest(const proto::messages::ShutdownRequest& request) = 0; + virtual void onShutdownResponse(const proto::messages::ShutdownResponse& response) = 0; + virtual void onNavigationFocusRequest(const proto::messages::NavigationFocusRequest& request) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Input/IInputServiceChannel.hpp b/include/f1x/aasdk/Channel/Input/IInputServiceChannel.hpp new file mode 100644 index 0000000..0d13cc2 --- /dev/null +++ b/include/f1x/aasdk/Channel/Input/IInputServiceChannel.hpp @@ -0,0 +1,57 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace input +{ + +class IInputServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + IInputServiceChannel() = default; + virtual ~IInputServiceChannel() = default; + + virtual void receive(IInputServiceChannelEventHandler::Pointer eventHandler) = 0; + virtual void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendInputEventIndication(const proto::messages::InputEventIndication& indication, SendPromise::Pointer promise) = 0; + virtual void sendBindingResponse(const proto::messages::BindingResponse& response, SendPromise::Pointer promise) = 0; + virtual messenger::ChannelId getId() = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Input/IInputServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/Input/IInputServiceChannelEventHandler.hpp new file mode 100644 index 0000000..acb1ecf --- /dev/null +++ b/include/f1x/aasdk/Channel/Input/IInputServiceChannelEventHandler.hpp @@ -0,0 +1,50 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace input +{ + +class IInputServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + IInputServiceChannelEventHandler() = default; + virtual ~IInputServiceChannelEventHandler() = default; + + virtual void onChannelOpenRequest(const proto::messages::ChannelOpenRequest& request) = 0; + virtual void onBindingRequest(const proto::messages::BindingRequest& request) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Input/InputServiceChannel.hpp b/include/f1x/aasdk/Channel/Input/InputServiceChannel.hpp new file mode 100644 index 0000000..42bfef3 --- /dev/null +++ b/include/f1x/aasdk/Channel/Input/InputServiceChannel.hpp @@ -0,0 +1,54 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace input +{ + +class InputServiceChannel: public IInputServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ + public: + InputServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); + + void receive(IInputServiceChannelEventHandler::Pointer eventHandler) override; + void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) override; + void sendInputEventIndication(const proto::messages::InputEventIndication& indication, SendPromise::Pointer promise) override; + void sendBindingResponse(const proto::messages::BindingResponse& response, SendPromise::Pointer promise) override; + messenger::ChannelId getId() override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, IInputServiceChannelEventHandler::Pointer eventHandler); + void handleBindingRequest(const common::DataConstBuffer& payload, IInputServiceChannelEventHandler::Pointer eventHandler); + void handleChannelOpenRequest(const common::DataConstBuffer& payload, IInputServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Promise.hpp b/include/f1x/aasdk/Channel/Promise.hpp new file mode 100644 index 0000000..ce8a07a --- /dev/null +++ b/include/f1x/aasdk/Channel/Promise.hpp @@ -0,0 +1,35 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ + +typedef io::Promise SendPromise; + +} +} +} diff --git a/include/f1x/aasdk/Channel/Sensor/ISensorServiceChannel.hpp b/include/f1x/aasdk/Channel/Sensor/ISensorServiceChannel.hpp new file mode 100644 index 0000000..66400ee --- /dev/null +++ b/include/f1x/aasdk/Channel/Sensor/ISensorServiceChannel.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace sensor +{ + +class ISensorServiceChannel +{ +public: + typedef std::shared_ptr Pointer; + + ISensorServiceChannel() = default; + virtual ~ISensorServiceChannel() = default; + + virtual void receive(ISensorServiceChannelEventHandler::Pointer eventHandler) = 0; + virtual messenger::ChannelId getId() = 0; + virtual void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) = 0; + virtual void sendSensorEventIndication(const proto::messages::SensorEventIndication& indication, SendPromise::Pointer promise) = 0; + virtual void sendSensorStartResponse(const proto::messages::SensorStartResponseMessage& response, SendPromise::Pointer promise) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Sensor/ISensorServiceChannelEventHandler.hpp b/include/f1x/aasdk/Channel/Sensor/ISensorServiceChannelEventHandler.hpp new file mode 100644 index 0000000..4719ed3 --- /dev/null +++ b/include/f1x/aasdk/Channel/Sensor/ISensorServiceChannelEventHandler.hpp @@ -0,0 +1,50 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace sensor +{ + +class ISensorServiceChannelEventHandler +{ +public: + typedef std::shared_ptr Pointer; + + ISensorServiceChannelEventHandler() = default; + virtual ~ISensorServiceChannelEventHandler() = default; + + virtual void onChannelOpenRequest(const proto::messages::ChannelOpenRequest& request) = 0; + virtual void onSensorStartRequest(const proto::messages::SensorStartRequestMessage& request) = 0; + virtual void onChannelError(const error::Error& e) = 0; +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/Sensor/SensorServiceChannel.hpp b/include/f1x/aasdk/Channel/Sensor/SensorServiceChannel.hpp new file mode 100644 index 0000000..3cdd30b --- /dev/null +++ b/include/f1x/aasdk/Channel/Sensor/SensorServiceChannel.hpp @@ -0,0 +1,54 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace sensor +{ + +class SensorServiceChannel: public ISensorServiceChannel, public ServiceChannel, public std::enable_shared_from_this +{ +public: + SensorServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger); + + void receive(ISensorServiceChannelEventHandler::Pointer eventHandler) override; + messenger::ChannelId getId() override; + void sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) override; + void sendSensorEventIndication(const proto::messages::SensorEventIndication& indication, SendPromise::Pointer promise) override; + void sendSensorStartResponse(const proto::messages::SensorStartResponseMessage& response, SendPromise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void messageHandler(messenger::Message::Pointer message, ISensorServiceChannelEventHandler::Pointer eventHandler); + void handleSensorStartRequest(const common::DataConstBuffer& payload, ISensorServiceChannelEventHandler::Pointer eventHandler); + void handleChannelOpenRequest(const common::DataConstBuffer& payload, ISensorServiceChannelEventHandler::Pointer eventHandler); +}; + +} +} +} +} diff --git a/include/f1x/aasdk/Channel/ServiceChannel.hpp b/include/f1x/aasdk/Channel/ServiceChannel.hpp new file mode 100644 index 0000000..c15ea68 --- /dev/null +++ b/include/f1x/aasdk/Channel/ServiceChannel.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ + +class ServiceChannel +{ +protected: + ServiceChannel(boost::asio::io_service::strand& strand, + messenger::IMessenger::Pointer messenger, + messenger::ChannelId channelId); + + virtual ~ServiceChannel() = default; + void send(messenger::Message::Pointer message, SendPromise::Pointer promise); + + boost::asio::io_service::strand& strand_; + messenger::IMessenger::Pointer messenger_; + messenger::ChannelId channelId_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Common/Data.hpp b/include/f1x/aasdk/Common/Data.hpp new file mode 100644 index 0000000..70d3917 --- /dev/null +++ b/include/f1x/aasdk/Common/Data.hpp @@ -0,0 +1,85 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace common +{ + +typedef std::vector Data; + +static constexpr size_t cStaticDataSize = 30 * 1024 * 1024; + +struct DataBuffer +{ + DataBuffer(); + DataBuffer(Data::value_type* _data, Data::size_type _size, Data::size_type offset = 0); + DataBuffer(void* _data, Data::size_type _size, Data::size_type offset = 0); + explicit DataBuffer(Data& _data, Data::size_type offset = 0); + bool operator==(const std::nullptr_t&) const; + + Data::value_type* data; + Data::size_type size; +}; + +struct DataConstBuffer +{ + DataConstBuffer(); + explicit DataConstBuffer(const DataBuffer& other); + DataConstBuffer(const Data::value_type* _data, Data::size_type _size, Data::size_type offset = 0); + DataConstBuffer(const void* _data, Data::size_type _size, Data::size_type offset = 0); + explicit DataConstBuffer(const Data& _data, Data::size_type offset = 0); + bool operator==(const std::nullptr_t&) const; + + const Data::value_type* cdata; + Data::size_type size; +}; + +template +void copy(DataType& data, const DataBuffer& buffer) +{ + size_t offset = data.size(); + data.resize(data.size() + buffer.size); + memcpy(&data[offset], buffer.data, buffer.size); +} + +template +void copy(DataType& data, const DataConstBuffer& buffer) +{ + size_t offset = data.size(); + data.resize(data.size() + buffer.size); + memcpy(&data[offset], buffer.cdata, buffer.size); +} + +common::Data createData(const DataConstBuffer& buffer); + +std::string dump(const Data& data); +std::string dump(const DataConstBuffer& buffer); + +} +} +} diff --git a/include/f1x/aasdk/Common/Log.hpp b/include/f1x/aasdk/Common/Log.hpp new file mode 100644 index 0000000..6a7197f --- /dev/null +++ b/include/f1x/aasdk/Common/Log.hpp @@ -0,0 +1,23 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +#define AASDK_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[AaSdk] " diff --git a/include/f1x/aasdk/Error/Error.hpp b/include/f1x/aasdk/Error/Error.hpp new file mode 100644 index 0000000..fb14d52 --- /dev/null +++ b/include/f1x/aasdk/Error/Error.hpp @@ -0,0 +1,52 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace error +{ + +class Error: public std::exception +{ +public: + Error(); + Error(ErrorCode code, uint32_t nativeCode = 0); + + ErrorCode getCode() const; + uint32_t getNativeCode() const; + const char* what() const noexcept override; + + bool operator!() const; + bool operator==(const Error& other) const; + +private: + ErrorCode code_; + uint32_t nativeCode_; + std::string message_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Error/ErrorCode.hpp b/include/f1x/aasdk/Error/ErrorCode.hpp new file mode 100644 index 0000000..7f3be33 --- /dev/null +++ b/include/f1x/aasdk/Error/ErrorCode.hpp @@ -0,0 +1,70 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace error +{ + +enum class ErrorCode +{ + NONE, + USB_CLAIM_INTERFACE, + USB_INVALID_CONFIG_DESCRIPTOR, + USB_OBTAIN_INTERFACE_DESCRIPTOR, + USB_EMPTY_INTERFACES, + USB_INVALID_DEVICE_ENDPOINTS, + USB_INVALID_TRANSFER_METHOD, + USB_TRANSFER_ALLOCATION, + USB_LIST_DEVICES, + USB_OBTAIN_CONFIG_DESCRIPTOR, + USB_TRANSFER, + USB_SINK_COMMIT_OVERFLOW, + USB_SINK_CONSUME_UNDERFLOW, + USB_AOAP_PROTOCOL_VERSION, + USB_EMPTY_DEVICE_LIST, + USB_AOAP_DEVICE_NOT_FOUND, + SSL_READ_CERTIFICATE, + SSL_READ_PRIVATE_KEY, + SSL_METHOD, + SSL_CONTEXT_CREATION, + SSL_USE_CERTIFICATE, + SSL_USE_PRIVATE_KEY, + SSL_HANDLER_CREATION, + SSL_READ_BIO_CREATION, + SSL_WRITE_BIO_CREATION, + SSL_HANDSHAKE, + SSL_WRITE, + SSL_READ, + SSL_BIO_READ, + SSL_BIO_WRITE, + MESSENGER_INTERTWINED_CHANNELS, + OPERATION_ABORTED, + OPERATION_IN_PROGRESS, + PARSE_PAYLOAD +}; + +} +} +} diff --git a/include/f1x/aasdk/IO/IOContextWrapper.hpp b/include/f1x/aasdk/IO/IOContextWrapper.hpp new file mode 100644 index 0000000..2478f90 --- /dev/null +++ b/include/f1x/aasdk/IO/IOContextWrapper.hpp @@ -0,0 +1,76 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace io +{ + +class IOContextWrapper: boost::noncopyable +{ +public: + typedef std::shared_ptr Pointer; + + IOContextWrapper(); + explicit IOContextWrapper(boost::asio::io_service& ioService); + explicit IOContextWrapper(boost::asio::io_service::strand& strand); + + template + void post(CompletionHandlerType&& handler) + { + if(ioService_ != nullptr) + { + ioService_->post(std::move(handler)); + } + else if(strand_ != nullptr) + { + strand_->post(std::move(handler)); + } + } + + template + void dispatch(CompletionHandlerType&& handler) + { + if(ioService_ != nullptr) + { + ioService_->dispatch(std::move(handler)); + } + else if(strand_ != nullptr) + { + strand_->dispatch(std::move(handler)); + } + } + + void reset(); + bool isActive() const; + +private: + boost::asio::io_service* ioService_; + boost::asio::io_service::strand* strand_; +}; + +} +} +} diff --git a/include/f1x/aasdk/IO/Promise.hpp b/include/f1x/aasdk/IO/Promise.hpp new file mode 100644 index 0000000..0775641 --- /dev/null +++ b/include/f1x/aasdk/IO/Promise.hpp @@ -0,0 +1,368 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace io +{ + +template +class Promise: boost::noncopyable +{ +public: + typedef ResolveArgumentType ValueType; + typedef ErrorArgumentType ErrorType; + typedef std::function ResolveHandler; + typedef std::function RejectHandler; + typedef std::shared_ptr Pointer; + + static Pointer defer(boost::asio::io_service& ioService) + { + return std::make_shared(ioService); + } + + static Pointer defer(boost::asio::io_service::strand& strand) + { + return std::make_shared(strand); + } + + Promise(boost::asio::io_service& ioService) + : ioContextWrapper_(std::make_shared(ioService)) + { + + } + + Promise(boost::asio::io_service::strand& strand) + : ioContextWrapper_(std::make_shared(strand)) + { + + } + + void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) + { + std::lock_guard lock(mutex_); + + resolveHandler_ = std::make_shared(std::move(resolveHandler)); + rejectHandler_ = rejectHandler == nullptr ? nullptr : std::make_shared(std::move(rejectHandler)); + } + + void resolve(ResolveArgumentType argument) + { + std::lock_guard lock(mutex_); + + if(resolveHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([argument = std::move(argument), resolveHandler = std::move(resolveHandler_)]() mutable { + (*resolveHandler)(std::move(argument)); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + rejectHandler_.reset(); + } + + void reject(ErrorArgumentType error) + { + std::lock_guard lock(mutex_); + + if(rejectHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([error = std::move(error), rejectHandler = std::move(rejectHandler_)]() mutable { + (*rejectHandler)(std::move(error)); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + resolveHandler_.reset(); + } + +private: + bool isPending() const + { + return ioContextWrapper_ != nullptr && ioContextWrapper_->isActive(); + } + + std::shared_ptr resolveHandler_; + std::shared_ptr rejectHandler_; + IOContextWrapper::Pointer ioContextWrapper_; + std::mutex mutex_; +}; + +template +class Promise: boost::noncopyable +{ +public: + typedef ErrorArgumentType ErrorType; + typedef std::function ResolveHandler; + typedef std::function RejectHandler; + typedef std::shared_ptr Pointer; + + static Pointer defer(boost::asio::io_service& ioService) + { + return std::make_shared(ioService); + } + + static Pointer defer(boost::asio::io_service::strand& strand) + { + return std::make_shared(strand); + } + + Promise(boost::asio::io_service& ioService) + : ioContextWrapper_(std::make_shared(ioService)) + { + + } + + Promise(boost::asio::io_service::strand& strand) + : ioContextWrapper_(std::make_shared(strand)) + { + + } + + void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) + { + std::lock_guard lock(mutex_); + + resolveHandler_ = std::make_shared(std::move(resolveHandler)); + rejectHandler_ = rejectHandler == nullptr ? nullptr : std::make_shared(std::move(rejectHandler)); + } + + void resolve() + { + std::lock_guard lock(mutex_); + + if(resolveHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([resolveHandler = std::move(resolveHandler_)]() mutable { + (*resolveHandler)(); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + rejectHandler_.reset(); + } + + void reject(ErrorArgumentType error) + { + std::lock_guard lock(mutex_); + + if(rejectHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([error = std::move(error), rejectHandler = std::move(rejectHandler_)]() mutable { + (*rejectHandler)(std::move(error)); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + resolveHandler_.reset(); + } + +private: + bool isPending() const + { + return ioContextWrapper_ != nullptr && ioContextWrapper_->isActive(); + } + + std::shared_ptr resolveHandler_; + std::shared_ptr rejectHandler_; + IOContextWrapper::Pointer ioContextWrapper_; + std::mutex mutex_; +}; + +template<> +class Promise: boost::noncopyable +{ +public: + typedef std::function ResolveHandler; + typedef std::function RejectHandler; + typedef std::shared_ptr Pointer; + + static Pointer defer(boost::asio::io_service& ioService) + { + return std::make_shared(ioService); + } + + static Pointer defer(boost::asio::io_service::strand& strand) + { + return std::make_shared(strand); + } + + Promise(boost::asio::io_service& ioService) + : ioContextWrapper_(std::make_shared(ioService)) + { + + } + + Promise(boost::asio::io_service::strand& strand) + : ioContextWrapper_(std::make_shared(strand)) + { + + } + + void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) + { + std::lock_guard lock(mutex_); + + resolveHandler_ = std::make_shared(std::move(resolveHandler)); + rejectHandler_ = rejectHandler == nullptr ? nullptr : std::make_shared(std::move(rejectHandler)); + } + + void resolve() + { + std::lock_guard lock(mutex_); + + if(resolveHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([resolveHandler = std::move(resolveHandler_)]() mutable { + (*resolveHandler)(); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + rejectHandler_.reset(); + } + + void reject() + { + std::lock_guard lock(mutex_); + + if(rejectHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([rejectHandler = std::move(rejectHandler_)]() mutable { + (*rejectHandler)(); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + resolveHandler_.reset(); + } + +private: + bool isPending() const + { + return ioContextWrapper_ != nullptr && ioContextWrapper_->isActive(); + } + + std::shared_ptr resolveHandler_; + std::shared_ptr rejectHandler_; + IOContextWrapper::Pointer ioContextWrapper_; + std::mutex mutex_; +}; + +template +class Promise: boost::noncopyable +{ +public: + typedef ResolveArgumentType ValueType; + typedef std::function ResolveHandler; + typedef std::function RejectHandler; + typedef std::shared_ptr Pointer; + + static Pointer defer(boost::asio::io_service& ioService) + { + return std::make_shared(ioService); + } + + static Pointer defer(boost::asio::io_service::strand& strand) + { + return std::make_shared(strand); + } + + Promise(boost::asio::io_service& ioService) + : ioContextWrapper_(std::make_shared(ioService)) + { + + } + + Promise(boost::asio::io_service::strand& strand) + : ioContextWrapper_(std::make_shared(strand)) + { + + } + + void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) + { + std::lock_guard lock(mutex_); + + resolveHandler_ = std::make_shared(std::move(resolveHandler)); + rejectHandler_ = rejectHandler == nullptr ? nullptr : std::make_shared(std::move(rejectHandler)); + } + + void resolve(ResolveArgumentType argument) + { + std::lock_guard lock(mutex_); + + if(resolveHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([argument = std::move(argument), resolveHandler = std::move(resolveHandler_)]() mutable { + (*resolveHandler)(std::move(argument)); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + rejectHandler_.reset(); + } + + void reject() + { + std::lock_guard lock(mutex_); + + if(rejectHandler_ != nullptr && this->isPending()) + { + ioContextWrapper_->post([rejectHandler = std::move(rejectHandler_)]() mutable { + (*rejectHandler)(); + }); + } + + ioContextWrapper_->reset(); + ioContextWrapper_.reset(); + resolveHandler_.reset(); + } + +private: + bool isPending() const + { + return ioContextWrapper_ != nullptr && ioContextWrapper_->isActive(); + } + + std::shared_ptr resolveHandler_; + std::shared_ptr rejectHandler_; + IOContextWrapper::Pointer ioContextWrapper_; + std::mutex mutex_; +}; + + +} +} +} diff --git a/include/f1x/aasdk/IO/PromiseLink.hpp b/include/f1x/aasdk/IO/PromiseLink.hpp new file mode 100644 index 0000000..64ed03b --- /dev/null +++ b/include/f1x/aasdk/IO/PromiseLink.hpp @@ -0,0 +1,132 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace io +{ + +template +class PromiseLink: public std::enable_shared_from_this> +{ +public: + typedef std::shared_ptr> Pointer; + typedef std::function TransformFunctor; + + PromiseLink(typename Promise::Pointer promise, TransformFunctor transformFunctor) + : promise_(std::move(promise)) + , transformFunctor_(std::make_shared(std::move(transformFunctor))) + { + + } + + static void forward(Promise& source, typename Promise::Pointer destination, + TransformFunctor transformFunctor = [](SourceResolveArgumentType&& argument) { return std::move(argument); }) + { + auto link = std::make_shared>(std::forward::Pointer>(destination), + std::forward(transformFunctor)); + source.then(link->getResolveHandler(), link->getRejectHandler()); + } + +private: + using std::enable_shared_from_this>::shared_from_this; + + void resolve(SourceResolveArgumentType argument) + { + if(transformFunctor_ != nullptr) + { + promise_->resolve((*transformFunctor_)(std::move(argument))); + transformFunctor_.reset(); + } + } + + void reject(const error::Error& e) + { + promise_->reject(e); + } + + typename Promise::ResolveHandler getResolveHandler() + { + return std::bind(&PromiseLink::resolve, this->shared_from_this(), std::placeholders::_1); + } + + typename Promise::RejectHandler getRejectHandler() + { + return std::bind(&PromiseLink::reject, this->shared_from_this(), std::placeholders::_1); + } + + typename Promise::Pointer promise_; + std::shared_ptr transformFunctor_; +}; + +template<> +class PromiseLink: public std::enable_shared_from_this> +{ +public: + typedef std::shared_ptr> Pointer; + + PromiseLink(typename Promise::Pointer promise) + : promise_(std::move(promise)) + { + + } + + static void forward(Promise& source, typename Promise::Pointer destination) + { + auto link = std::make_shared>(std::forward::Pointer>(destination)); + source.then(link->getResolveHandler(), link->getRejectHandler()); + } + +private: + using std::enable_shared_from_this>::shared_from_this; + + void resolve() + { + promise_->resolve(); + } + + void reject(const error::Error& e) + { + promise_->reject(e); + } + + Promise::ResolveHandler getResolveHandler() + { + return std::bind(&PromiseLink::resolve, this->shared_from_this()); + } + + Promise::RejectHandler getRejectHandler() + { + return std::bind(&PromiseLink::reject, this->shared_from_this(), std::placeholders::_1); + } + + typename Promise::Pointer promise_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/ChannelId.hpp b/include/f1x/aasdk/Messenger/ChannelId.hpp new file mode 100644 index 0000000..c8fba5c --- /dev/null +++ b/include/f1x/aasdk/Messenger/ChannelId.hpp @@ -0,0 +1,48 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +enum class ChannelId +{ + CONTROL, + INPUT, + SENSOR, + VIDEO, + MEDIA_AUDIO, + SPEECH_AUDIO, + SYSTEM_AUDIO, + AV_INPUT, + BLUETOOTH, + NONE = 255 +}; + +std::string channelIdToString(ChannelId channelId); + +} +} +} diff --git a/include/f1x/aasdk/Messenger/ChannelReceiveMessageQueue.hpp b/include/f1x/aasdk/Messenger/ChannelReceiveMessageQueue.hpp new file mode 100644 index 0000000..a0d0ecb --- /dev/null +++ b/include/f1x/aasdk/Messenger/ChannelReceiveMessageQueue.hpp @@ -0,0 +1,48 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class ChannelReceiveMessageQueue +{ +public: + void push(Message::Pointer message); + Message::Pointer pop(ChannelId channelId); + bool empty(ChannelId channelId) const; + void clear(); + +private: + typedef std::queue MessageQueue; + std::unordered_map queue_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/ChannelReceivePromiseQueue.hpp b/include/f1x/aasdk/Messenger/ChannelReceivePromiseQueue.hpp new file mode 100644 index 0000000..74d3d5e --- /dev/null +++ b/include/f1x/aasdk/Messenger/ChannelReceivePromiseQueue.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class ChannelReceivePromiseQueue +{ +public: + void push(ChannelId channelId, ReceivePromise::Pointer promise); + ReceivePromise::Pointer pop(ChannelId channelId); + bool isPending(ChannelId channelId) const; + size_t size() const; + bool empty() const; + void clear(); + ReceivePromise::Pointer pop(); + +private: + std::unordered_map> queue_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/Cryptor.hpp b/include/f1x/aasdk/Messenger/Cryptor.hpp new file mode 100644 index 0000000..3cbf0f5 --- /dev/null +++ b/include/f1x/aasdk/Messenger/Cryptor.hpp @@ -0,0 +1,67 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class Cryptor: public ICryptor +{ +public: + Cryptor(transport::ISSLWrapper::Pointer sslWrapper); + + void init() override; + void deinit() override; + bool doHandshake() override; + size_t encrypt(common::Data& output, const common::DataConstBuffer& buffer) override; + size_t decrypt(common::Data& output, const common::DataConstBuffer& buffer) override; + + common::Data readHandshakeBuffer() override; + void writeHandshakeBuffer(const common::DataConstBuffer& buffer) override; + bool isActive() const override; + +private: + size_t read(common::Data& output); + void write(const common::DataConstBuffer& buffer); + + transport::ISSLWrapper::Pointer sslWrapper_; + size_t maxBufferSize_; + X509* certificate_; + EVP_PKEY* privateKey_; + SSL_CTX* context_; + SSL* ssl_; + transport::ISSLWrapper::BIOs bIOs_; + bool isActive_; + + const static std::string cCertificate; + const static std::string cPrivateKey; + mutable std::mutex mutex_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/EncryptionType.hpp b/include/f1x/aasdk/Messenger/EncryptionType.hpp new file mode 100644 index 0000000..6c99c9b --- /dev/null +++ b/include/f1x/aasdk/Messenger/EncryptionType.hpp @@ -0,0 +1,36 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +enum class EncryptionType +{ + PLAIN, + ENCRYPTED = 1 << 3 +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/FrameHeader.hpp b/include/f1x/aasdk/Messenger/FrameHeader.hpp new file mode 100644 index 0000000..2e1aaac --- /dev/null +++ b/include/f1x/aasdk/Messenger/FrameHeader.hpp @@ -0,0 +1,57 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class FrameHeader +{ +public: + FrameHeader(const common::DataConstBuffer& buffer); + FrameHeader(ChannelId channelId, FrameType frameType, EncryptionType encryptionType, MessageType messageType); + + ChannelId getChannelId() const; + FrameType getType() const; + EncryptionType getEncryptionType() const; + MessageType getMessageType() const; + common::Data getData() const; + + static constexpr size_t getSizeOf() { return 2; } + +private: + ChannelId channelId_; + FrameType frameType_; + EncryptionType encryptionType_; + MessageType messageType_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/FrameSize.hpp b/include/f1x/aasdk/Messenger/FrameSize.hpp new file mode 100644 index 0000000..affa1fb --- /dev/null +++ b/include/f1x/aasdk/Messenger/FrameSize.hpp @@ -0,0 +1,51 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class FrameSize +{ +public: + FrameSize(size_t frameSize, size_t totalSize); + FrameSize(size_t frameSize); + FrameSize(const common::DataConstBuffer& buffer); + + common::Data getData() const; + size_t getSize() const; + + static size_t getSizeOf(FrameSizeType type); + +private: + FrameSizeType frameSizeType_; + size_t frameSize_; + size_t totalSize_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/FrameSizeType.hpp b/include/f1x/aasdk/Messenger/FrameSizeType.hpp new file mode 100644 index 0000000..1a0d85f --- /dev/null +++ b/include/f1x/aasdk/Messenger/FrameSizeType.hpp @@ -0,0 +1,36 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +enum class FrameSizeType +{ + SHORT, + EXTENDED +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/FrameType.hpp b/include/f1x/aasdk/Messenger/FrameType.hpp new file mode 100644 index 0000000..fba5777 --- /dev/null +++ b/include/f1x/aasdk/Messenger/FrameType.hpp @@ -0,0 +1,40 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +enum class FrameType +{ + MIDDLE = 0, + FIRST = 1 << 0, + LAST = 1 << 1, + BULK = FIRST | LAST +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/ICryptor.hpp b/include/f1x/aasdk/Messenger/ICryptor.hpp new file mode 100644 index 0000000..fc60946 --- /dev/null +++ b/include/f1x/aasdk/Messenger/ICryptor.hpp @@ -0,0 +1,51 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class ICryptor +{ +public: + typedef std::shared_ptr Pointer; + + ICryptor() = default; + virtual ~ICryptor() = default; + + virtual void init() = 0; + virtual void deinit() = 0; + virtual bool doHandshake() = 0; + virtual size_t encrypt(common::Data& output, const common::DataConstBuffer& buffer) = 0; + virtual size_t decrypt(common::Data& output, const common::DataConstBuffer& buffer) = 0; + virtual common::Data readHandshakeBuffer() = 0; + virtual void writeHandshakeBuffer(const common::DataConstBuffer& buffer) = 0; + virtual bool isActive() const = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/IMessageInStream.hpp b/include/f1x/aasdk/Messenger/IMessageInStream.hpp new file mode 100644 index 0000000..dc49c05 --- /dev/null +++ b/include/f1x/aasdk/Messenger/IMessageInStream.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class IMessageInStream +{ +public: + typedef std::shared_ptr Pointer; + + IMessageInStream() = default; + virtual ~IMessageInStream() = default; + + virtual void startReceive(ReceivePromise::Pointer promise) = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/IMessageOutStream.hpp b/include/f1x/aasdk/Messenger/IMessageOutStream.hpp new file mode 100644 index 0000000..88813a7 --- /dev/null +++ b/include/f1x/aasdk/Messenger/IMessageOutStream.hpp @@ -0,0 +1,45 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class IMessageOutStream +{ +public: + typedef std::shared_ptr Pointer; + + IMessageOutStream() = default; + virtual ~IMessageOutStream() = default; + + virtual void stream(Message::Pointer message, SendPromise::Pointer promise) = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/IMessenger.hpp b/include/f1x/aasdk/Messenger/IMessenger.hpp new file mode 100644 index 0000000..856e2bd --- /dev/null +++ b/include/f1x/aasdk/Messenger/IMessenger.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class IMessenger +{ +public: + IMessenger() = default; + virtual ~IMessenger() = default; + + typedef std::shared_ptr Pointer; + + virtual void enqueueReceive(ChannelId channelId, ReceivePromise::Pointer promise) = 0; + virtual void enqueueSend(Message::Pointer message, SendPromise::Pointer promise) = 0; + virtual void stop() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/Message.hpp b/include/f1x/aasdk/Messenger/Message.hpp new file mode 100644 index 0000000..55a2de5 --- /dev/null +++ b/include/f1x/aasdk/Messenger/Message.hpp @@ -0,0 +1,66 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class Message: boost::noncopyable +{ +public: + typedef std::shared_ptr Pointer; + + Message(ChannelId channelId, EncryptionType encryptionType, MessageType type); + Message(Message&& other); + Message& operator=(Message&& other); + + ChannelId getChannelId() const; + EncryptionType getEncryptionType() const; + MessageType getType() const; + + common::Data& getPayload(); + const common::Data& getPayload() const; + void insertPayload(const common::Data& payload); + void insertPayload(const google::protobuf::Message& message); + void insertPayload(const common::DataConstBuffer& buffer); + void insertPayload(common::DataBuffer& buffer); + +private: + ChannelId channelId_; + EncryptionType encryptionType_; + MessageType type_; + common::Data payload_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/MessageId.hpp b/include/f1x/aasdk/Messenger/MessageId.hpp new file mode 100644 index 0000000..b61ccda --- /dev/null +++ b/include/f1x/aasdk/Messenger/MessageId.hpp @@ -0,0 +1,55 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class MessageId +{ +public: + MessageId(uint16_t id); + MessageId(const common::Data& data); + + common::Data getData() const; + static constexpr size_t getSizeOf() { return 2; } + uint16_t getId() const; + + bool operator>(uint16_t id) const; + bool operator<(uint16_t id) const; + bool operator==(uint16_t id) const; + bool operator>=(uint16_t id) const; + bool operator<=(uint16_t id) const; + MessageId& operator=(uint16_t id); + +private: + uint16_t id_; +}; + +std::ostream& operator<<(std::ostream& stream, const f1x::aasdk::messenger::MessageId& messageId); + +} +} +} diff --git a/include/f1x/aasdk/Messenger/MessageInStream.hpp b/include/f1x/aasdk/Messenger/MessageInStream.hpp new file mode 100644 index 0000000..262c3f5 --- /dev/null +++ b/include/f1x/aasdk/Messenger/MessageInStream.hpp @@ -0,0 +1,58 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class MessageInStream: public IMessageInStream, public std::enable_shared_from_this, boost::noncopyable +{ +public: + MessageInStream(boost::asio::io_service& ioService, transport::ITransport::Pointer transport, ICryptor::Pointer cryptor); + + void startReceive(ReceivePromise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + + void receiveFrameHeaderHandler(const common::DataConstBuffer& buffer); + void receiveFrameSizeHandler(const common::DataConstBuffer& buffer); + void receiveFramePayloadHandler(const common::DataConstBuffer& buffer); + + boost::asio::io_service::strand strand_; + transport::ITransport::Pointer transport_; + ICryptor::Pointer cryptor_; + FrameType recentFrameType_; + ReceivePromise::Pointer promise_; + Message::Pointer message_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/MessageOutStream.hpp b/include/f1x/aasdk/Messenger/MessageOutStream.hpp new file mode 100644 index 0000000..028839a --- /dev/null +++ b/include/f1x/aasdk/Messenger/MessageOutStream.hpp @@ -0,0 +1,65 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class MessageOutStream: public IMessageOutStream, public std::enable_shared_from_this, boost::noncopyable +{ +public: + MessageOutStream(boost::asio::io_service& ioService, transport::ITransport::Pointer transport, ICryptor::Pointer cryptor); + + void stream(Message::Pointer message, SendPromise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + + void streamSplittedMessage(); + common::Data compoundFrame(FrameType frameType, const common::DataConstBuffer& payloadBuffer); + void streamEncryptedFrame(FrameType frameType, const common::DataConstBuffer& payloadBuffer); + void streamPlainFrame(FrameType frameType, const common::DataConstBuffer& payloadBuffer); + void setFrameSize(common::Data& data, FrameType frameType, size_t payloadSize, size_t totalSize); + void reset(); + + boost::asio::io_service::strand strand_; + transport::ITransport::Pointer transport_; + ICryptor::Pointer cryptor_; + Message::Pointer message_; + size_t offset_; + size_t remainingSize_; + SendPromise::Pointer promise_; + + static constexpr size_t cMaxFramePayloadSize = 0x4000; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/MessageType.hpp b/include/f1x/aasdk/Messenger/MessageType.hpp new file mode 100644 index 0000000..76d5842 --- /dev/null +++ b/include/f1x/aasdk/Messenger/MessageType.hpp @@ -0,0 +1,40 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +enum class MessageType +{ + SPECIFIC = 0, + CONTROL = 1 << 2 +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/Messenger.hpp b/include/f1x/aasdk/Messenger/Messenger.hpp new file mode 100644 index 0000000..f922774 --- /dev/null +++ b/include/f1x/aasdk/Messenger/Messenger.hpp @@ -0,0 +1,65 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class Messenger: public IMessenger, public std::enable_shared_from_this, boost::noncopyable +{ +public: + Messenger(boost::asio::io_service& ioService, IMessageInStream::Pointer messageInStream, IMessageOutStream::Pointer messageOutStream); + void enqueueReceive(ChannelId channelId, ReceivePromise::Pointer promise) override; + void enqueueSend(Message::Pointer message, SendPromise::Pointer promise) override; + void stop() override; + +private: + using std::enable_shared_from_this::shared_from_this; + typedef std::list> ChannelSendQueue; + void doSend(); + void inStreamMessageHandler(Message::Pointer message); + void outStreamMessageHandler(ChannelSendQueue::iterator queueElement); + void rejectReceivePromiseQueue(const error::Error& e); + void rejectSendPromiseQueue(const error::Error& e); + + boost::asio::io_service::strand receiveStrand_; + boost::asio::io_service::strand sendStrand_; + IMessageInStream::Pointer messageInStream_; + IMessageOutStream::Pointer messageOutStream_; + + ChannelReceivePromiseQueue channelReceivePromiseQueue_; + ChannelReceiveMessageQueue channelReceiveMessageQueue_; + ChannelSendQueue channelSendPromiseQueue_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/Promise.hpp b/include/f1x/aasdk/Messenger/Promise.hpp new file mode 100644 index 0000000..8afd9f2 --- /dev/null +++ b/include/f1x/aasdk/Messenger/Promise.hpp @@ -0,0 +1,36 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +typedef io::Promise ReceivePromise; +typedef io::Promise SendPromise; + +} +} +} diff --git a/include/f1x/aasdk/Messenger/Timestamp.hpp b/include/f1x/aasdk/Messenger/Timestamp.hpp new file mode 100644 index 0000000..046f40e --- /dev/null +++ b/include/f1x/aasdk/Messenger/Timestamp.hpp @@ -0,0 +1,47 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +class Timestamp +{ +public: + typedef uint64_t ValueType; + + Timestamp(ValueType stamp); + Timestamp(const common::DataConstBuffer& buffer); + + common::Data getData() const; + ValueType getValue() const; + +private: + ValueType stamp_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Transport/ISSLWrapper.hpp b/include/f1x/aasdk/Transport/ISSLWrapper.hpp new file mode 100644 index 0000000..536e124 --- /dev/null +++ b/include/f1x/aasdk/Transport/ISSLWrapper.hpp @@ -0,0 +1,70 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +class ISSLWrapper +{ +public: + typedef std::pair BIOs; + typedef std::shared_ptr Pointer; + + ISSLWrapper() = default; + virtual ~ISSLWrapper() = default; + + virtual X509* readCertificate(const std::string& certificate) = 0; + virtual EVP_PKEY* readPrivateKey(const std::string& privateKey) = 0; + virtual const SSL_METHOD* getMethod() = 0; + virtual SSL_CTX* createContext(const SSL_METHOD* method) = 0; + virtual bool useCertificate(SSL_CTX* context, X509* certificate) = 0; + virtual bool usePrivateKey(SSL_CTX* context, EVP_PKEY* privateKey) = 0; + virtual SSL* createInstance(SSL_CTX* context) = 0; + virtual bool checkPrivateKey(SSL* ssl) = 0; + virtual std::pair createBIOs() = 0; + virtual void setBIOs(SSL* ssl, const BIOs& bIOs, size_t maxBufferSize) = 0; + virtual void setConnectState(SSL* ssl) = 0; + virtual int doHandshake(SSL* ssl) = 0; + virtual void free(SSL* ssl) = 0; + virtual void free(SSL_CTX* context) = 0; + virtual void free(BIO* bio) = 0; + virtual void free(X509* certificate) = 0; + virtual void free(EVP_PKEY* privateKey) = 0; + + virtual size_t bioCtrlPending(BIO* b) = 0; + virtual int bioRead(BIO *b, void *data, int len) = 0; + virtual int bioWrite(BIO *b, const void *data, int len) = 0; + + virtual int getAvailableBytes(const SSL* ssl) = 0; + virtual int sslRead(SSL *ssl, void *buf, int num) = 0; + virtual int sslWrite(SSL *ssl, const void *buf, int num) = 0; + virtual int getError(SSL* ssl, int returnCode) = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/Transport/ITransport.hpp b/include/f1x/aasdk/Transport/ITransport.hpp new file mode 100644 index 0000000..4c73abf --- /dev/null +++ b/include/f1x/aasdk/Transport/ITransport.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +class ITransport +{ +public: + typedef std::shared_ptr Pointer; + typedef io::Promise ReceivePromise; + typedef io::Promise SendPromise; + + ITransport() = default; + virtual ~ITransport() = default; + + virtual void receive(size_t size, ReceivePromise::Pointer promise) = 0; + virtual void send(common::Data data, SendPromise::Pointer promise) = 0; + virtual void stop() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/Transport/SSLWrapper.hpp b/include/f1x/aasdk/Transport/SSLWrapper.hpp new file mode 100644 index 0000000..a42c0b6 --- /dev/null +++ b/include/f1x/aasdk/Transport/SSLWrapper.hpp @@ -0,0 +1,66 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +class SSLWrapper: public ISSLWrapper +{ +public: + SSLWrapper(); + ~SSLWrapper() override; + + X509* readCertificate(const std::string& certificate) override; + EVP_PKEY* readPrivateKey(const std::string& privateKey) override; + const SSL_METHOD* getMethod() override; + SSL_CTX* createContext(const SSL_METHOD* method) override; + bool useCertificate(SSL_CTX* context, X509* certificate) override; + bool usePrivateKey(SSL_CTX* context, EVP_PKEY* privateKey) override; + SSL* createInstance(SSL_CTX* context) override; + bool checkPrivateKey(SSL* ssl) override; + BIOs createBIOs() override; + void setBIOs(SSL* ssl, const BIOs& bIOs, size_t maxBufferSize) override; + void setConnectState(SSL* ssl) override; + int doHandshake(SSL* ssl) override; + int getError(SSL* ssl, int returnCode) override; + + void free(SSL* ssl) override; + void free(SSL_CTX* context) override; + void free(BIO* bio) override; + void free(X509* certificate) override; + void free(EVP_PKEY* privateKey) override; + + size_t bioCtrlPending(BIO* b) override; + int bioRead(BIO *b, void *data, int len) override; + int bioWrite(BIO *b, const void *data, int len) override; + int getAvailableBytes(const SSL* ssl) override; + int sslRead(SSL *ssl, void *buf, int num) override; + int sslWrite(SSL *ssl, const void *buf, int num) override; +}; + +} +} +} diff --git a/include/f1x/aasdk/Transport/USBDataSink.hpp b/include/f1x/aasdk/Transport/USBDataSink.hpp new file mode 100644 index 0000000..2c7d3e6 --- /dev/null +++ b/include/f1x/aasdk/Transport/USBDataSink.hpp @@ -0,0 +1,51 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +class USBDataSink +{ +public: + USBDataSink(); + + common::DataBuffer fill(); + void commit(common::Data::size_type size); + + common::Data::size_type getAvailableSize(); + common::Data consume(common::Data::size_type size); + +private: + boost::circular_buffer data_; + static constexpr common::Data::size_type cChunkSize = 16384; +}; + +} +} +} diff --git a/include/f1x/aasdk/Transport/USBTransport.hpp b/include/f1x/aasdk/Transport/USBTransport.hpp new file mode 100644 index 0000000..9d3ed71 --- /dev/null +++ b/include/f1x/aasdk/Transport/USBTransport.hpp @@ -0,0 +1,71 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +class USBTransport: public ITransport, public std::enable_shared_from_this, boost::noncopyable +{ +public: + USBTransport(boost::asio::io_service& ioService, usb::IAOAPDevice::Pointer aoapDevice); + + void receive(size_t size, ReceivePromise::Pointer promise) override; + void send(common::Data data, SendPromise::Pointer promise) override; + void stop() override; + +private: + typedef std::list> InTransferQueue; + typedef std::list> OutTransferQueue; + + using std::enable_shared_from_this::shared_from_this; + void receiveHandler(size_t bytesTransferred); + void distributeReceivedData(); + void rejectReceivePromises(const error::Error& e); + + void doSend(OutTransferQueue::iterator queueElementIter, common::Data::size_type offset); + void sendHandler(OutTransferQueue::iterator queueElementIter, common::Data::size_type offset, size_t bytesTransferred); + + usb::IAOAPDevice::Pointer aoapDevice_; + USBDataSink usbReceivedDataSink_; + + boost::asio::io_service::strand receiveStrand_; + InTransferQueue receiveQueue_; + + boost::asio::io_service::strand sendStrand_; + OutTransferQueue sendQueue_; + + static constexpr uint32_t cSendTimeoutMs = 10000; + static constexpr uint32_t cReceiveTimeoutMs = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AOAPDevice.hpp b/include/f1x/aasdk/USB/AOAPDevice.hpp new file mode 100644 index 0000000..2a8f56d --- /dev/null +++ b/include/f1x/aasdk/USB/AOAPDevice.hpp @@ -0,0 +1,63 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class AOAPDevice: public IAOAPDevice, boost::noncopyable +{ +public: + AOAPDevice(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, DeviceHandle handle, const libusb_interface_descriptor* interfaceDescriptor); + ~AOAPDevice() override; + + IUSBEndpoint& getInEndpoint() override; + IUSBEndpoint& getOutEndpoint() override; + + static IAOAPDevice::Pointer create(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, DeviceHandle handle); + +private: + static ConfigDescriptorHandle getConfigDescriptor(IUSBWrapper& usbWrapper, DeviceHandle handle); + static const libusb_interface* getInterface(const ConfigDescriptorHandle& configDescriptorHandle); + static const libusb_interface_descriptor* getInterfaceDescriptor(const libusb_interface* interface); + + IUSBWrapper& usbWrapper_; + DeviceHandle handle_; + const libusb_interface_descriptor* interfaceDescriptor_; + IUSBEndpoint::Pointer inEndpoint_; + IUSBEndpoint::Pointer outEndpoint_; + + static constexpr uint16_t cGoogleVendorId = 0x18D1; + static constexpr uint16_t cAOAPId = 0x2D00; + static constexpr uint16_t cAOAPWithAdbId = 0x2D01; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeProtocolVersionQuery.hpp b/include/f1x/aasdk/USB/AccessoryModeProtocolVersionQuery.hpp new file mode 100644 index 0000000..0a09a9d --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeProtocolVersionQuery.hpp @@ -0,0 +1,46 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class AccessoryModeProtocolVersionQuery: public AccessoryModeQuery, public std::enable_shared_from_this +{ +public: + AccessoryModeProtocolVersionQuery(boost::asio::io_service& ioService, IUSBWrapper& usbWrapper, IUSBEndpoint::Pointer usbEndpoint); + void start(Promise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void protocolVersionHandler(size_t bytesTransferred); + + typedef uint16_t ProtocolVersion; + static constexpr uint32_t ACC_REQ_GET_PROTOCOL = 51; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeQuery.hpp b/include/f1x/aasdk/USB/AccessoryModeQuery.hpp new file mode 100644 index 0000000..8972369 --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeQuery.hpp @@ -0,0 +1,53 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class AccessoryModeQuery: public IAccessoryModeQuery, boost::noncopyable +{ +public: + AccessoryModeQuery(boost::asio::io_service& ioService, IUSBEndpoint::Pointer usbEndpoint); + void cancel() override; + +protected: + boost::asio::io_service::strand strand_; + IUSBEndpoint::Pointer usbEndpoint_; + common::Data data_; + Promise::Pointer promise_; + + static constexpr uint32_t cTransferTimeoutMs = 1000; + static constexpr uint32_t USB_TYPE_VENDOR = 0x40; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeQueryChain.hpp b/include/f1x/aasdk/USB/AccessoryModeQueryChain.hpp new file mode 100644 index 0000000..65d38c1 --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeQueryChain.hpp @@ -0,0 +1,68 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IAccessoryModeQueryFactory; + +class AccessoryModeQueryChain: public IAccessoryModeQueryChain, public std::enable_shared_from_this, boost::noncopyable +{ +public: + AccessoryModeQueryChain(IUSBWrapper& usbWrapper, + boost::asio::io_service& ioService, + IAccessoryModeQueryFactory& queryFactory); + + void start(DeviceHandle handle, Promise::Pointer promise) override; + void cancel() override; + +private: + using std::enable_shared_from_this::shared_from_this; + + void startQuery(AccessoryModeQueryType queryType, IUSBEndpoint::Pointer usbEndpoint, IAccessoryModeQuery::Promise::Pointer queryPromise); + + void protocolVersionQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void manufacturerQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void modelQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void descriptionQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void versionQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void uriQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void serialQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + void startQueryHandler(IUSBEndpoint::Pointer usbEndpoint); + + IUSBWrapper& usbWrapper_; + boost::asio::io_service::strand strand_; + IAccessoryModeQueryFactory& queryFactory_; + DeviceHandle handle_; + Promise::Pointer promise_; + IAccessoryModeQuery::Pointer activeQuery_; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeQueryChainFactory.hpp b/include/f1x/aasdk/USB/AccessoryModeQueryChainFactory.hpp new file mode 100644 index 0000000..cbe2e53 --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeQueryChainFactory.hpp @@ -0,0 +1,47 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class AccessoryModeQueryChainFactory: public IAccessoryModeQueryChainFactory +{ +public: + AccessoryModeQueryChainFactory(IUSBWrapper& usbWrapper, + boost::asio::io_service& ioService, + IAccessoryModeQueryFactory& queryFactory); + IAccessoryModeQueryChain::Pointer create() override; + +private: + IUSBWrapper& usbWrapper_; + boost::asio::io_service& ioService_; + IAccessoryModeQueryFactory& queryFactory_; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeQueryFactory.hpp b/include/f1x/aasdk/USB/AccessoryModeQueryFactory.hpp new file mode 100644 index 0000000..2344d8d --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeQueryFactory.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + + +class AccessoryModeQueryFactory: public IAccessoryModeQueryFactory +{ +public: + AccessoryModeQueryFactory(usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService); + IAccessoryModeQuery::Pointer createQuery(AccessoryModeQueryType queryType, IUSBEndpoint::Pointer usbEndpoint) override; + +private: + usb::IUSBWrapper& usbWrapper_; + boost::asio::io_service& ioService_; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeQueryType.hpp b/include/f1x/aasdk/USB/AccessoryModeQueryType.hpp new file mode 100644 index 0000000..bde6813 --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeQueryType.hpp @@ -0,0 +1,45 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +enum class AccessoryModeQueryType +{ + PROTOCOL_VERSION, + SEND_MANUFACTURER, + SEND_MODEL, + SEND_DESCRIPTION, + SEND_VERSION, + SEND_URI, + SEND_SERIAL, + START +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeSendStringQuery.hpp b/include/f1x/aasdk/USB/AccessoryModeSendStringQuery.hpp new file mode 100644 index 0000000..ccdaa58 --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeSendStringQuery.hpp @@ -0,0 +1,48 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class AccessoryModeSendStringQuery: public AccessoryModeQuery, public std::enable_shared_from_this +{ +public: + AccessoryModeSendStringQuery(boost::asio::io_service& ioService, IUSBWrapper& usbWrapper, IUSBEndpoint::Pointer usbEndpoint, + AccessoryModeSendStringType sendStringType, const std::string& queryValue); + void start(Promise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + + AccessoryModeSendStringType sendStringType_; + static constexpr uint32_t ACC_REQ_SEND_STRING = 52; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeSendStringType.hpp b/include/f1x/aasdk/USB/AccessoryModeSendStringType.hpp new file mode 100644 index 0000000..ec9c9fd --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeSendStringType.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +enum class AccessoryModeSendStringType +{ + MANUFACTURER, + MODEL, + DESCRIPTION, + VERSION, + URI, + SERIAL +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/AccessoryModeStartQuery.hpp b/include/f1x/aasdk/USB/AccessoryModeStartQuery.hpp new file mode 100644 index 0000000..d15dba5 --- /dev/null +++ b/include/f1x/aasdk/USB/AccessoryModeStartQuery.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class AccessoryModeStartQuery: public AccessoryModeQuery, public std::enable_shared_from_this +{ +public: + AccessoryModeStartQuery(boost::asio::io_service& ioService, IUSBWrapper& usbWrapper, IUSBEndpoint::Pointer usbEndpoint); + void start(Promise::Pointer promise) override; + +private: + using std::enable_shared_from_this::shared_from_this; + + static constexpr uint32_t ACC_REQ_START = 53; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IAOAPDevice.hpp b/include/f1x/aasdk/USB/IAOAPDevice.hpp new file mode 100644 index 0000000..30e1c2b --- /dev/null +++ b/include/f1x/aasdk/USB/IAOAPDevice.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IAOAPDevice +{ +public: + typedef std::shared_ptr Pointer; + + IAOAPDevice() = default; + virtual ~IAOAPDevice() = default; + + virtual IUSBEndpoint& getInEndpoint() = 0; + virtual IUSBEndpoint& getOutEndpoint() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IAccessoryModeQuery.hpp b/include/f1x/aasdk/USB/IAccessoryModeQuery.hpp new file mode 100644 index 0000000..2cdba69 --- /dev/null +++ b/include/f1x/aasdk/USB/IAccessoryModeQuery.hpp @@ -0,0 +1,48 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IAccessoryModeQuery +{ +public: + typedef std::shared_ptr Pointer; + typedef io::Promise Promise; + + IAccessoryModeQuery() = default; + virtual ~IAccessoryModeQuery() = default; + + virtual void start(Promise::Pointer promise) = 0; + virtual void cancel() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IAccessoryModeQueryChain.hpp b/include/f1x/aasdk/USB/IAccessoryModeQueryChain.hpp new file mode 100644 index 0000000..203dc2a --- /dev/null +++ b/include/f1x/aasdk/USB/IAccessoryModeQueryChain.hpp @@ -0,0 +1,47 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IAccessoryModeQueryChain +{ +public: + typedef std::shared_ptr Pointer; + typedef io::Promise Promise; + + IAccessoryModeQueryChain() = default; + virtual ~IAccessoryModeQueryChain() = default; + virtual void start(DeviceHandle handle, Promise::Pointer promise) = 0; + virtual void cancel() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IAccessoryModeQueryChainFactory.hpp b/include/f1x/aasdk/USB/IAccessoryModeQueryChainFactory.hpp new file mode 100644 index 0000000..41beb3a --- /dev/null +++ b/include/f1x/aasdk/USB/IAccessoryModeQueryChainFactory.hpp @@ -0,0 +1,40 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IAccessoryModeQueryChainFactory +{ +public: + virtual ~IAccessoryModeQueryChainFactory() = default; + + virtual IAccessoryModeQueryChain::Pointer create() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IAccessoryModeQueryFactory.hpp b/include/f1x/aasdk/USB/IAccessoryModeQueryFactory.hpp new file mode 100644 index 0000000..af3b16e --- /dev/null +++ b/include/f1x/aasdk/USB/IAccessoryModeQueryFactory.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IAccessoryModeQueryFactory +{ +public: + IAccessoryModeQueryFactory() = default; + virtual ~IAccessoryModeQueryFactory() = default; + + virtual IAccessoryModeQuery::Pointer createQuery(AccessoryModeQueryType queryType, IUSBEndpoint::Pointer usbEndpoint) = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IUSBEndpoint.hpp b/include/f1x/aasdk/USB/IUSBEndpoint.hpp new file mode 100644 index 0000000..659a2d3 --- /dev/null +++ b/include/f1x/aasdk/USB/IUSBEndpoint.hpp @@ -0,0 +1,52 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IUSBEndpoint +{ +public: + typedef std::shared_ptr Pointer; + typedef io::Promise Promise; + + IUSBEndpoint() = default; + virtual ~IUSBEndpoint() = default; + + virtual uint8_t getAddress() = 0; + virtual void controlTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) = 0; + virtual void bulkTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) = 0; + virtual void interruptTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) = 0; + virtual void cancelTransfers() = 0; + virtual DeviceHandle getDeviceHandle() const = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IUSBHub.hpp b/include/f1x/aasdk/USB/IUSBHub.hpp new file mode 100644 index 0000000..b18c9db --- /dev/null +++ b/include/f1x/aasdk/USB/IUSBHub.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IUSBHub +{ +public: + typedef std::shared_ptr Pointer; + typedef io::Promise Promise; + + IUSBHub() = default; + virtual ~IUSBHub() = default; + + virtual void start(Promise::Pointer promise) = 0; + virtual void cancel() = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/IUSBWrapper.hpp b/include/f1x/aasdk/USB/IUSBWrapper.hpp new file mode 100644 index 0000000..0c5797f --- /dev/null +++ b/include/f1x/aasdk/USB/IUSBWrapper.hpp @@ -0,0 +1,82 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +typedef std::shared_ptr DeviceHandle; +typedef std::list DeviceList; +typedef std::shared_ptr DeviceListHandle; +typedef std::shared_ptr ConfigDescriptorHandle; +typedef std::shared_ptr HotplugCallbackHandle; + +class IUSBWrapper +{ +public: + virtual ~IUSBWrapper() = default; + + virtual int releaseInterface(const DeviceHandle& dev_handle, int interface_number) = 0; + virtual libusb_device* getDevice(const DeviceHandle& dev_handle) = 0; + virtual int claimInterface(const DeviceHandle& dev_handle, int interface_number) = 0; + virtual DeviceHandle openDeviceWithVidPid(uint16_t vendor_id, uint16_t product_id) = 0; + virtual int getConfigDescriptor(libusb_device *dev, uint8_t config_index, ConfigDescriptorHandle& config_descriptor_handle) = 0; + + virtual void fillBulkTransfer(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) = 0; + + virtual void fillInterruptTransfer(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) = 0; + + virtual void fillControlTransfer( + libusb_transfer *transfer, const DeviceHandle& dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) = 0; + + virtual int submitTransfer(libusb_transfer *transfer) = 0; + virtual int cancelTransfer(libusb_transfer *transfer) = 0; + virtual void freeTransfer(libusb_transfer *transfer) = 0; + + virtual ssize_t getDeviceList(DeviceListHandle& handle) = 0; + virtual int open(libusb_device *dev, DeviceHandle& dev_handle) = 0; + virtual void fillControlSetup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) = 0; + virtual int getDeviceDescriptor(libusb_device *dev, libusb_device_descriptor &desc) = 0; + virtual void handleEvents() = 0; + virtual HotplugCallbackHandle hotplugRegisterCallback(libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data) = 0; + virtual libusb_transfer* allocTransfer(int iso_packets) = 0; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/USBEndpoint.hpp b/include/f1x/aasdk/USB/USBEndpoint.hpp new file mode 100644 index 0000000..d603391 --- /dev/null +++ b/include/f1x/aasdk/USB/USBEndpoint.hpp @@ -0,0 +1,65 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class USBEndpoint: public IUSBEndpoint, + public std::enable_shared_from_this, + boost::noncopyable +{ +public: + USBEndpoint(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, DeviceHandle handle, uint8_t endpointAddress = 0x00); + + void controlTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) override; + void bulkTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) override; + void interruptTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) override; + uint8_t getAddress() override; + void cancelTransfers() override; + DeviceHandle getDeviceHandle() const override; + +private: + typedef std::unordered_map Transfers; + + using std::enable_shared_from_this::shared_from_this; + void transfer(libusb_transfer *transfer, Promise::Pointer promise); + static void transferHandler(libusb_transfer *transfer); + + IUSBWrapper& usbWrapper_; + boost::asio::io_service::strand strand_; + DeviceHandle handle_; + uint8_t endpointAddress_; + Transfers transfers_; + std::shared_ptr self_; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/USBHub.hpp b/include/f1x/aasdk/USB/USBHub.hpp new file mode 100644 index 0000000..23442fc --- /dev/null +++ b/include/f1x/aasdk/USB/USBHub.hpp @@ -0,0 +1,66 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class IUSBWrapper; + +class USBHub: public IUSBHub, public std::enable_shared_from_this, boost::noncopyable +{ +public: + USBHub(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, IAccessoryModeQueryChainFactory& queryChainFactory); + + void start(Promise::Pointer promise) override; + void cancel() override; + +private: + typedef std::list QueryChainQueue; + using std::enable_shared_from_this::shared_from_this; + void handleDevice(libusb_device* device); + bool isAOAPDevice(const libusb_device_descriptor& deviceDescriptor) const; + static int hotplugEventsHandler(libusb_context* usbContext, libusb_device* device, libusb_hotplug_event event, void* uerData); + + IUSBWrapper& usbWrapper_; + boost::asio::io_service::strand strand_; + IAccessoryModeQueryChainFactory& queryChainFactory_; + Promise::Pointer hotplugPromise_; + Pointer self_; + HotplugCallbackHandle hotplugHandle_; + QueryChainQueue queryChainQueue_; + + static constexpr uint16_t cGoogleVendorId = 0x18D1; + static constexpr uint16_t cAOAPId = 0x2D00; + static constexpr uint16_t cAOAPWithAdbId = 0x2D01; +}; + +} +} +} diff --git a/include/f1x/aasdk/USB/USBWrapper.hpp b/include/f1x/aasdk/USB/USBWrapper.hpp new file mode 100644 index 0000000..7a4074c --- /dev/null +++ b/include/f1x/aasdk/USB/USBWrapper.hpp @@ -0,0 +1,77 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +class USBWrapper: public IUSBWrapper +{ +public: + USBWrapper(libusb_context* usbContext); + + int releaseInterface(const DeviceHandle& dev_handle, int interface_number) override; + libusb_device* getDevice(const DeviceHandle& dev_handle) override; + int claimInterface(const DeviceHandle& dev_handle, int interface_number) override; + DeviceHandle openDeviceWithVidPid(uint16_t vendor_id, uint16_t product_id) override; + int getConfigDescriptor(libusb_device *dev, uint8_t config_index, ConfigDescriptorHandle& config_descriptor_handle) override; + + void fillBulkTransfer(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) override; + + void fillInterruptTransfer(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) override; + + void fillControlTransfer( + libusb_transfer *transfer, const DeviceHandle& dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) override; + + int submitTransfer(libusb_transfer *transfer) override; + int cancelTransfer(libusb_transfer *transfer) override; + void freeTransfer(libusb_transfer *transfer) override; + + ssize_t getDeviceList(DeviceListHandle& handle) override; + int open(libusb_device *dev, DeviceHandle& dev_handle) override; + void fillControlSetup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) override; + int getDeviceDescriptor(libusb_device *dev, libusb_device_descriptor &desc) override; + void handleEvents() override; + HotplugCallbackHandle hotplugRegisterCallback(libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data) override; + libusb_transfer* allocTransfer(int iso_packets) override; + +private: + libusb_context* usbContext_; +}; + +} +} +} diff --git a/include/f1x/aasdk/Version.hpp b/include/f1x/aasdk/Version.hpp new file mode 100644 index 0000000..898cf20 --- /dev/null +++ b/include/f1x/aasdk/Version.hpp @@ -0,0 +1,24 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include + +static const uint16_t AASDK_MAJOR = 1; +static const uint16_t AASDK_MINOR = 1; diff --git a/include_ut/f1x/aasdk/Messenger/UT/Cryptor.mock.hpp b/include_ut/f1x/aasdk/Messenger/UT/Cryptor.mock.hpp new file mode 100644 index 0000000..fe6e325 --- /dev/null +++ b/include_ut/f1x/aasdk/Messenger/UT/Cryptor.mock.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +class CryptorMock: public ICryptor +{ +public: + MOCK_METHOD0(init, void()); + MOCK_METHOD0(deinit, void()); + MOCK_METHOD0(doHandshake, bool()); + MOCK_METHOD2(encrypt, size_t(common::Data& output, const common::DataConstBuffer& buffer)); + MOCK_METHOD2(decrypt, size_t(common::Data& output, const common::DataConstBuffer& buffer)); + MOCK_METHOD0(readHandshakeBuffer, common::Data()); + MOCK_METHOD1(writeHandshakeBuffer, void(const common::DataConstBuffer& buffer)); + MOCK_CONST_METHOD0(isActive, bool()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Messenger/UT/MessageInStream.mock.hpp b/include_ut/f1x/aasdk/Messenger/UT/MessageInStream.mock.hpp new file mode 100644 index 0000000..d024f28 --- /dev/null +++ b/include_ut/f1x/aasdk/Messenger/UT/MessageInStream.mock.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +class MessageInStreamMock: public IMessageInStream +{ +public: + MOCK_METHOD1(startReceive, void(ReceivePromise::Pointer promise)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Messenger/UT/MessageOutStream.mock.hpp b/include_ut/f1x/aasdk/Messenger/UT/MessageOutStream.mock.hpp new file mode 100644 index 0000000..10e99de --- /dev/null +++ b/include_ut/f1x/aasdk/Messenger/UT/MessageOutStream.mock.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +class MessageOutStreamMock: public IMessageOutStream +{ +public: + MOCK_METHOD2(stream, void(Message::Pointer message, SendPromise::Pointer promise)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Messenger/UT/ReceivePromiseHandler.mock.hpp b/include_ut/f1x/aasdk/Messenger/UT/ReceivePromiseHandler.mock.hpp new file mode 100644 index 0000000..368d681 --- /dev/null +++ b/include_ut/f1x/aasdk/Messenger/UT/ReceivePromiseHandler.mock.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +class ReceivePromiseHandlerMock +{ +public: + MOCK_METHOD1(onResolve, void(Message::Pointer message)); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Messenger/UT/SendPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/Messenger/UT/SendPromiseHandler.mock.hpp new file mode 100644 index 0000000..b3c354b --- /dev/null +++ b/include_ut/f1x/aasdk/Messenger/UT/SendPromiseHandler.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +class SendPromiseHandlerMock +{ +public: + MOCK_METHOD0(onResolve, void()); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Transport/UT/Transport.mock.hpp b/include_ut/f1x/aasdk/Transport/UT/Transport.mock.hpp new file mode 100644 index 0000000..a8cc75d --- /dev/null +++ b/include_ut/f1x/aasdk/Transport/UT/Transport.mock.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ +namespace ut +{ + +class TransportMock: public ITransport +{ +public: + MOCK_METHOD2(receive, void(size_t size, ReceivePromise::Pointer promise)); + MOCK_METHOD2(send, void(common::Data data, SendPromise::Pointer promise)); + MOCK_METHOD0(stop, void()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Transport/UT/TransportReceivePromiseHandler.mock.hpp b/include_ut/f1x/aasdk/Transport/UT/TransportReceivePromiseHandler.mock.hpp new file mode 100644 index 0000000..d5ed660 --- /dev/null +++ b/include_ut/f1x/aasdk/Transport/UT/TransportReceivePromiseHandler.mock.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ +namespace ut +{ + +class TransportReceivePromiseHandlerMock +{ +public: + MOCK_METHOD1(onResolve, void(common::Data)); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/Transport/UT/TransportSendPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/Transport/UT/TransportSendPromiseHandler.mock.hpp new file mode 100644 index 0000000..b92ae46 --- /dev/null +++ b/include_ut/f1x/aasdk/Transport/UT/TransportSendPromiseHandler.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ +namespace ut +{ + +class TransportSendPromiseHandlerMock +{ +public: + MOCK_METHOD0(onResolve, void()); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AOAPDevice.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AOAPDevice.mock.hpp new file mode 100644 index 0000000..fca721c --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AOAPDevice.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AOAPDeviceMock: public IAOAPDevice +{ +public: + MOCK_METHOD0(getInEndpoint, IUSBEndpoint&()); + MOCK_METHOD0(getOutEndpoint, IUSBEndpoint&()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AccessoryModeQuery.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQuery.mock.hpp new file mode 100644 index 0000000..7383a89 --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQuery.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AccessoryModeQueryMock: public IAccessoryModeQuery +{ +public: + MOCK_METHOD1(start, void(Promise::Pointer promise)); + MOCK_METHOD0(cancel, void()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChain.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChain.mock.hpp new file mode 100644 index 0000000..6f4b11d --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChain.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AccessoryModeQueryChainMock: public IAccessoryModeQueryChain +{ +public: + MOCK_METHOD2(start, void(DeviceHandle handle, Promise::Pointer promise)); + MOCK_METHOD0(cancel, void()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChainFactory.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChainFactory.mock.hpp new file mode 100644 index 0000000..ab03026 --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChainFactory.mock.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AccessoryModeQueryChainFactoryMock: public IAccessoryModeQueryChainFactory +{ +public: + MOCK_METHOD0(create, IAccessoryModeQueryChain::Pointer()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChainPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChainPromiseHandler.mock.hpp new file mode 100644 index 0000000..bbd121c --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryChainPromiseHandler.mock.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AccessoryModeQueryChainPromiseHandlerMock +{ +public: + MOCK_METHOD1(onResolve, void(DeviceHandle handle)); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryFactory.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryFactory.mock.hpp new file mode 100644 index 0000000..c14ad80 --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryFactory.mock.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AccessoryModeQueryFactoryMock: public IAccessoryModeQueryFactory +{ +public: + MOCK_METHOD2(createQuery, IAccessoryModeQuery::Pointer(AccessoryModeQueryType queryType, IUSBEndpoint::Pointer usbEndpoint)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryPromiseHandler.mock.hpp new file mode 100644 index 0000000..516b41b --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/AccessoryModeQueryPromiseHandler.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class AccessoryModeQueryPromiseHandlerMock +{ +public: + MOCK_METHOD1(onResolve, void(IUSBEndpoint::Pointer endpoint)); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/USBEndpoint.mock.hpp b/include_ut/f1x/aasdk/USB/UT/USBEndpoint.mock.hpp new file mode 100644 index 0000000..a002677 --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/USBEndpoint.mock.hpp @@ -0,0 +1,47 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class USBEndpointMock: public IUSBEndpoint +{ +public: + MOCK_METHOD0(getAddress, uint8_t()); + MOCK_METHOD3(controlTransfer, void(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise)); + MOCK_METHOD3(bulkTransfer, void(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise)); + MOCK_METHOD3(interruptTransfer, void(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise)); + MOCK_METHOD0(cancelTransfers, void()); + MOCK_CONST_METHOD0(getDeviceHandle, DeviceHandle()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/USBEndpointPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/USB/UT/USBEndpointPromiseHandler.mock.hpp new file mode 100644 index 0000000..6759f1c --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/USBEndpointPromiseHandler.mock.hpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class USBEndpointPromiseHandlerMock +{ +public: + MOCK_METHOD1(onResolve, void(size_t transferredBytes)); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/USBHub.mock.hpp b/include_ut/f1x/aasdk/USB/UT/USBHub.mock.hpp new file mode 100644 index 0000000..c1680a1 --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/USBHub.mock.hpp @@ -0,0 +1,45 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class USBHubMock: public IUSBHub +{ +public: + MOCK_METHOD1(start, void(Promise::Pointer promise)); + MOCK_METHOD0(cancel, void()); + MOCK_METHOD1(listenHotplugEvents, void(Promise::Pointer promise)); + MOCK_METHOD0(stopListenHotplugEvents, void()); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/USBHubPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/USB/UT/USBHubPromiseHandler.mock.hpp new file mode 100644 index 0000000..d1f31bc --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/USBHubPromiseHandler.mock.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class USBHubPromiseHandlerMock +{ +public: + MOCK_METHOD1(onResolve, void(DeviceHandle handle)); + MOCK_METHOD1(onReject, void(const error::Error& e)); +}; + +} +} +} +} diff --git a/include_ut/f1x/aasdk/USB/UT/USBWrapper.mock.hpp b/include_ut/f1x/aasdk/USB/UT/USBWrapper.mock.hpp new file mode 100644 index 0000000..f83c3e0 --- /dev/null +++ b/include_ut/f1x/aasdk/USB/UT/USBWrapper.mock.hpp @@ -0,0 +1,78 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +class USBWrapperMock: public IUSBWrapper +{ +public: + struct DummyDeviceHandle {}; + + MOCK_METHOD2(releaseInterface, int(const DeviceHandle& dev_handle, int interface_number)); + MOCK_METHOD1(getDevice, libusb_device*(const DeviceHandle& dev_handle)); + MOCK_METHOD2(claimInterface, int(const DeviceHandle& dev_handle, int interface_number)); + MOCK_METHOD2(openDeviceWithVidPid, DeviceHandle(uint16_t vendor_id, uint16_t product_id)); + MOCK_METHOD3(getConfigDescriptor, int(libusb_device *dev, uint8_t config_index, ConfigDescriptorHandle& config_descriptor_handle)); + + MOCK_METHOD8(fillBulkTransfer, void(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout)); + + MOCK_METHOD8(fillInterruptTransfer, void(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout)); + + MOCK_METHOD6(fillControlTransfer, void( + libusb_transfer *transfer, const DeviceHandle& dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout)); + + MOCK_METHOD1(submitTransfer, int(libusb_transfer *transfer)); + MOCK_METHOD1(cancelTransfer, int(libusb_transfer *transfer)); + MOCK_METHOD1(freeTransfer, void(libusb_transfer *transfer)); + + MOCK_METHOD1(getDeviceList, ssize_t(DeviceListHandle& handle)); + MOCK_METHOD2(open, int(libusb_device *dev, DeviceHandle& dev_handle)); + MOCK_METHOD6(fillControlSetup, void(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength)); + MOCK_METHOD2(getDeviceDescriptor, int(libusb_device *dev, libusb_device_descriptor &desc)); + MOCK_METHOD0(handleEvents, void()); + MOCK_METHOD7(hotplugRegisterCallback, HotplugCallbackHandle(libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data)); + MOCK_METHOD1(allocTransfer, libusb_transfer*(int iso_packets)); +}; + +} +} +} +} diff --git a/src/Channel/AV/AVInputServiceChannel.cpp b/src/Channel/AV/AVInputServiceChannel.cpp new file mode 100644 index 0000000..d18baa9 --- /dev/null +++ b/src/Channel/AV/AVInputServiceChannel.cpp @@ -0,0 +1,175 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +AVInputServiceChannel::AVInputServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : ServiceChannel(strand, std::move(messenger), messenger::ChannelId::AV_INPUT) +{ + +} + +void AVInputServiceChannel::receive(IAVInputServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&AVInputServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&IAVInputServiceChannelEventHandler::onChannelError, eventHandler, std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +void AVInputServiceChannel::sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::CONTROL)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::CHANNEL_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void AVInputServiceChannel::sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::SETUP_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +messenger::ChannelId AVInputServiceChannel::getId() +{ + return channelId_; +} + +void AVInputServiceChannel::messageHandler(messenger::Message::Pointer message, IAVInputServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::AVChannelMessage::SETUP_REQUEST: + this->handleAVChannelSetupRequest(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::AV_INPUT_OPEN_REQUEST: + this->handleAVInputOpenRequest(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::AV_MEDIA_ACK_INDICATION: + this->handleAVMediaAckIndication(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::CHANNEL_OPEN_REQUEST: + this->handleChannelOpenRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[AVInputServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void AVInputServiceChannel::sendAVInputOpenResponse(const proto::messages::AVInputOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::AV_INPUT_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void AVInputServiceChannel::sendAVMediaWithTimestampIndication(messenger::Timestamp::ValueType timestamp, const common::Data& data, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::AV_MEDIA_WITH_TIMESTAMP_INDICATION).getData()); + + auto timestampData = messenger::Timestamp(timestamp).getData(); + message->insertPayload(std::move(timestampData)); + message->insertPayload(data); + + this->send(std::move(message), std::move(promise)); +} + +void AVInputServiceChannel::handleAVChannelSetupRequest(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVChannelSetupRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVChannelSetupRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AVInputServiceChannel::handleAVInputOpenRequest(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVInputOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVInputOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AVInputServiceChannel::handleAVMediaAckIndication(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVMediaAckIndication indication; + if(indication.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVMediaAckIndication(indication); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AVInputServiceChannel::handleChannelOpenRequest(const common::DataConstBuffer& payload, IAVInputServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ChannelOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onChannelOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/AV/AudioServiceChannel.cpp b/src/Channel/AV/AudioServiceChannel.cpp new file mode 100644 index 0000000..e4e698a --- /dev/null +++ b/src/Channel/AV/AudioServiceChannel.cpp @@ -0,0 +1,181 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +AudioServiceChannel::AudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger, messenger::ChannelId channelId) + : ServiceChannel(strand, std::move(messenger), channelId) +{ + +} + +void AudioServiceChannel::receive(IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&AudioServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&IAudioServiceChannelEventHandler::onChannelError, eventHandler, std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +messenger::ChannelId AudioServiceChannel::getId() +{ + return channelId_; +} + +void AudioServiceChannel::sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::CONTROL)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::CHANNEL_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void AudioServiceChannel::sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::SETUP_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void AudioServiceChannel::sendAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::AV_MEDIA_ACK_INDICATION).getData()); + message->insertPayload(indication); + + this->send(std::move(message), std::move(promise)); +} + +void AudioServiceChannel::messageHandler(messenger::Message::Pointer message, IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::AVChannelMessage::SETUP_REQUEST: + this->handleAVChannelSetupRequest(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::START_INDICATION: + this->handleStartIndication(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::STOP_INDICATION: + this->handleStopIndication(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::AV_MEDIA_WITH_TIMESTAMP_INDICATION: + this->handleAVMediaWithTimestampIndication(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::AV_MEDIA_INDICATION: + eventHandler->onAVMediaIndication(payload); + break; + case proto::ids::ControlMessage::CHANNEL_OPEN_REQUEST: + this->handleChannelOpenRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[AudioServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void AudioServiceChannel::handleAVChannelSetupRequest(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVChannelSetupRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVChannelSetupRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AudioServiceChannel::handleStartIndication(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVChannelStartIndication indication; + if(indication.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVChannelStartIndication(indication); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AudioServiceChannel::handleStopIndication(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVChannelStopIndication indication; + if(indication.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVChannelStopIndication(indication); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AudioServiceChannel::handleChannelOpenRequest(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ChannelOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onChannelOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void AudioServiceChannel::handleAVMediaWithTimestampIndication(const common::DataConstBuffer& payload, IAudioServiceChannelEventHandler::Pointer eventHandler) +{ + if(payload.size >= sizeof(messenger::Timestamp::ValueType)) + { + messenger::Timestamp timestamp(payload); + eventHandler->onAVMediaWithTimestampIndication(timestamp.getValue(), common::DataConstBuffer(payload.cdata, payload.size, sizeof(messenger::Timestamp::ValueType))); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/AV/MediaAudioServiceChannel.cpp b/src/Channel/AV/MediaAudioServiceChannel.cpp new file mode 100644 index 0000000..0aab28c --- /dev/null +++ b/src/Channel/AV/MediaAudioServiceChannel.cpp @@ -0,0 +1,39 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +MediaAudioServiceChannel::MediaAudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : AudioServiceChannel(strand, std::move(messenger), messenger::ChannelId::MEDIA_AUDIO) +{ + +} + +} +} +} +} diff --git a/src/Channel/AV/SpeechAudioServiceChannel.cpp b/src/Channel/AV/SpeechAudioServiceChannel.cpp new file mode 100644 index 0000000..2ff457f --- /dev/null +++ b/src/Channel/AV/SpeechAudioServiceChannel.cpp @@ -0,0 +1,39 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +SpeechAudioServiceChannel::SpeechAudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : AudioServiceChannel(strand, std::move(messenger), messenger::ChannelId::SPEECH_AUDIO) +{ + +} + +} +} +} +} diff --git a/src/Channel/AV/SystemAudioServiceChannel.cpp b/src/Channel/AV/SystemAudioServiceChannel.cpp new file mode 100644 index 0000000..2a350e1 --- /dev/null +++ b/src/Channel/AV/SystemAudioServiceChannel.cpp @@ -0,0 +1,39 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +SystemAudioServiceChannel::SystemAudioServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : AudioServiceChannel(strand, std::move(messenger), messenger::ChannelId::SYSTEM_AUDIO) +{ + +} + +} +} +} +} diff --git a/src/Channel/AV/VideoServiceChannel.cpp b/src/Channel/AV/VideoServiceChannel.cpp new file mode 100644 index 0000000..c1dde6b --- /dev/null +++ b/src/Channel/AV/VideoServiceChannel.cpp @@ -0,0 +1,191 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace av +{ + +VideoServiceChannel::VideoServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : ServiceChannel(strand, std::move(messenger), messenger::ChannelId::VIDEO) +{ + +} + +void VideoServiceChannel::receive(IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&VideoServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&IVideoServiceChannelEventHandler::onChannelError, eventHandler, std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +messenger::ChannelId VideoServiceChannel::getId() +{ + return channelId_; +} + +void VideoServiceChannel::sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::CONTROL)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::CHANNEL_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void VideoServiceChannel::sendAVChannelSetupResponse(const proto::messages::AVChannelSetupResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::SETUP_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void VideoServiceChannel::sendVideoFocusIndication(const proto::messages::VideoFocusIndication& indication, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::VIDEO_FOCUS_INDICATION).getData()); + message->insertPayload(indication); + + this->send(std::move(message), std::move(promise)); +} + +void VideoServiceChannel::sendAVMediaAckIndication(const proto::messages::AVMediaAckIndication& indication, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::AVChannelMessage::AV_MEDIA_ACK_INDICATION).getData()); + message->insertPayload(indication); + + this->send(std::move(message), std::move(promise)); +} + +void VideoServiceChannel::messageHandler(messenger::Message::Pointer message, IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::AVChannelMessage::SETUP_REQUEST: + this->handleAVChannelSetupRequest(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::START_INDICATION: + this->handleStartIndication(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::AV_MEDIA_WITH_TIMESTAMP_INDICATION: + this->handleAVMediaWithTimestampIndication(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::AV_MEDIA_INDICATION: + eventHandler->onAVMediaIndication(payload); + break; + case proto::ids::ControlMessage::CHANNEL_OPEN_REQUEST: + this->handleChannelOpenRequest(payload, std::move(eventHandler)); + break; + case proto::ids::AVChannelMessage::VIDEO_FOCUS_REQUEST: + this->handleVideoFocusRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[VideoServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void VideoServiceChannel::handleAVChannelSetupRequest(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVChannelSetupRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVChannelSetupRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void VideoServiceChannel::handleStartIndication(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AVChannelStartIndication indication; + if(indication.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAVChannelStartIndication(indication); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void VideoServiceChannel::handleChannelOpenRequest(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ChannelOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onChannelOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void VideoServiceChannel::handleVideoFocusRequest(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::VideoFocusRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onVideoFocusRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void VideoServiceChannel::handleAVMediaWithTimestampIndication(const common::DataConstBuffer& payload, IVideoServiceChannelEventHandler::Pointer eventHandler) +{ + if(payload.size >= sizeof(messenger::Timestamp::ValueType)) + { + messenger::Timestamp timestamp(payload); + eventHandler->onAVMediaWithTimestampIndication(timestamp.getValue(), common::DataConstBuffer(payload.cdata, payload.size, sizeof(messenger::Timestamp::ValueType))); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/Bluetooth/BluetoothServiceChannel.cpp b/src/Channel/Bluetooth/BluetoothServiceChannel.cpp new file mode 100644 index 0000000..283a6f6 --- /dev/null +++ b/src/Channel/Bluetooth/BluetoothServiceChannel.cpp @@ -0,0 +1,122 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace bluetooth +{ + +BluetoothServiceChannel::BluetoothServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : ServiceChannel(strand, std::move(messenger), messenger::ChannelId::BLUETOOTH) +{ + +} + +void BluetoothServiceChannel::receive(IBluetoothServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&BluetoothServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&IBluetoothServiceChannelEventHandler::onChannelError, eventHandler,std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +messenger::ChannelId BluetoothServiceChannel::getId() +{ + return channelId_; +} + +void BluetoothServiceChannel::sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::CONTROL)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::CHANNEL_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void BluetoothServiceChannel::sendBluetoothPairingResponse(const proto::messages::BluetoothPairingResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::BluetoothChannelMessage::PAIRING_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void BluetoothServiceChannel::messageHandler(messenger::Message::Pointer message, IBluetoothServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::ControlMessage::CHANNEL_OPEN_REQUEST: + this->handleChannelOpenRequest(payload, std::move(eventHandler)); + break; + case proto::ids::BluetoothChannelMessage::PAIRING_REQUEST: + this->handleBluetoothPairingRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[BluetoothServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void BluetoothServiceChannel::handleChannelOpenRequest(const common::DataConstBuffer& payload, IBluetoothServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ChannelOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onChannelOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void BluetoothServiceChannel::handleBluetoothPairingRequest(const common::DataConstBuffer& payload, IBluetoothServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::BluetoothPairingRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onBluetoothPairingRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/Control/ControlServiceChannel.cpp b/src/Channel/Control/ControlServiceChannel.cpp new file mode 100644 index 0000000..00b1ef3 --- /dev/null +++ b/src/Channel/Control/ControlServiceChannel.cpp @@ -0,0 +1,242 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace control +{ + +ControlServiceChannel::ControlServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : ServiceChannel(strand, messenger, messenger::ChannelId::CONTROL) +{ + +} + +void ControlServiceChannel::sendVersionRequest(SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::PLAIN, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::VERSION_REQUEST).getData()); + + common::Data versionBuffer(4, 0); + reinterpret_cast(versionBuffer[0]) = boost::endian::native_to_big(AASDK_MAJOR); + reinterpret_cast(versionBuffer[2]) = boost::endian::native_to_big(AASDK_MINOR); + message->insertPayload(versionBuffer); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendHandshake(common::Data handshakeBuffer, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::PLAIN, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::SSL_HANDSHAKE).getData()); + message->insertPayload(handshakeBuffer); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendAuthComplete(const proto::messages::AuthCompleteIndication& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::PLAIN, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::AUTH_COMPLETE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendServiceDiscoveryResponse(const proto::messages::ServiceDiscoveryResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::SERVICE_DISCOVERY_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendAudioFocusResponse(const proto::messages::AudioFocusResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::AUDIO_FOCUS_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendShutdownRequest(const proto::messages::ShutdownRequest& request, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::SHUTDOWN_REQUEST).getData()); + message->insertPayload(request); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendShutdownResponse(const proto::messages::ShutdownResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::SHUTDOWN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::sendNavigationFocusResponse(const proto::messages::NavigationFocusResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::NAVIGATION_FOCUS_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void ControlServiceChannel::receive(IControlServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&ControlServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&IControlServiceChannelEventHandler::onChannelError, eventHandler, std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +void ControlServiceChannel::messageHandler(messenger::Message::Pointer message, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::ControlMessage::VERSION_RESPONSE: + this->handleVersionResponse(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::SSL_HANDSHAKE: + eventHandler->onHandshake(payload); + break; + case proto::ids::ControlMessage::SERVICE_DISCOVERY_REQUEST: + this->handleServiceDiscoveryRequest(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::AUDIO_FOCUS_REQUEST: + this->handleAudioFocusRequest(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::SHUTDOWN_REQUEST: + this->handleShutdownRequest(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::SHUTDOWN_RESPONSE: + this->handleShutdownResponse(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::NAVIGATION_FOCUS_REQUEST: + this->handleNavigationFocusRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[ControlServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void ControlServiceChannel::handleVersionResponse(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + const size_t elements = payload.size / sizeof(uint16_t); + const uint16_t* versionResponse = reinterpret_cast(payload.cdata); + + uint16_t majorCode = elements > 0 ? boost::endian::big_to_native(versionResponse[0]) : 0; + uint16_t minorCode = elements > 1 ? boost::endian::big_to_native(versionResponse[1]) : 0; + proto::enums::VersionResponseStatus::Enum status = elements > 2 ? static_cast(versionResponse[2]) : proto::enums::VersionResponseStatus::MISMATCH; + + eventHandler->onVersionResponse(majorCode, minorCode, status); +} + +void ControlServiceChannel::handleServiceDiscoveryRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ServiceDiscoveryRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onServiceDiscoveryRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void ControlServiceChannel::handleAudioFocusRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::AudioFocusRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onAudioFocusRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void ControlServiceChannel::handleShutdownRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ShutdownRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onShutdownRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void ControlServiceChannel::handleShutdownResponse(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ShutdownResponse response; + if(response.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onShutdownResponse(response); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void ControlServiceChannel::handleNavigationFocusRequest(const common::DataConstBuffer& payload, IControlServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::NavigationFocusRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onNavigationFocusRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/Input/InputServiceChannel.cpp b/src/Channel/Input/InputServiceChannel.cpp new file mode 100644 index 0000000..f3073e7 --- /dev/null +++ b/src/Channel/Input/InputServiceChannel.cpp @@ -0,0 +1,131 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace input +{ + +InputServiceChannel::InputServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : ServiceChannel(strand, std::move(messenger), messenger::ChannelId::INPUT) +{ + +} + +void InputServiceChannel::receive(IInputServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&InputServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&IInputServiceChannelEventHandler::onChannelError, eventHandler, std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +messenger::ChannelId InputServiceChannel::getId() +{ + return channelId_; +} + +void InputServiceChannel::sendInputEventIndication(const proto::messages::InputEventIndication& indication, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::InputChannelMessage::INPUT_EVENT_INDICATION).getData()); + message->insertPayload(indication); + + this->send(std::move(message), std::move(promise)); +} + +void InputServiceChannel::sendBindingResponse(const proto::messages::BindingResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::InputChannelMessage::BINDING_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void InputServiceChannel::sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::CONTROL)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::CHANNEL_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void InputServiceChannel::messageHandler(messenger::Message::Pointer message, IInputServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::InputChannelMessage::BINDING_REQUEST: + this->handleBindingRequest(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::CHANNEL_OPEN_REQUEST: + this->handleChannelOpenRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[InputServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void InputServiceChannel::handleBindingRequest(const common::DataConstBuffer& payload, IInputServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::BindingRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onBindingRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void InputServiceChannel::handleChannelOpenRequest(const common::DataConstBuffer& payload, IInputServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ChannelOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onChannelOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/Sensor/SensorServiceChannel.cpp b/src/Channel/Sensor/SensorServiceChannel.cpp new file mode 100644 index 0000000..7ef7863 --- /dev/null +++ b/src/Channel/Sensor/SensorServiceChannel.cpp @@ -0,0 +1,131 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ +namespace sensor +{ + +SensorServiceChannel::SensorServiceChannel(boost::asio::io_service::strand& strand, messenger::IMessenger::Pointer messenger) + : ServiceChannel(strand, std::move(messenger), messenger::ChannelId::SENSOR) +{ + +} + +void SensorServiceChannel::receive(ISensorServiceChannelEventHandler::Pointer eventHandler) +{ + auto receivePromise = messenger::ReceivePromise::defer(strand_); + receivePromise->then(std::bind(&SensorServiceChannel::messageHandler, this->shared_from_this(), std::placeholders::_1, eventHandler), + std::bind(&ISensorServiceChannelEventHandler::onChannelError, eventHandler, std::placeholders::_1)); + + messenger_->enqueueReceive(channelId_, std::move(receivePromise)); +} + +messenger::ChannelId SensorServiceChannel::getId() +{ + return channelId_; +} + +void SensorServiceChannel::sendChannelOpenResponse(const proto::messages::ChannelOpenResponse& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::CONTROL)); + message->insertPayload(messenger::MessageId(proto::ids::ControlMessage::CHANNEL_OPEN_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void SensorServiceChannel::messageHandler(messenger::Message::Pointer message, ISensorServiceChannelEventHandler::Pointer eventHandler) +{ + messenger::MessageId messageId(message->getPayload()); + common::DataConstBuffer payload(message->getPayload(), messageId.getSizeOf()); + + switch(messageId.getId()) + { + case proto::ids::SensorChannelMessage::SENSOR_START_REQUEST: + this->handleSensorStartRequest(payload, std::move(eventHandler)); + break; + case proto::ids::ControlMessage::CHANNEL_OPEN_REQUEST: + this->handleChannelOpenRequest(payload, std::move(eventHandler)); + break; + default: + AASDK_LOG(error) << "[SensorServiceChannel] message not handled: " << messageId.getId(); + this->receive(std::move(eventHandler)); + break; + } +} + +void SensorServiceChannel::sendSensorEventIndication(const proto::messages::SensorEventIndication& indication, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::SensorChannelMessage::SENSOR_EVENT_INDICATION).getData()); + message->insertPayload(indication); + + this->send(std::move(message), std::move(promise)); +} + +void SensorServiceChannel::sendSensorStartResponse(const proto::messages::SensorStartResponseMessage& response, SendPromise::Pointer promise) +{ + auto message(std::make_shared(channelId_, messenger::EncryptionType::ENCRYPTED, messenger::MessageType::SPECIFIC)); + message->insertPayload(messenger::MessageId(proto::ids::SensorChannelMessage::SENSOR_START_RESPONSE).getData()); + message->insertPayload(response); + + this->send(std::move(message), std::move(promise)); +} + +void SensorServiceChannel::handleSensorStartRequest(const common::DataConstBuffer& payload, ISensorServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::SensorStartRequestMessage request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onSensorStartRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +void SensorServiceChannel::handleChannelOpenRequest(const common::DataConstBuffer& payload, ISensorServiceChannelEventHandler::Pointer eventHandler) +{ + proto::messages::ChannelOpenRequest request; + if(request.ParseFromArray(payload.cdata, payload.size)) + { + eventHandler->onChannelOpenRequest(request); + } + else + { + eventHandler->onChannelError(error::Error(error::ErrorCode::PARSE_PAYLOAD)); + } +} + +} +} +} +} diff --git a/src/Channel/ServiceChannel.cpp b/src/Channel/ServiceChannel.cpp new file mode 100644 index 0000000..74b3a5b --- /dev/null +++ b/src/Channel/ServiceChannel.cpp @@ -0,0 +1,48 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace channel +{ + +ServiceChannel::ServiceChannel(boost::asio::io_service::strand& strand, + messenger::IMessenger::Pointer messenger, + messenger::ChannelId channelId) + : strand_(strand) + , messenger_(std::move(messenger)) + , channelId_(channelId) +{ + +} + +void ServiceChannel::send(messenger::Message::Pointer message, SendPromise::Pointer promise) +{ + auto sendPromise = messenger::SendPromise::defer(strand_.get_io_service()); + io::PromiseLink<>::forward(*sendPromise, std::move(promise)); + messenger_->enqueueSend(std::move(message), std::move(sendPromise)); +} + +} +} +} diff --git a/src/Common/Data.cpp b/src/Common/Data.cpp new file mode 100644 index 0000000..989a4ef --- /dev/null +++ b/src/Common/Data.cpp @@ -0,0 +1,140 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace common +{ + +DataBuffer::DataBuffer() + : data(nullptr) + , size(0) +{ + +} + +DataBuffer::DataBuffer(Data::value_type* _data, Data::size_type _size, Data::size_type offset) +{ + if(offset > _size || _data == nullptr || _size == 0) + { + data = nullptr; + size = 0; + } + else if(offset <= _size) + { + data = _data + offset; + size = _size - offset; + } +} + +DataBuffer::DataBuffer(void* _data, Data::size_type _size, Data::size_type offset) + : DataBuffer(reinterpret_cast(_data), _size, offset) +{ + +} + +DataBuffer::DataBuffer(Data& _data, Data::size_type offset) + : DataBuffer(_data.empty() ? nullptr : &_data[0], _data.size(), offset > _data.size() ? 0 : offset) +{ + +} + +bool DataBuffer::operator==(const std::nullptr_t&) const +{ + return data == nullptr || size == 0; +} + +DataConstBuffer::DataConstBuffer() + : cdata(nullptr) + , size(0) +{ + +} + +DataConstBuffer::DataConstBuffer(const DataBuffer& other) + : cdata(other.data) + , size(other.size) +{ +} + +DataConstBuffer::DataConstBuffer(const Data::value_type* _data, Data::size_type _size, Data::size_type offset) +{ + if(offset > _size || _data == nullptr || _size == 0) + { + cdata = nullptr; + size = 0; + } + else if(offset <= _size) + { + cdata = _data + offset; + size = _size - offset; + } +} + +DataConstBuffer::DataConstBuffer(const void* _data, Data::size_type _size, Data::size_type offset) + : DataConstBuffer(reinterpret_cast(_data), _size, offset) +{ + +} + +DataConstBuffer::DataConstBuffer(const Data& _data, Data::size_type offset) + : DataConstBuffer(_data.empty() ? nullptr : &_data[0], _data.size(), offset > _data.size() ? 0 : offset) +{ + +} + +bool DataConstBuffer::operator==(const std::nullptr_t&) const +{ + return cdata == nullptr || size == 0; +} + +common::Data createData(const DataConstBuffer& buffer) +{ + common::Data data; + copy(data, buffer); + return data; +} + +std::string dump(const Data& data) +{ + return dump(DataConstBuffer(data)); +} + +std::string dump(const DataConstBuffer& buffer) +{ + if(buffer.size == 0) + { + return "[0] null"; + } + else + { + std::string hexDump = "[" + std::to_string(buffer.size) + "] "; + //boost::algorithm::hex(bufferBegin(buffer), bufferEnd(buffer), back_inserter(hexDump)); + return hexDump; + } +} + +} +} +} diff --git a/src/Error/Error.cpp b/src/Error/Error.cpp new file mode 100644 index 0000000..b8cdbb6 --- /dev/null +++ b/src/Error/Error.cpp @@ -0,0 +1,70 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace error +{ + +Error::Error() + : code_(ErrorCode::NONE) + , nativeCode_(0) +{ + +} + +Error::Error(ErrorCode code, uint32_t nativeCode) + : code_(code) + , nativeCode_(nativeCode) +{ + message_ = "AaSdk error code: " + std::to_string(static_cast(code_)) + + ", native code: " + std::to_string(nativeCode_); +} + +ErrorCode Error::getCode() const +{ + return code_; +} + +uint32_t Error::getNativeCode() const +{ + return nativeCode_; +} + +const char* Error::what() const noexcept +{ + return message_.c_str(); +} + +bool Error::operator!() const +{ + return code_ != ErrorCode::NONE || nativeCode_ != 0; +} + +bool Error::operator==(const Error& other) const +{ + return code_ == other.code_ && nativeCode_ == other.nativeCode_; +} + +} +} +} diff --git a/src/IO/IOContextWrapper.cpp b/src/IO/IOContextWrapper.cpp new file mode 100644 index 0000000..8813507 --- /dev/null +++ b/src/IO/IOContextWrapper.cpp @@ -0,0 +1,62 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace io +{ + +IOContextWrapper::IOContextWrapper() + : ioService_(nullptr) + , strand_(nullptr) +{ + +} + +IOContextWrapper::IOContextWrapper(boost::asio::io_service& ioService) + : ioService_(&ioService) + , strand_(nullptr) +{ + +} + +IOContextWrapper::IOContextWrapper(boost::asio::io_service::strand& strand) + : ioService_(nullptr) + , strand_(&strand) +{ + +} + +void IOContextWrapper::reset() +{ + ioService_ = nullptr; + strand_ = nullptr; +} + +bool IOContextWrapper::isActive() const +{ + return ioService_ != nullptr || strand_ != nullptr; +} + +} +} +} diff --git a/src/Main.ut.cpp b/src/Main.ut.cpp new file mode 100644 index 0000000..2b54205 --- /dev/null +++ b/src/Main.ut.cpp @@ -0,0 +1,21 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#define BOOST_TEST_MODULE aasdk_ut + +#include diff --git a/src/Messenger/ChannelId.cpp b/src/Messenger/ChannelId.cpp new file mode 100644 index 0000000..ff74a8d --- /dev/null +++ b/src/Messenger/ChannelId.cpp @@ -0,0 +1,59 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +std::string channelIdToString(ChannelId channelId) +{ + switch(channelId) + { + case ChannelId::CONTROL: + return "CONTROL"; + case ChannelId::INPUT: + return "INPUT"; + case ChannelId::SENSOR: + return "SENSOR"; + case ChannelId::VIDEO: + return "VIDEO"; + case ChannelId::MEDIA_AUDIO: + return "MEDIA_AUDIO"; + case ChannelId::SPEECH_AUDIO: + return "SPEECH_AUDIO"; + case ChannelId::SYSTEM_AUDIO: + return "SYSTEM_AUDIO"; + case ChannelId::AV_INPUT: + return "AV_INPUT"; + case ChannelId::BLUETOOTH: + return "BLUETOOTH"; + case ChannelId::NONE: + return "NONE"; + default: + return "(null)"; + } +} + +} +} +} diff --git a/src/Messenger/ChannelReceiveMessageQueue.cpp b/src/Messenger/ChannelReceiveMessageQueue.cpp new file mode 100644 index 0000000..c15d7cf --- /dev/null +++ b/src/Messenger/ChannelReceiveMessageQueue.cpp @@ -0,0 +1,67 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +void ChannelReceiveMessageQueue::push(Message::Pointer message) +{ + const auto channelId = message->getChannelId(); + + if(queue_.count(channelId) == 0) + { + queue_.emplace(std::make_pair(channelId, MessageQueue())); + } + + auto& channelQueue = queue_.at(channelId); + channelQueue.emplace(std::move(message)); +} + +Message::Pointer ChannelReceiveMessageQueue::pop(ChannelId channelId) +{ + auto& channelQueue = queue_.at(channelId); + auto message(std::move(channelQueue.front())); + channelQueue.pop(); + + if(channelQueue.empty()) + { + queue_.erase(channelId); + } + + return message; +} + +bool ChannelReceiveMessageQueue::empty(ChannelId channelId) const +{ + return queue_.count(channelId) == 0; +} + +void ChannelReceiveMessageQueue::clear() +{ + queue_.clear(); +} + +} +} +} diff --git a/src/Messenger/ChannelReceivePromiseQueue.cpp b/src/Messenger/ChannelReceivePromiseQueue.cpp new file mode 100644 index 0000000..8aba2de --- /dev/null +++ b/src/Messenger/ChannelReceivePromiseQueue.cpp @@ -0,0 +1,74 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +void ChannelReceivePromiseQueue::push(ChannelId channelId, ReceivePromise::Pointer promise) +{ + queue_[channelId].push(std::move(promise)); +} + +ReceivePromise::Pointer ChannelReceivePromiseQueue::pop(ChannelId channelId) +{ + auto& channelQueue = queue_.at(channelId); + auto promise = std::move(channelQueue.front()); + channelQueue.pop(); + + if(channelQueue.empty()) + { + queue_.erase(channelId); + } + + return promise; +} + +bool ChannelReceivePromiseQueue::isPending(ChannelId channelId) const +{ + return queue_.count(channelId) > 0 && !queue_.at(channelId).empty(); +} + +size_t ChannelReceivePromiseQueue::size() const +{ + return queue_.size(); +} + +bool ChannelReceivePromiseQueue::empty() const +{ + return this->size() == 0; +} + +void ChannelReceivePromiseQueue::clear() +{ + queue_.clear(); +} + +ReceivePromise::Pointer ChannelReceivePromiseQueue::pop() +{ + return this->pop(queue_.begin()->first); +} + +} +} +} diff --git a/src/Messenger/Cryptor.cpp b/src/Messenger/Cryptor.cpp new file mode 100644 index 0000000..d431911 --- /dev/null +++ b/src/Messenger/Cryptor.cpp @@ -0,0 +1,326 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +Cryptor::Cryptor(transport::ISSLWrapper::Pointer sslWrapper) + : sslWrapper_(std::move(sslWrapper)) + , maxBufferSize_(1024 * 20) + , certificate_(nullptr) + , privateKey_(nullptr) + , context_(nullptr) + , ssl_(nullptr) + , isActive_(false) +{ + +} + +void Cryptor::init() +{ + std::lock_guard lock(mutex_); + + certificate_ = sslWrapper_->readCertificate(cCertificate); + + if(certificate_ == nullptr) + { + throw error::Error(error::ErrorCode::SSL_READ_CERTIFICATE); + } + + privateKey_ = sslWrapper_->readPrivateKey(cPrivateKey); + + if(privateKey_ == nullptr) + { + throw error::Error(error::ErrorCode::SSL_READ_PRIVATE_KEY); + } + + auto method = sslWrapper_->getMethod(); + + if(method == nullptr) + { + throw error::Error(error::ErrorCode::SSL_METHOD); + } + + context_ = sslWrapper_->createContext(method); + + if(context_ == nullptr) + { + throw error::Error(error::ErrorCode::SSL_CONTEXT_CREATION); + } + + if(!sslWrapper_->useCertificate(context_, certificate_)) + { + throw error::Error(error::ErrorCode::SSL_USE_CERTIFICATE); + } + + if(!sslWrapper_->usePrivateKey(context_, privateKey_)) + { + throw error::Error(error::ErrorCode::SSL_USE_PRIVATE_KEY); + } + + ssl_ = sslWrapper_->createInstance(context_); + + if(ssl_ == nullptr) + { + throw error::Error(error::ErrorCode::SSL_HANDLER_CREATION); + } + + bIOs_ = sslWrapper_->createBIOs(); + + if(bIOs_.first == nullptr) + { + throw error::Error(error::ErrorCode::SSL_READ_BIO_CREATION); + } + + if(bIOs_.second == nullptr) + { + throw error::Error(error::ErrorCode::SSL_WRITE_BIO_CREATION); + } + + sslWrapper_->setBIOs(ssl_, bIOs_, maxBufferSize_); + + sslWrapper_->setConnectState(ssl_); +} + +void Cryptor::deinit() +{ + std::lock_guard lock(mutex_); + + if(ssl_ != nullptr) + { + sslWrapper_->free(ssl_); + ssl_ = nullptr; + } + + bIOs_ = std::make_pair(nullptr, nullptr); + + if(context_ != nullptr) + { + sslWrapper_->free(context_); + context_ = nullptr; + } + + if(certificate_ != nullptr) + { + sslWrapper_->free(certificate_); + certificate_ = nullptr; + } + + if(privateKey_ != nullptr) + { + sslWrapper_->free(privateKey_); + privateKey_ = nullptr; + } +} + +bool Cryptor::doHandshake() +{ + std::lock_guard lock(mutex_); + + auto result = sslWrapper_->doHandshake(ssl_); + if(result == SSL_ERROR_WANT_READ) + { + return false; + } + else if(result == SSL_ERROR_NONE) + { + isActive_ = true; + return true; + } + else + { + throw error::Error(error::ErrorCode::SSL_HANDSHAKE, result); + } +} + +size_t Cryptor::encrypt(common::Data& output, const common::DataConstBuffer& buffer) +{ + std::lock_guard lock(mutex_); + + size_t totalWrittenBytes = 0; + + while(totalWrittenBytes < buffer.size) + { + const common::DataConstBuffer currentBuffer(buffer.cdata, buffer.size, totalWrittenBytes); + const auto writeSize = sslWrapper_->sslWrite(ssl_, currentBuffer.cdata, currentBuffer.size); + + if(writeSize <= 0) + { + throw error::Error(error::ErrorCode::SSL_WRITE, sslWrapper_->getError(ssl_, writeSize)); + } + + totalWrittenBytes += writeSize; + } + + return this->read(output); +} + +size_t Cryptor::decrypt(common::Data& output, const common::DataConstBuffer& buffer) +{ + std::lock_guard lock(mutex_); + + this->write(buffer); + const size_t beginOffset = output.size(); + output.resize(beginOffset + 1); + + size_t availableBytes = 1; + size_t totalReadSize = 0; + + while(availableBytes > 0) + { + const auto& currentBuffer = common::DataBuffer(output, totalReadSize + beginOffset); + auto readSize = sslWrapper_->sslRead(ssl_, currentBuffer.data, currentBuffer.size); + + if(readSize <= 0) + { + throw error::Error(error::ErrorCode::SSL_READ, sslWrapper_->getError(ssl_, readSize)); + } + + totalReadSize += readSize; + availableBytes = sslWrapper_->getAvailableBytes(ssl_); + output.resize(output.size() + availableBytes); + } + + return totalReadSize; +} + +common::Data Cryptor::readHandshakeBuffer() +{ + std::lock_guard lock(mutex_); + + common::Data output; + this->read(output); + return output; +} + +void Cryptor::writeHandshakeBuffer(const common::DataConstBuffer& buffer) +{ + std::lock_guard lock(mutex_); + + this->write(buffer); +} + +size_t Cryptor::read(common::Data& output) +{ + const auto pendingSize = sslWrapper_->bioCtrlPending(bIOs_.second); + + size_t beginOffset = output.size(); + output.resize(beginOffset + pendingSize); + size_t totalReadSize = 0; + + while(totalReadSize < pendingSize) + { + const auto& currentBuffer = common::DataBuffer(output, totalReadSize + beginOffset); + const auto readSize = sslWrapper_->bioRead(bIOs_.second, currentBuffer.data, currentBuffer.size); + + if(readSize <= 0) + { + throw error::Error(error::ErrorCode::SSL_BIO_READ, sslWrapper_->getError(ssl_, readSize)); + } + + totalReadSize += readSize; + } + + return totalReadSize; +} + +void Cryptor::write(const common::DataConstBuffer& buffer) +{ + size_t totalWrittenBytes = 0; + + while(totalWrittenBytes < buffer.size) + { + const common::DataConstBuffer currentBuffer(buffer.cdata, buffer.size, totalWrittenBytes); + const auto writeSize = sslWrapper_->bioWrite(bIOs_.first, currentBuffer.cdata, currentBuffer.size); + + if(writeSize <= 0) + { + throw error::Error(error::ErrorCode::SSL_BIO_WRITE, sslWrapper_->getError(ssl_, writeSize)); + } + + totalWrittenBytes += writeSize; + } +} + +bool Cryptor::isActive() const +{ + std::lock_guard lock(mutex_); + + return isActive_; +} + +const std::string Cryptor::cCertificate = "-----BEGIN CERTIFICATE-----\n\ +MIIDKjCCAhICARswDQYJKoZIhvcNAQELBQAwWzELMAkGA1UEBhMCVVMxEzARBgNV\n\ +BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n\ +Fkdvb2dsZSBBdXRvbW90aXZlIExpbmswJhcRMTQwNzA0MDAwMDAwLTA3MDAXETQ1\n\ +MDQyOTE0MjgzOC0wNzAwMFMxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzER\n\ +MA8GA1UEBwwISGFjaGlvamkxFDASBgNVBAoMC0pWQyBLZW53b29kMQswCQYDVQQL\n\ +DAIwMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM911mNnUfx+WJtx\n\ +uk06GO7kXRW/gXUVNQBkbAFZmVdVNvLoEQNthi2X8WCOwX6n6oMPxU2MGJnvicP3\n\ +6kBqfHhfQ2Fvqlf7YjjhgBHh0lqKShVPxIvdatBjVQ76aym5H3GpkigLGkmeyiVo\n\ +VO8oc3cJ1bO96wFRmk7kJbYcEjQyakODPDu4QgWUTwp1Z8Dn41ARMG5OFh6otITL\n\ +XBzj9REkUPkxfS03dBXGr5/LIqvSsnxib1hJ47xnYJXROUsBy3e6T+fYZEEzZa7y\n\ +7tFioHIQ8G/TziPmvFzmQpaWMGiYfoIgX8WoR3GD1diYW+wBaZTW+4SFUZJmRKgq\n\ +TbMNFkMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsGdH5VFn78WsBElMXaMziqFC\n\ +zmilkvr85/QpGCIztI0FdF6xyMBJk/gYs2thwvF+tCCpXoO8mjgJuvJZlwr6fHzK\n\ +Ox5hNUb06AeMtsUzUfFjSZXKrSR+XmclVd+Z6/ie33VhGePOPTKYmJ/PPfTT9wvT\n\ +93qswcxhA+oX5yqLbU3uDPF1ZnJaEeD/YN45K/4eEA4/0SDXaWW14OScdS2LV0Bc\n\ +YmsbkPVNYZn37FlY7e2Z4FUphh0A7yME2Eh/e57QxWrJ1wubdzGnX8mrABc67ADU\n\ +U5r9tlTRqMs7FGOk6QS2Cxp4pqeVQsrPts4OEwyPUyb3LfFNo3+sP111D9zEow==\n\ +-----END CERTIFICATE-----\n"; + +const std::string Cryptor::cPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\n\ +MIIEowIBAAKCAQEAz3XWY2dR/H5Ym3G6TToY7uRdFb+BdRU1AGRsAVmZV1U28ugR\n\ +A22GLZfxYI7Bfqfqgw/FTYwYme+Jw/fqQGp8eF9DYW+qV/tiOOGAEeHSWopKFU/E\n\ +i91q0GNVDvprKbkfcamSKAsaSZ7KJWhU7yhzdwnVs73rAVGaTuQlthwSNDJqQ4M8\n\ +O7hCBZRPCnVnwOfjUBEwbk4WHqi0hMtcHOP1ESRQ+TF9LTd0Fcavn8siq9KyfGJv\n\ +WEnjvGdgldE5SwHLd7pP59hkQTNlrvLu0WKgchDwb9POI+a8XOZClpYwaJh+giBf\n\ +xahHcYPV2Jhb7AFplNb7hIVRkmZEqCpNsw0WQwIDAQABAoIBAB2u7ZLheKCY71Km\n\ +bhKYqnKb6BmxgfNfqmq4858p07/kKG2O+Mg1xooFgHrhUhwuKGbCPee/kNGNrXeF\n\ +pFW9JrwOXVS2pnfaNw6ObUWhuvhLaxgrhqLAdoUEgWoYOHcKzs3zhj8Gf6di+edq\n\ +SyTA8+xnUtVZ6iMRKvP4vtCUqaIgBnXdmQbGINP+/4Qhb5R7XzMt/xPe6uMyAIyC\n\ +y5Fm9HnvekaepaeFEf3bh4NV1iN/R8px6cFc6ELYxIZc/4Xbm91WGqSdB0iSriaZ\n\ +TjgrmaFjSO40tkCaxI9N6DGzJpmpnMn07ifhl2VjnGOYwtyuh6MKEnyLqTrTg9x0\n\ +i3mMwskCgYEA9IyljPRerXxHUAJt+cKOayuXyNt80q9PIcGbyRNvn7qIY6tr5ut+\n\ +ZbaFgfgHdSJ/4nICRq02HpeDJ8oj9BmhTAhcX6c1irH5ICjRlt40qbPwemIcpybt\n\ +mb+DoNYbI8O4dUNGH9IPfGK8dRpOok2m+ftfk94GmykWbZF5CnOKIp8CgYEA2Syc\n\ +5xlKB5Qk2ZkwXIzxbzozSfunHhWWdg4lAbyInwa6Y5GB35UNdNWI8TAKZsN2fKvX\n\ +RFgCjbPreUbREJaM3oZ92o5X4nFxgjvAE1tyRqcPVbdKbYZgtcqqJX06sW/g3r/3\n\ +RH0XPj2SgJIHew9sMzjGWDViMHXLmntI8rVA7d0CgYBOr36JFwvrqERN0ypNpbMr\n\ +epBRGYZVSAEfLGuSzEUrUNqXr019tKIr2gmlIwhLQTmCxApFcXArcbbKs7jTzvde\n\ +PoZyZJvOr6soFNozP/YT8Ijc5/quMdFbmgqhUqLS5CPS3z2N+YnwDNj0mO1aPcAP\n\ +STmcm2DmxdaolJksqrZ0owKBgQCD0KJDWoQmaXKcaHCEHEAGhMrQot/iULQMX7Vy\n\ +gl5iN5E2EgFEFZIfUeRWkBQgH49xSFPWdZzHKWdJKwSGDvrdrcABwdfx520/4MhK\n\ +d3y7CXczTZbtN1zHuoTfUE0pmYBhcx7AATT0YCblxrynosrHpDQvIefBBh5YW3AB\n\ +cKZCOQKBgEM/ixzI/OVSZ0Py2g+XV8+uGQyC5XjQ6cxkVTX3Gs0ZXbemgUOnX8co\n\ +eCXS4VrhEf4/HYMWP7GB5MFUOEVtlLiLM05ruUL7CrphdfgayDXVcTPfk75lLhmu\n\ +KAwp3tIHPoJOQiKNQ3/qks5km/9dujUGU2ARiU3qmxLMdgegFz8e\n\ +-----END RSA PRIVATE KEY-----\n"; + +} +} +} diff --git a/src/Messenger/FrameHeader.cpp b/src/Messenger/FrameHeader.cpp new file mode 100644 index 0000000..1324c2c --- /dev/null +++ b/src/Messenger/FrameHeader.cpp @@ -0,0 +1,78 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +FrameHeader::FrameHeader(const common::DataConstBuffer& buffer) +{ + channelId_ = static_cast(buffer.cdata[0]); + frameType_ = static_cast(buffer.cdata[1] & static_cast(FrameType::BULK)); + encryptionType_ = static_cast(buffer.cdata[1] & static_cast(EncryptionType::ENCRYPTED)); + messageType_ = static_cast(buffer.cdata[1] & static_cast(MessageType::CONTROL)); +} + +FrameHeader::FrameHeader(ChannelId channelId, FrameType frameType, EncryptionType encryptionType, MessageType messageType) + : channelId_(channelId) + , frameType_(frameType) + , encryptionType_(encryptionType) + , messageType_(messageType) +{ + +} + +ChannelId FrameHeader::getChannelId() const +{ + return channelId_; +} + +FrameType FrameHeader::getType() const +{ + return frameType_; +} + +EncryptionType FrameHeader::getEncryptionType() const +{ + return encryptionType_; +} + +MessageType FrameHeader::getMessageType() const +{ + return messageType_; +} + +common::Data FrameHeader::getData() const +{ + common::Data data; + + data.push_back(static_cast(channelId_)); + data.push_back(static_cast(encryptionType_) | static_cast(messageType_) | static_cast(frameType_)); + + return data; +} + +} +} +} diff --git a/src/Messenger/FrameSize.cpp b/src/Messenger/FrameSize.cpp new file mode 100644 index 0000000..352de2f --- /dev/null +++ b/src/Messenger/FrameSize.cpp @@ -0,0 +1,90 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +FrameSize::FrameSize(size_t frameSize, size_t totalSize) + : frameSizeType_(FrameSizeType::EXTENDED) + , frameSize_(frameSize) + , totalSize_(totalSize) +{ + +} + +FrameSize::FrameSize(size_t frameSize) + : frameSizeType_(FrameSizeType::SHORT) + , frameSize_(frameSize) + , totalSize_(0) +{ + +} + +FrameSize::FrameSize(const common::DataConstBuffer& buffer) +{ + if(buffer.size >= 2) + { + frameSizeType_ = FrameSizeType::SHORT; + frameSize_ = boost::endian::big_to_native(reinterpret_cast(buffer.cdata[0])); + } + + if(buffer.size >= 6) + { + frameSizeType_ = FrameSizeType::EXTENDED; + totalSize_ = boost::endian::big_to_native(reinterpret_cast(buffer.cdata[2])); + } +} + +common::Data FrameSize::getData() const +{ + common::Data data; + + uint16_t frameSizeBig = boost::endian::native_to_big(static_cast(frameSize_)); + const common::DataConstBuffer frameSizeBigBuffer(&frameSizeBig, sizeof(frameSizeBig)); + common::copy(data, frameSizeBigBuffer); + + if(frameSizeType_ == FrameSizeType::EXTENDED) + { + uint32_t totalSizeBig = boost::endian::native_to_big(static_cast(totalSize_)); + const common::DataConstBuffer totalSizeBigBuffer(&totalSizeBig, sizeof(totalSizeBig)); + common::copy(data, totalSizeBigBuffer); + } + + return data; +} + +size_t FrameSize::getSize() const +{ + return frameSize_; +} + +size_t FrameSize::getSizeOf(FrameSizeType type) +{ + return type == FrameSizeType::EXTENDED ? 6 : 2; +} + +} +} +} diff --git a/src/Messenger/Message.cpp b/src/Messenger/Message.cpp new file mode 100644 index 0000000..ab4d943 --- /dev/null +++ b/src/Messenger/Message.cpp @@ -0,0 +1,105 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +Message::Message(ChannelId channelId, EncryptionType encryptionType, MessageType type) + : channelId_(channelId) + , encryptionType_(encryptionType) + , type_(type) +{ +} + +Message::Message(Message&& other) + : channelId_(other.channelId_) + , encryptionType_(other.encryptionType_) + , type_(other.type_) + , payload_(std::move(other.payload_)) +{ + +} + +Message& Message::operator=(Message&& other) +{ + channelId_ = std::move(other.channelId_); + encryptionType_ = std::move(other.encryptionType_); + type_ = std::move(other.type_); + payload_ = std::move(other.payload_); + + return *this; +} + +ChannelId Message::getChannelId() const +{ + return channelId_; +} + +EncryptionType Message::getEncryptionType() const +{ + return encryptionType_; +} + +MessageType Message::getType() const +{ + return type_; +} + +common::Data& Message::getPayload() +{ + return payload_; +} + +const common::Data& Message::getPayload() const +{ + return payload_; +} + +void Message::insertPayload(const common::Data& payload) +{ + payload_.insert(payload_.end(), payload.begin(), payload.end()); +} + +void Message::insertPayload(const google::protobuf::Message& message) +{ + auto offset = payload_.size(); + payload_.resize(payload_.size() + message.ByteSize()); + + common::DataBuffer buffer(payload_, offset); + message.SerializeToArray(buffer.data, buffer.size); +} + +void Message::insertPayload(const common::DataConstBuffer& buffer) +{ + common::copy(payload_, buffer); +} + +void Message::insertPayload(common::DataBuffer& buffer) +{ + common::copy(payload_, buffer); +} + +} +} +} diff --git a/src/Messenger/MessageId.cpp b/src/Messenger/MessageId.cpp new file mode 100644 index 0000000..ddc196c --- /dev/null +++ b/src/Messenger/MessageId.cpp @@ -0,0 +1,91 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +MessageId::MessageId(uint16_t id): + id_(id) +{ + +} +MessageId::MessageId(const common::Data& data) +{ + id_ = boost::endian::big_to_native(reinterpret_cast(data[0])); +} + +uint16_t MessageId::getId() const +{ + return id_; +} + +common::Data MessageId::getData() const +{ + const MessageId messageIdBig = boost::endian::native_to_big(id_); + const common::DataConstBuffer messageIdBigBuffer(&messageIdBig, sizeof(messageIdBig)); + return common::createData(messageIdBigBuffer); +} + +bool MessageId::operator>(uint16_t id) const +{ + return id > id_; +} + +bool MessageId::operator<(uint16_t id) const +{ + return id < id_; +} + +bool MessageId::operator==(uint16_t id) const +{ + return id == id_; +} + +MessageId& MessageId::operator=(uint16_t id) +{ + id_ = id; + return *this; +} + +bool MessageId::operator>=(uint16_t id) const +{ + return id >= id_; +} + +bool MessageId::operator<=(uint16_t id) const +{ + return id <= id_; +} + +std::ostream& operator<<(std::ostream& stream, const f1x::aasdk::messenger::MessageId& messageId) +{ + stream << "0x" << std::hex << messageId.getId() << std::dec; + return stream; +} + +} +} +} diff --git a/src/Messenger/MessageInStream.cpp b/src/Messenger/MessageInStream.cpp new file mode 100644 index 0000000..72a666f --- /dev/null +++ b/src/Messenger/MessageInStream.cpp @@ -0,0 +1,158 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +MessageInStream::MessageInStream(boost::asio::io_service& ioService, transport::ITransport::Pointer transport, ICryptor::Pointer cryptor) + : strand_(ioService) + , transport_(std::move(transport)) + , cryptor_(std::move(cryptor)) +{ + +} + +void MessageInStream::startReceive(ReceivePromise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable { + if(promise_ == nullptr) + { + promise_ = std::move(promise); + + auto transportPromise = transport::ITransport::ReceivePromise::defer(strand_); + transportPromise->then( + [this, self = this->shared_from_this()](common::Data data) mutable { + this->receiveFrameHeaderHandler(common::DataConstBuffer(data)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + transport_->receive(FrameHeader::getSizeOf(), std::move(transportPromise)); + } + else + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + } + }); +} + +void MessageInStream::receiveFrameHeaderHandler(const common::DataConstBuffer& buffer) +{ + FrameHeader frameHeader(buffer); + + if(message_ == nullptr) + { + message_ = std::make_shared(frameHeader.getChannelId(), frameHeader.getEncryptionType(), frameHeader.getMessageType()); + } + else if(message_->getChannelId() != frameHeader.getChannelId()) + { + message_.reset(); + promise_->reject(error::Error(error::ErrorCode::MESSENGER_INTERTWINED_CHANNELS)); + promise_.reset(); + return; + } + + recentFrameType_ = frameHeader.getType(); + const size_t frameSize = FrameSize::getSizeOf(frameHeader.getType() == FrameType::FIRST ? FrameSizeType::EXTENDED : FrameSizeType::SHORT); + + auto transportPromise = transport::ITransport::ReceivePromise::defer(strand_); + transportPromise->then( + [this, self = this->shared_from_this()](common::Data data) mutable { + this->receiveFrameSizeHandler(common::DataConstBuffer(data)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + message_.reset(); + promise_->reject(e); + promise_.reset(); + }); + + transport_->receive(frameSize, std::move(transportPromise)); +} + +void MessageInStream::receiveFrameSizeHandler(const common::DataConstBuffer& buffer) +{ + auto transportPromise = transport::ITransport::ReceivePromise::defer(strand_); + transportPromise->then( + [this, self = this->shared_from_this()](common::Data data) mutable { + this->receiveFramePayloadHandler(common::DataConstBuffer(data)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + message_.reset(); + promise_->reject(e); + promise_.reset(); + }); + + FrameSize frameSize(buffer); + transport_->receive(frameSize.getSize(), std::move(transportPromise)); +} + +void MessageInStream::receiveFramePayloadHandler(const common::DataConstBuffer& buffer) +{ + if(message_->getEncryptionType() == EncryptionType::ENCRYPTED) + { + try + { + cryptor_->decrypt(message_->getPayload(), buffer); + } + catch(const error::Error& e) + { + message_.reset(); + promise_->reject(e); + promise_.reset(); + return; + } + } + else + { + message_->insertPayload(buffer); + } + + if(recentFrameType_ == FrameType::BULK || recentFrameType_ == FrameType::LAST) + { + promise_->resolve(std::move(message_)); + promise_.reset(); + } + else + { + auto transportPromise = transport::ITransport::ReceivePromise::defer(strand_); + transportPromise->then( + [this, self = this->shared_from_this()](common::Data data) mutable { + this->receiveFrameHeaderHandler(common::DataConstBuffer(data)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + message_.reset(); + promise_->reject(e); + promise_.reset(); + }); + + transport_->receive(FrameHeader::getSizeOf(), std::move(transportPromise)); + } +} + +} +} +} diff --git a/src/Messenger/MessageInStream.ut.cpp b/src/Messenger/MessageInStream.ut.cpp new file mode 100644 index 0000000..1d215c3 --- /dev/null +++ b/src/Messenger/MessageInStream.ut.cpp @@ -0,0 +1,424 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +using ::testing::_; +using ::testing::SaveArg; +using ::testing::SetArgReferee; +using ::testing::Return; + +class MessageInStreamUnitTest +{ +protected: + MessageInStreamUnitTest() + : transport_(&transportMock_, [](auto*) {}) + , cryptor_(&cryptorMock_, [](auto*) {}) + , receivePromise_(ReceivePromise::defer(ioService_)) + { + receivePromise_->then(std::bind(&ReceivePromiseHandlerMock::onResolve, &receivePromiseHandlerMock_, std::placeholders::_1), + std::bind(&ReceivePromiseHandlerMock::onReject, &receivePromiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + transport::ut::TransportMock transportMock_; + transport::ITransport::Pointer transport_; + CryptorMock cryptorMock_; + ICryptor::Pointer cryptor_; + ReceivePromiseHandlerMock receivePromiseHandlerMock_; + ReceivePromise::Pointer receivePromise_; +}; + + +ACTION(ThrowSSLReadException) +{ + throw error::Error(error::ErrorCode::SSL_READ, 123); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_ReceivePlainMessage, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::BLUETOOTH, FrameType::BULK, EncryptionType::PLAIN, MessageType::SPECIFIC); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data framePayload(1000, 0x5E); + FrameSize frameSize(framePayload.size()); + transport::ITransport::ReceivePromise::Pointer frameSizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::SHORT), _)).WillOnce(SaveArg<1>(&frameSizeTransportPromise)); + frameHeaderTransportPromise->resolve(frameHeader.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer framePayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(framePayload.size(), _)).WillOnce(SaveArg<1>(&framePayloadTransportPromise)); + frameSizeTransportPromise->resolve(frameSize.getData()); + + ioService_.run(); + ioService_.reset(); + + Message::Pointer message; + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).WillOnce(SaveArg<0>(&message)); + framePayloadTransportPromise->resolve(framePayload); + + ioService_.run(); + + BOOST_CHECK(message->getChannelId() == ChannelId::BLUETOOTH); + BOOST_CHECK(message->getEncryptionType() == EncryptionType::PLAIN); + BOOST_CHECK(message->getType() == MessageType::SPECIFIC); + + const auto& payload = message->getPayload(); + BOOST_CHECK_EQUAL_COLLECTIONS(payload.begin(), payload.end(), framePayload.begin(), framePayload.end()); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_ReceiveEncryptedMessage, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::VIDEO, FrameType::BULK, EncryptionType::ENCRYPTED, MessageType::CONTROL); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data framePayload(1000, 0x5E); + FrameSize frameSize(framePayload.size()); + transport::ITransport::ReceivePromise::Pointer frameSizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::SHORT), _)).WillOnce(SaveArg<1>(&frameSizeTransportPromise)); + frameHeaderTransportPromise->resolve(frameHeader.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Promise::Pointer framePayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(framePayload.size(), _)).WillOnce(SaveArg<1>(&framePayloadTransportPromise)); + + common::Data decryptedPayload(500, 0x5F); + EXPECT_CALL(cryptorMock_, decrypt(_, _)).WillOnce(DoAll(SetArgReferee<0>(decryptedPayload), Return(decryptedPayload.size()))); + frameSizeTransportPromise->resolve(frameSize.getData()); + + ioService_.run(); + ioService_.reset(); + + Message::Pointer message; + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).WillOnce(SaveArg<0>(&message)); + framePayloadTransportPromise->resolve(framePayload); + + ioService_.run(); + + BOOST_CHECK(message->getChannelId() == ChannelId::VIDEO); + BOOST_CHECK(message->getEncryptionType() == EncryptionType::ENCRYPTED); + BOOST_CHECK(message->getType() == MessageType::CONTROL); + + const auto& payload = message->getPayload(); + BOOST_CHECK_EQUAL_COLLECTIONS(payload.begin(), payload.end(), decryptedPayload.begin(), decryptedPayload.end()); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_MessageDecryptionFailed, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::VIDEO, FrameType::BULK, EncryptionType::ENCRYPTED, MessageType::CONTROL); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data framePayload(1000, 0x5E); + FrameSize frameSize(framePayload.size()); + transport::ITransport::ReceivePromise::Pointer frameSizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::SHORT), _)).WillOnce(SaveArg<1>(&frameSizeTransportPromise)); + frameHeaderTransportPromise->resolve(frameHeader.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer framePayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(framePayload.size(), _)).WillOnce(SaveArg<1>(&framePayloadTransportPromise)); + + common::Data decryptedPayload(500, 0x5F); + EXPECT_CALL(cryptorMock_, decrypt(_, _)).WillOnce(ThrowSSLReadException()); + frameSizeTransportPromise->resolve(frameSize.getData()); + + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(receivePromiseHandlerMock_, onReject(error::Error(error::ErrorCode::SSL_READ, 123))); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + framePayloadTransportPromise->resolve(framePayload); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_FramePayloadReceiveFailed, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::BLUETOOTH, FrameType::BULK, EncryptionType::PLAIN, MessageType::SPECIFIC); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data framePayload(1000, 0x5E); + FrameSize frameSize(framePayload.size()); + transport::ITransport::ReceivePromise::Pointer frameSizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::SHORT), _)).WillOnce(SaveArg<1>(&frameSizeTransportPromise)); + frameHeaderTransportPromise->resolve(frameHeader.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer framePayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(framePayload.size(), _)).WillOnce(SaveArg<1>(&framePayloadTransportPromise)); + frameSizeTransportPromise->resolve(frameSize.getData()); + + ioService_.run(); + ioService_.reset(); + + error::Error e(error::ErrorCode::USB_TRANSFER, 5); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(e)); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + framePayloadTransportPromise->reject(e); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_FramePayloadSizeReceiveFailed, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::BLUETOOTH, FrameType::BULK, EncryptionType::PLAIN, MessageType::SPECIFIC); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer frameSizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::SHORT), _)).WillOnce(SaveArg<1>(&frameSizeTransportPromise)); + frameHeaderTransportPromise->resolve(frameHeader.getData()); + + ioService_.run(); + ioService_.reset(); + + error::Error e(error::ErrorCode::USB_TRANSFER, 5); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(e)); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + frameSizeTransportPromise->reject(e); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_FrameHeaderReceiveFailed, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::BLUETOOTH, FrameType::BULK, EncryptionType::PLAIN, MessageType::SPECIFIC); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + error::Error e(error::ErrorCode::USB_TRANSFER, 5); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(e)); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + frameHeaderTransportPromise->reject(e); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_ReceiveSplittedMessage, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + FrameHeader frame1Header(ChannelId::BLUETOOTH, FrameType::FIRST, EncryptionType::PLAIN, MessageType::SPECIFIC); + + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).Times(2).WillRepeatedly(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data frame1Payload(1000, 0x5E); + common::Data frame2Payload(2000, 0x5F); + common::Data expectedPayload(frame1Payload.begin(), frame1Payload.end()); + expectedPayload.insert(expectedPayload.end(), frame2Payload.begin(), frame2Payload.end()); + + transport::ITransport::ReceivePromise::Pointer frame1SizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::EXTENDED), _)).WillOnce(SaveArg<1>(&frame1SizeTransportPromise)); + frameHeaderTransportPromise->resolve(frame1Header.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer frame1PayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(frame1Payload.size(), _)).WillOnce(SaveArg<1>(&frame1PayloadTransportPromise)); + FrameSize frame1Size(frame1Payload.size(), frame1Payload.size() + frame2Payload.size()); + frame1SizeTransportPromise->resolve(frame1Size.getData()); + + ioService_.run(); + ioService_.reset(); + + frame1PayloadTransportPromise->resolve(frame1Payload); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer frame2SizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::SHORT), _)).WillOnce(SaveArg<1>(&frame2SizeTransportPromise)); + + FrameHeader frame2Header(ChannelId::BLUETOOTH, FrameType::LAST, EncryptionType::PLAIN, MessageType::SPECIFIC); + frameHeaderTransportPromise->resolve(frame2Header.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer frame2PayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(frame2Payload.size(), _)).WillOnce(SaveArg<1>(&frame2PayloadTransportPromise)); + FrameSize frame2Size(frame2Payload.size()); + frame2SizeTransportPromise->resolve(frame2Size.getData()); + + ioService_.run(); + ioService_.reset(); + + Message::Pointer message; + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).WillOnce(SaveArg<0>(&message)); + frame2PayloadTransportPromise->resolve(frame2Payload); + + ioService_.run(); + + BOOST_CHECK(message->getChannelId() == ChannelId::BLUETOOTH); + BOOST_CHECK(message->getEncryptionType() == EncryptionType::PLAIN); + BOOST_CHECK(message->getType() == MessageType::SPECIFIC); + + const auto& payload = message->getPayload(); + BOOST_CHECK_EQUAL_COLLECTIONS(payload.begin(), payload.end(), expectedPayload.begin(), expectedPayload.end()); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_IntertwinedChannels, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + FrameHeader frame1Header(ChannelId::BLUETOOTH, FrameType::FIRST, EncryptionType::PLAIN, MessageType::SPECIFIC); + + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).Times(2).WillRepeatedly(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data frame1Payload(1000, 0x5E); + common::Data frame2Payload(2000, 0x5F); + + transport::ITransport::ReceivePromise::Pointer frame1SizeTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameSize::getSizeOf(FrameSizeType::EXTENDED), _)).WillOnce(SaveArg<1>(&frame1SizeTransportPromise)); + frameHeaderTransportPromise->resolve(frame1Header.getData()); + + ioService_.run(); + ioService_.reset(); + + transport::ITransport::ReceivePromise::Pointer frame1PayloadTransportPromise; + EXPECT_CALL(transportMock_, receive(frame1Payload.size(), _)).WillOnce(SaveArg<1>(&frame1PayloadTransportPromise)); + FrameSize frame1Size(frame1Payload.size(), frame1Payload.size() + frame2Payload.size()); + frame1SizeTransportPromise->resolve(frame1Size.getData()); + + ioService_.run(); + ioService_.reset(); + + frame1PayloadTransportPromise->resolve(frame1Payload); + + ioService_.run(); + ioService_.reset(); + + FrameHeader frame2Header(ChannelId::VIDEO, FrameType::LAST, EncryptionType::PLAIN, MessageType::SPECIFIC); + + EXPECT_CALL(receivePromiseHandlerMock_, onReject(error::Error(error::ErrorCode::MESSENGER_INTERTWINED_CHANNELS))); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + frameHeaderTransportPromise->resolve(frame2Header.getData()); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageInStream_RejectWhenInProgress, MessageInStreamUnitTest) +{ + MessageInStream::Pointer messageInStream(std::make_shared(ioService_, transport_, cryptor_)); + + FrameHeader frameHeader(ChannelId::BLUETOOTH, FrameType::BULK, EncryptionType::PLAIN, MessageType::SPECIFIC); + transport::ITransport::ReceivePromise::Pointer frameHeaderTransportPromise; + EXPECT_CALL(transportMock_, receive(FrameHeader::getSizeOf(), _)).WillOnce(SaveArg<1>(&frameHeaderTransportPromise)); + + messageInStream->startReceive(std::move(receivePromise_)); + + ReceivePromiseHandlerMock secondReceivePromiseHandlerMock; + auto secondReceivePromise = ReceivePromise::defer(ioService_); + + secondReceivePromise->then(std::bind(&ReceivePromiseHandlerMock::onResolve, &secondReceivePromiseHandlerMock, std::placeholders::_1), + std::bind(&ReceivePromiseHandlerMock::onReject, &secondReceivePromiseHandlerMock, std::placeholders::_1)); + + EXPECT_CALL(secondReceivePromiseHandlerMock, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS))); + EXPECT_CALL(secondReceivePromiseHandlerMock, onResolve(_)).Times(0); + messageInStream->startReceive(std::move(secondReceivePromise)); + ioService_.run(); +} + + +} +} +} +} diff --git a/src/Messenger/MessageOutStream.cpp b/src/Messenger/MessageOutStream.cpp new file mode 100644 index 0000000..48343e2 --- /dev/null +++ b/src/Messenger/MessageOutStream.cpp @@ -0,0 +1,158 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +MessageOutStream::MessageOutStream(boost::asio::io_service& ioService, transport::ITransport::Pointer transport, ICryptor::Pointer cryptor) + : strand_(ioService) + , transport_(std::move(transport)) + , cryptor_(std::move(cryptor)) + , offset_(0) + , remainingSize_(0) +{ + +} + +void MessageOutStream::stream(Message::Pointer message, SendPromise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), message = std::move(message), promise = std::move(promise)]() mutable { + if(promise_ != nullptr) + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + return; + } + + message_ = std::move(message); + promise_ = std::move(promise); + + if(message_->getPayload().size() >= cMaxFramePayloadSize) + { + offset_ = 0; + remainingSize_ = message_->getPayload().size(); + this->streamSplittedMessage(); + } + else + { + try + { + auto data(this->compoundFrame(FrameType::BULK, common::DataConstBuffer(message_->getPayload()))); + + auto transportPromise = transport::ITransport::SendPromise::defer(strand_); + io::PromiseLink<>::forward(*transportPromise, std::move(promise_)); + transport_->send(std::move(data), std::move(transportPromise)); + } + catch(const error::Error& e) + { + promise_->reject(e); + promise_.reset(); + } + + this->reset(); + } + }); +} + +void MessageOutStream::streamSplittedMessage() +{ + try + { + const auto& payload = message_->getPayload(); + auto ptr = &payload[offset_]; + auto size = remainingSize_ < cMaxFramePayloadSize ? remainingSize_ : cMaxFramePayloadSize; + + FrameType frameType = offset_ == 0 ? FrameType::FIRST : (remainingSize_ - size > 0 ? FrameType::MIDDLE : FrameType::LAST); + auto data(this->compoundFrame(frameType, common::DataConstBuffer(ptr, size))); + + auto transportPromise = transport::ITransport::SendPromise::defer(strand_); + + if(frameType == FrameType::LAST) + { + this->reset(); + io::PromiseLink<>::forward(*transportPromise, std::move(promise_)); + } + else + { + transportPromise->then([this, self = this->shared_from_this(), size]() mutable { + offset_ += size; + remainingSize_ -= size; + this->streamSplittedMessage(); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + this->reset(); + promise_->reject(e); + promise_.reset(); + }); + } + + transport_->send(std::move(data), std::move(transportPromise)); + } + catch(const error::Error& e) + { + this->reset(); + promise_->reject(e); + promise_.reset(); + } +} + +common::Data MessageOutStream::compoundFrame(FrameType frameType, const common::DataConstBuffer& payloadBuffer) +{ + const FrameHeader frameHeader(message_->getChannelId(), frameType, message_->getEncryptionType(), message_->getType()); + common::Data data(frameHeader.getData()); + data.resize(data.size() + FrameSize::getSizeOf(frameType == FrameType::FIRST ? FrameSizeType::EXTENDED : FrameSizeType::SHORT)); + size_t payloadSize = 0; + + if(message_->getEncryptionType() == EncryptionType::ENCRYPTED) + { + payloadSize = cryptor_->encrypt(data, payloadBuffer); + } + else + { + data.insert(data.end(), payloadBuffer.cdata, payloadBuffer.cdata + payloadBuffer.size); + payloadSize = payloadBuffer.size; + } + + this->setFrameSize(data, frameType, payloadSize, message_->getPayload().size()); + return data; +} + +void MessageOutStream::setFrameSize(common::Data& data, FrameType frameType, size_t payloadSize, size_t totalSize) +{ + const auto& frameSize = frameType == FrameType::FIRST ? FrameSize(payloadSize, totalSize) : FrameSize(payloadSize); + const auto& frameSizeData = frameSize.getData(); + memcpy(&data[FrameHeader::getSizeOf()], &frameSizeData[0], frameSizeData.size()); +} + +void MessageOutStream::reset() +{ + offset_ = 0; + remainingSize_ = 0; + message_.reset(); +} + +} +} +} diff --git a/src/Messenger/MessageOutStream.ut.cpp b/src/Messenger/MessageOutStream.ut.cpp new file mode 100644 index 0000000..535e1d4 --- /dev/null +++ b/src/Messenger/MessageOutStream.ut.cpp @@ -0,0 +1,229 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +using ::testing::_; +using ::testing::SaveArg; +using ::testing::SetArgReferee; +using ::testing::Return; + +class MessageOutStreamUnitTest +{ +protected: + MessageOutStreamUnitTest() + : transport_(&transportMock_, [](auto*) {}) + , cryptor_(&cryptorMock_, [](auto*) {}) + , sendPromise_(SendPromise::defer(ioService_)) + { + sendPromise_->then(std::bind(&SendPromiseHandlerMock::onResolve, &sendPromiseHandlerMock_), + std::bind(&SendPromiseHandlerMock::onReject, &sendPromiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + transport::ut::TransportMock transportMock_; + transport::ITransport::Pointer transport_; + CryptorMock cryptorMock_; + ICryptor::Pointer cryptor_; + SendPromiseHandlerMock sendPromiseHandlerMock_; + SendPromise::Pointer sendPromise_; +}; + +ACTION(ThrowSSLWriteException) +{ + throw error::Error(error::ErrorCode::SSL_WRITE, 32); +} + +BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendPlainMessage, MessageOutStreamUnitTest) +{ + const FrameHeader frameHeader(ChannelId::INPUT, FrameType::BULK, EncryptionType::PLAIN, MessageType::CONTROL); + const common::Data payload(1000, 0x5E); + const FrameSize frameSize(payload.size()); + + const auto& frameHeaderData = frameHeader.getData(); + common::Data expectedData(frameHeaderData.begin(), frameHeaderData.end()); + + const auto& frameSizeData = frameSize.getData(); + expectedData.insert(expectedData.end(), frameSizeData.begin(), frameSizeData.end()); + expectedData.insert(expectedData.end(), payload.begin(), payload.end()); + + transport::ITransport::SendPromise::Pointer transportSendPromise; + EXPECT_CALL(transportMock_, send(expectedData, _)).WillOnce(SaveArg<1>(&transportSendPromise)); + + Message::Pointer message(std::make_shared(ChannelId::INPUT, EncryptionType::PLAIN, MessageType::CONTROL)); + message->insertPayload(payload); + MessageOutStream::Pointer messageOutStream(std::make_shared(ioService_, transport_, cryptor_)); + messageOutStream->stream(message, std::move(sendPromise_)); + + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + transportSendPromise->resolve(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendEncryptedMessage, MessageOutStreamUnitTest) +{ + const FrameHeader frameHeader(ChannelId::VIDEO, FrameType::BULK, EncryptionType::ENCRYPTED, MessageType::CONTROL); + const common::Data encryptedPayload(2000, 0x5F); + const FrameSize frameSize(encryptedPayload.size()); + + const auto& frameHeaderData = frameHeader.getData(); + common::Data expectedData(frameHeaderData.begin(), frameHeaderData.end()); + + const auto& frameSizeData = frameSize.getData(); + expectedData.insert(expectedData.end(), frameSizeData.begin(), frameSizeData.end()); + expectedData.insert(expectedData.end(), encryptedPayload.begin(), encryptedPayload.end()); + + common::Data encryptedData(expectedData.begin(), expectedData.begin() + FrameHeader::getSizeOf() + FrameSize::getSizeOf(FrameSizeType::SHORT)); + encryptedData.insert(encryptedData.end(), encryptedPayload.begin(), encryptedPayload.end()); + transport::ITransport::SendPromise::Pointer transportSendPromise; + EXPECT_CALL(cryptorMock_, encrypt(_, _)).WillOnce(DoAll(SetArgReferee<0>(encryptedData), Return(encryptedPayload.size()))); + EXPECT_CALL(transportMock_, send(expectedData, _)).WillOnce(SaveArg<1>(&transportSendPromise)); + + Message::Pointer message(std::make_shared(ChannelId::VIDEO, EncryptionType::ENCRYPTED, MessageType::CONTROL)); + const common::Data payload(1000, 0x5E); + message->insertPayload(payload); + MessageOutStream::Pointer messageOutStream(std::make_shared(ioService_, transport_, cryptor_)); + messageOutStream->stream(message, std::move(sendPromise_)); + + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + transportSendPromise->resolve(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageOutStream_MessageEncryptionFailed, MessageOutStreamUnitTest) +{ + Message::Pointer message(std::make_shared(ChannelId::VIDEO, EncryptionType::ENCRYPTED, MessageType::CONTROL)); + const common::Data payload(1000, 0x5E); + message->insertPayload(payload); + MessageOutStream::Pointer messageOutStream(std::make_shared(ioService_, transport_, cryptor_)); + + EXPECT_CALL(cryptorMock_, encrypt(_, _)).WillOnce(ThrowSSLWriteException()); + EXPECT_CALL(sendPromiseHandlerMock_, onReject(error::Error(error::ErrorCode::SSL_WRITE, 32))); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(0); + messageOutStream->stream(message, std::move(sendPromise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendError, MessageOutStreamUnitTest) +{ + Message::Pointer message(std::make_shared(ChannelId::VIDEO, EncryptionType::PLAIN, MessageType::CONTROL)); + const common::Data payload(1000, 0x5E); + message->insertPayload(payload); + MessageOutStream::Pointer messageOutStream(std::make_shared(ioService_, transport_, cryptor_)); + + transport::ITransport::SendPromise::Pointer transportSendPromise; + EXPECT_CALL(transportMock_, send(_, _)).WillOnce(SaveArg<1>(&transportSendPromise)); + messageOutStream->stream(message, std::move(sendPromise_)); + + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER, 513); + EXPECT_CALL(sendPromiseHandlerMock_, onReject(e)); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(0); + + transportSendPromise->reject(e); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(MessageOutStream_SendSplittedMessage, MessageOutStreamUnitTest) +{ + const size_t maxFramePayloadSize = 0x4000; + + const common::Data frame1Payload(maxFramePayloadSize, 0x5E); + const common::Data frame2Payload(maxFramePayloadSize, 0x5E); + + const FrameHeader frame1Header(ChannelId::VIDEO, FrameType::FIRST, EncryptionType::PLAIN, MessageType::CONTROL); + const auto& frame1HeaderData = frame1Header.getData(); + + const FrameSize frame1Size(frame1Payload.size(), frame1Payload.size() + frame2Payload.size()); + const auto& frame1SizeData = frame1Size.getData(); + + const FrameHeader frame2Header(ChannelId::VIDEO, FrameType::LAST, EncryptionType::PLAIN, MessageType::CONTROL); + const auto& frame2HeaderData = frame2Header.getData(); + + const FrameSize frame2Size(frame2Payload.size()); + const auto& frame2SizeData = frame2Size.getData(); + + Message::Pointer message(std::make_shared(ChannelId::VIDEO, EncryptionType::PLAIN, MessageType::CONTROL)); + message->insertPayload(frame1Payload); + message->insertPayload(frame2Payload); + + transport::ITransport::SendPromise::Pointer transportSendPromise; + common::Data expectedData1(frame1HeaderData.begin(), frame1HeaderData.end()); + expectedData1.insert(expectedData1.end(), frame1SizeData.begin(), frame1SizeData.end()); + expectedData1.insert(expectedData1.end(), frame1Payload.begin(), frame1Payload.end()); + EXPECT_CALL(transportMock_, send(expectedData1, _)).WillOnce(SaveArg<1>(&transportSendPromise)); + + MessageOutStream::Pointer messageOutStream(std::make_shared(ioService_, transport_, cryptor_)); + messageOutStream->stream(message, std::move(sendPromise_)); + + ioService_.run(); + ioService_.reset(); + + common::Data expectedData2(frame2HeaderData.begin(), frame2HeaderData.end()); + expectedData2.insert(expectedData2.end(), frame2SizeData.begin(), frame2SizeData.end()); + expectedData2.insert(expectedData2.end(), frame2Payload.begin(), frame2Payload.end()); + EXPECT_CALL(transportMock_, send(expectedData2, _)).WillOnce(SaveArg<1>(&transportSendPromise)); + + auto secondSendPromise = SendPromise::defer(ioService_); + SendPromiseHandlerMock secondSendPromiseHandlerMock; + secondSendPromise->then(std::bind(&SendPromiseHandlerMock::onResolve, &secondSendPromiseHandlerMock), + std::bind(&SendPromiseHandlerMock::onReject, &secondSendPromiseHandlerMock, std::placeholders::_1)); + + EXPECT_CALL(secondSendPromiseHandlerMock, onResolve()).Times(0); + EXPECT_CALL(secondSendPromiseHandlerMock, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS))); + messageOutStream->stream(message, std::move(secondSendPromise)); + + transportSendPromise->resolve(); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + transportSendPromise->resolve(); + ioService_.run(); +} + +} +} +} +} diff --git a/src/Messenger/Messenger.cpp b/src/Messenger/Messenger.cpp new file mode 100644 index 0000000..17b267b --- /dev/null +++ b/src/Messenger/Messenger.cpp @@ -0,0 +1,143 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +Messenger::Messenger(boost::asio::io_service& ioService, IMessageInStream::Pointer messageInStream, IMessageOutStream::Pointer messageOutStream) + : receiveStrand_(ioService) + , sendStrand_(ioService) + , messageInStream_(std::move(messageInStream)) + , messageOutStream_(std::move(messageOutStream)) +{ + +} + +void Messenger::enqueueReceive(ChannelId channelId, ReceivePromise::Pointer promise) +{ + receiveStrand_.dispatch([this, self = this->shared_from_this(), channelId, promise = std::move(promise)]() mutable { + if(!channelReceiveMessageQueue_.empty(channelId)) + { + promise->resolve(std::move(channelReceiveMessageQueue_.pop(channelId))); + } + else + { + channelReceivePromiseQueue_.push(channelId, std::move(promise)); + + if(channelReceivePromiseQueue_.size() == 1) + { + auto inStreamPromise = ReceivePromise::defer(receiveStrand_); + inStreamPromise->then(std::bind(&Messenger::inStreamMessageHandler, this->shared_from_this(), std::placeholders::_1), + std::bind(&Messenger::rejectReceivePromiseQueue, this->shared_from_this(), std::placeholders::_1)); + messageInStream_->startReceive(std::move(inStreamPromise)); + } + } + }); +} + +void Messenger::enqueueSend(Message::Pointer message, SendPromise::Pointer promise) +{ + sendStrand_.dispatch([this, self = this->shared_from_this(), message = std::move(message), promise = std::move(promise)]() mutable { + channelSendPromiseQueue_.emplace_back(std::make_pair(std::move(message), std::move(promise))); + + if(channelSendPromiseQueue_.size() == 1) + { + this->doSend(); + } + }); +} + +void Messenger::inStreamMessageHandler(Message::Pointer message) +{ + auto channelId = message->getChannelId(); + + if(channelReceivePromiseQueue_.isPending(channelId)) + { + channelReceivePromiseQueue_.pop(channelId)->resolve(std::move(message)); + } + else + { + channelReceiveMessageQueue_.push(std::move(message)); + } + + if(!channelReceivePromiseQueue_.empty()) + { + auto inStreamPromise = ReceivePromise::defer(receiveStrand_); + inStreamPromise->then(std::bind(&Messenger::inStreamMessageHandler, this->shared_from_this(), std::placeholders::_1), + std::bind(&Messenger::rejectReceivePromiseQueue, this->shared_from_this(), std::placeholders::_1)); + messageInStream_->startReceive(std::move(inStreamPromise)); + } +} + +void Messenger::doSend() +{ + auto queueElementIter = channelSendPromiseQueue_.begin(); + auto outStreamPromise = SendPromise::defer(sendStrand_); + outStreamPromise->then(std::bind(&Messenger::outStreamMessageHandler, this->shared_from_this(), queueElementIter), + std::bind(&Messenger::rejectSendPromiseQueue, this->shared_from_this(), std::placeholders::_1)); + + messageOutStream_->stream(std::move(queueElementIter->first), std::move(outStreamPromise)); +} + +void Messenger::outStreamMessageHandler(ChannelSendQueue::iterator queueElement) +{ + queueElement->second->resolve(); + channelSendPromiseQueue_.erase(queueElement); + + if(!channelSendPromiseQueue_.empty()) + { + this->doSend(); + } +} + +void Messenger::rejectReceivePromiseQueue(const error::Error& e) +{ + while(!channelReceivePromiseQueue_.empty()) + { + channelReceivePromiseQueue_.pop()->reject(e); + } +} + +void Messenger::rejectSendPromiseQueue(const error::Error& e) +{ + while(!channelSendPromiseQueue_.empty()) + { + auto queueElement(std::move(channelSendPromiseQueue_.front())); + channelSendPromiseQueue_.pop_front(); + queueElement.second->reject(e); + } +} + +void Messenger::stop() +{ + this->rejectReceivePromiseQueue(error::Error(error::ErrorCode::OPERATION_ABORTED)); + this->rejectSendPromiseQueue(error::Error(error::ErrorCode::OPERATION_ABORTED)); + channelReceiveMessageQueue_.clear(); +} + +} +} +} diff --git a/src/Messenger/Messenger.ut.cpp b/src/Messenger/Messenger.ut.cpp new file mode 100644 index 0000000..4c71bb2 --- /dev/null +++ b/src/Messenger/Messenger.ut.cpp @@ -0,0 +1,232 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ +namespace ut +{ + +using ::testing::_; +using ::testing::SaveArg; +using ::testing::Return; + +class MessengerUnitTest +{ +protected: + MessengerUnitTest() + : messageInStream_(&messageInStreamMock_, [](auto*) {}) + , messageOutStream_(&messageOutStreamMock_, [](auto*) {}) + , receivePromise_(ReceivePromise::defer(ioService_)) + , sendPromise_(SendPromise::defer(ioService_)) + { + receivePromise_->then(std::bind(&ReceivePromiseHandlerMock::onResolve, &receivePromiseHandlerMock_, std::placeholders::_1), + std::bind(&ReceivePromiseHandlerMock::onReject, &receivePromiseHandlerMock_, std::placeholders::_1)); + + sendPromise_->then(std::bind(&SendPromiseHandlerMock::onResolve, &sendPromiseHandlerMock_), + std::bind(&SendPromiseHandlerMock::onReject, &sendPromiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + MessageInStreamMock messageInStreamMock_; + IMessageInStream::Pointer messageInStream_; + MessageOutStreamMock messageOutStreamMock_; + IMessageOutStream::Pointer messageOutStream_; + ReceivePromiseHandlerMock receivePromiseHandlerMock_; + ReceivePromise::Pointer receivePromise_; + SendPromiseHandlerMock sendPromiseHandlerMock_; + SendPromise::Pointer sendPromise_; +}; + +BOOST_FIXTURE_TEST_CASE(Messenger_Receive, MessengerUnitTest) +{ + Messenger::Pointer themessenger(std::make_shared(ioService_, messageInStream_, messageOutStream_)); + themessenger->enqueueReceive(ChannelId::MEDIA_AUDIO, std::move(receivePromise_)); + + ReceivePromise::Pointer inStreamReceivePromise; + EXPECT_CALL(messageInStreamMock_, startReceive(_)).WillOnce(SaveArg<0>(&inStreamReceivePromise)); + + ioService_.run(); + ioService_.reset(); + + Message::Pointer message(std::make_shared(ChannelId::MEDIA_AUDIO, EncryptionType::ENCRYPTED, MessageType::SPECIFIC)); + inStreamReceivePromise->resolve(message); + + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(message)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(Messenger_DirectReceive, MessengerUnitTest) +{ + Messenger::Pointer themessenger(std::make_shared(ioService_, messageInStream_, messageOutStream_)); + themessenger->enqueueReceive(ChannelId::MEDIA_AUDIO, std::move(receivePromise_)); + + ReceivePromise::Pointer inStreamReceivePromise; + EXPECT_CALL(messageInStreamMock_, startReceive(_)).WillRepeatedly(SaveArg<0>(&inStreamReceivePromise)); + + ioService_.run(); + ioService_.reset(); + + Message::Pointer inputChannelMessage(std::make_shared(ChannelId::INPUT, EncryptionType::ENCRYPTED, MessageType::SPECIFIC)); + inStreamReceivePromise->resolve(inputChannelMessage); + + ioService_.run(); + ioService_.reset(); + + auto secondReceivePromise = ReceivePromise::defer(ioService_); + secondReceivePromise->then(std::bind(&ReceivePromiseHandlerMock::onResolve, &receivePromiseHandlerMock_, std::placeholders::_1), + std::bind(&ReceivePromiseHandlerMock::onReject, &receivePromiseHandlerMock_, std::placeholders::_1)); + themessenger->enqueueReceive(ChannelId::INPUT, std::move(secondReceivePromise)); + + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(inputChannelMessage)); + + ioService_.run(); + ioService_.reset(); + + Message::Pointer audioChannelMessage(std::make_shared(ChannelId::MEDIA_AUDIO, EncryptionType::ENCRYPTED, MessageType::SPECIFIC)); + inStreamReceivePromise->resolve(audioChannelMessage); + + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(audioChannelMessage)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(Messenger_OnlyOneReceiveAtATime, MessengerUnitTest) +{ + Messenger::Pointer themessenger(std::make_shared(ioService_, messageInStream_, messageOutStream_)); + themessenger->enqueueReceive(ChannelId::MEDIA_AUDIO, std::move(receivePromise_)); + + ReceivePromise::Pointer inStreamReceivePromise; + EXPECT_CALL(messageInStreamMock_, startReceive(_)).WillOnce(SaveArg<0>(&inStreamReceivePromise)); + + ioService_.run(); + ioService_.reset(); + + auto secondReceivePromise = ReceivePromise::defer(ioService_); + secondReceivePromise->then(std::bind(&ReceivePromiseHandlerMock::onResolve, &receivePromiseHandlerMock_, std::placeholders::_1), + std::bind(&ReceivePromiseHandlerMock::onReject, &receivePromiseHandlerMock_, std::placeholders::_1)); + themessenger->enqueueReceive(ChannelId::INPUT, std::move(secondReceivePromise)); + + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER, 41); + inStreamReceivePromise->reject(e); + + EXPECT_CALL(receivePromiseHandlerMock_, onReject(e)).Times(2); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(Messenger_Send, MessengerUnitTest) +{ + Messenger::Pointer themessenger(std::make_shared(ioService_, messageInStream_, messageOutStream_)); + + Message::Pointer message(std::make_shared(ChannelId::MEDIA_AUDIO, EncryptionType::ENCRYPTED, MessageType::SPECIFIC)); + themessenger->enqueueSend(message, std::move(sendPromise_)); + + SendPromise::Pointer outStreamSendPromise; + EXPECT_CALL(messageOutStreamMock_, stream(message, _)).WillOnce(SaveArg<1>(&outStreamSendPromise)); + + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + + outStreamSendPromise->resolve(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(Messenger_OnlyOneSendAtATime, MessengerUnitTest) +{ + Messenger::Pointer themessenger(std::make_shared(ioService_, messageInStream_, messageOutStream_)); + + Message::Pointer message(std::make_shared(ChannelId::MEDIA_AUDIO, EncryptionType::ENCRYPTED, MessageType::SPECIFIC)); + themessenger->enqueueSend(message, std::move(sendPromise_)); + + SendPromise::Pointer outStreamSendPromise; + EXPECT_CALL(messageOutStreamMock_, stream(message, _)).Times(2).WillRepeatedly(SaveArg<1>(&outStreamSendPromise)); + + ioService_.run(); + ioService_.reset(); + + auto secondSendPromise = SendPromise::defer(ioService_); + secondSendPromise->then(std::bind(&SendPromiseHandlerMock::onResolve, &sendPromiseHandlerMock_), + std::bind(&SendPromiseHandlerMock::onReject, &sendPromiseHandlerMock_, std::placeholders::_1)); + themessenger->enqueueSend(message, std::move(secondSendPromise)); + + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(2); + outStreamSendPromise->resolve(); + ioService_.run(); + ioService_.reset(); + + outStreamSendPromise->resolve(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(Messenger_SendFailed, MessengerUnitTest) +{ + Messenger::Pointer themessenger(std::make_shared(ioService_, messageInStream_, messageOutStream_)); + + Message::Pointer message(std::make_shared(ChannelId::MEDIA_AUDIO, EncryptionType::ENCRYPTED, MessageType::SPECIFIC)); + themessenger->enqueueSend(message, std::move(sendPromise_)); + + SendPromise::Pointer outStreamSendPromise; + EXPECT_CALL(messageOutStreamMock_, stream(message, _)).WillOnce(SaveArg<1>(&outStreamSendPromise)); + + ioService_.run(); + ioService_.reset(); + + auto secondSendPromise = SendPromise::defer(ioService_); + secondSendPromise->then(std::bind(&SendPromiseHandlerMock::onResolve, &sendPromiseHandlerMock_), + std::bind(&SendPromiseHandlerMock::onReject, &sendPromiseHandlerMock_, std::placeholders::_1)); + themessenger->enqueueSend(message, std::move(secondSendPromise)); + + ioService_.run(); + ioService_.reset(); + + error::Error e(error::ErrorCode::USB_TRANSFER, 67); + outStreamSendPromise->reject(e); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(e)).Times(2); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(0); + ioService_.run(); +} + +} +} +} +} diff --git a/src/Messenger/Timestamp.cpp b/src/Messenger/Timestamp.cpp new file mode 100644 index 0000000..5de4e44 --- /dev/null +++ b/src/Messenger/Timestamp.cpp @@ -0,0 +1,55 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace messenger +{ + +Timestamp::Timestamp(ValueType stamp) + : stamp_(stamp) +{ + +} + +Timestamp::Timestamp(const common::DataConstBuffer& buffer) +{ + const ValueType& timestampBig = reinterpret_cast(buffer.cdata[0]); + stamp_ = boost::endian::big_to_native(timestampBig); +} + +common::Data Timestamp::getData() const +{ + const ValueType timestampBig = boost::endian::native_to_big(stamp_); + const common::DataConstBuffer timestampBuffer(×tampBig, sizeof(timestampBig)); + return common::createData(timestampBuffer); +} + +Timestamp::ValueType Timestamp::getValue() const +{ + return stamp_; +} + +} +} +} diff --git a/src/Transport/SSLWrapper.cpp b/src/Transport/SSLWrapper.cpp new file mode 100644 index 0000000..335a7f7 --- /dev/null +++ b/src/Transport/SSLWrapper.cpp @@ -0,0 +1,195 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +SSLWrapper::SSLWrapper() +{ + SSL_library_init(); + SSL_load_error_strings(); + ERR_load_BIO_strings(); + OpenSSL_add_all_algorithms(); +} + +SSLWrapper::~SSLWrapper() +{ + FIPS_mode_set(0); + ENGINE_cleanup(); + CONF_modules_unload(1); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + ERR_remove_state(0); +#endif + ERR_free_strings(); +} + +X509* SSLWrapper::readCertificate(const std::string& certificate) +{ + auto bio = BIO_new_mem_buf(certificate.c_str(), certificate.size()); + X509* x509Certificate = PEM_read_bio_X509_AUX(bio, nullptr, nullptr, nullptr); + BIO_free(bio); + + return x509Certificate; +} + +EVP_PKEY* SSLWrapper::readPrivateKey(const std::string& privateKey) +{ + auto bio = BIO_new_mem_buf(privateKey.c_str(), privateKey.size()); + auto result = PEM_read_bio_PrivateKey (bio, nullptr, nullptr, nullptr); + BIO_free(bio); + + return result; +} + +const SSL_METHOD* SSLWrapper::getMethod() +{ +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + return TLSv1_2_client_method(); +#else + return TLS_client_method(); +#endif +} + +SSL_CTX* SSLWrapper::createContext(const SSL_METHOD* method) +{ + return SSL_CTX_new(method); +} + +bool SSLWrapper::useCertificate(SSL_CTX* context, X509* certificate) +{ + return SSL_CTX_use_certificate(context, certificate) == 1; +} + +bool SSLWrapper::usePrivateKey(SSL_CTX* context, EVP_PKEY* privateKey) +{ + return SSL_CTX_use_PrivateKey(context, privateKey) == 1; +} + +SSL* SSLWrapper::createInstance(SSL_CTX* context) +{ + return SSL_new(context); +} + +bool SSLWrapper::checkPrivateKey(SSL* ssl) +{ + return SSL_check_private_key(ssl) == 1; +} + +std::pair SSLWrapper::createBIOs() +{ + auto readBIO = BIO_new(BIO_s_mem()); + auto writeBIO = BIO_new(BIO_s_mem()); + return std::make_pair(readBIO, writeBIO); +} + +void SSLWrapper::setBIOs(SSL* ssl, const BIOs& bIOs, size_t maxBufferSize) +{ + SSL_set_bio(ssl, bIOs.first, bIOs.second); + BIO_set_write_buf_size(bIOs.first, maxBufferSize); + BIO_set_write_buf_size(bIOs.second, maxBufferSize); +} + +void SSLWrapper::setConnectState(SSL* ssl) +{ + SSL_set_connect_state(ssl); + SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr); +} + +int SSLWrapper::doHandshake(SSL* ssl) +{ + auto result = SSL_do_handshake(ssl); + auto errorCode = SSL_get_error(ssl, result); + + return errorCode; +} + +void SSLWrapper::free(SSL* ssl) +{ + SSL_free(ssl); +} + +void SSLWrapper::free(SSL_CTX* context) +{ + SSL_CTX_free(context); +} + +void SSLWrapper::free(BIO* bio) +{ + BIO_free(bio); +} + +void SSLWrapper::free(X509* certificate) +{ + X509_free(certificate); +} + +void SSLWrapper::free(EVP_PKEY* privateKey) +{ + EVP_PKEY_free(privateKey); +} + +size_t SSLWrapper::bioCtrlPending(BIO* b) +{ + return BIO_ctrl_pending(b); +} + +int SSLWrapper::bioRead(BIO *b, void *data, int len) +{ + return BIO_read(b, data, len); +} + +int SSLWrapper::bioWrite(BIO *b, const void *data, int len) +{ + return BIO_write(b, data, len); +} + +int SSLWrapper::getAvailableBytes(const SSL* ssl) +{ + return SSL_pending(ssl); +} + +int SSLWrapper::sslRead(SSL *ssl, void *buf, int num) +{ + return SSL_read(ssl, buf, num); +} + +int SSLWrapper::sslWrite(SSL *ssl, const void *buf, int num) +{ + return SSL_write(ssl, buf, num); +} + +int SSLWrapper::getError(SSL* ssl, int returnCode) +{ + return SSL_get_error(ssl, returnCode); +} + +} +} +} diff --git a/src/Transport/USBDataSink.cpp b/src/Transport/USBDataSink.cpp new file mode 100644 index 0000000..772054d --- /dev/null +++ b/src/Transport/USBDataSink.cpp @@ -0,0 +1,74 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +USBDataSink::USBDataSink() + : data_(common::cStaticDataSize) +{ +} + +common::DataBuffer USBDataSink::fill() +{ + const auto offset = data_.size(); + data_.resize(data_.size() + cChunkSize); + + return common::DataBuffer(&data_[offset], cChunkSize); +} + +void USBDataSink::commit(common::Data::size_type size) +{ + if(size > cChunkSize) + { + throw error::Error(error::ErrorCode::USB_SINK_COMMIT_OVERFLOW); + } + + data_.resize(data_.size() - (cChunkSize - size)); +} + +common::Data::size_type USBDataSink::getAvailableSize() +{ + return data_.size(); +} + +common::Data USBDataSink::consume(common::Data::size_type size) +{ + if(size > data_.size()) + { + throw error::Error(error::ErrorCode::USB_SINK_CONSUME_UNDERFLOW); + } + + common::Data data; + common::copy(data, common::DataConstBuffer(&data_[0], size)); + data_.erase(data_.begin(), data_.begin() + size); + + return data; +} + +} +} +} diff --git a/src/Transport/USBTransport.cpp b/src/Transport/USBTransport.cpp new file mode 100644 index 0000000..89505d5 --- /dev/null +++ b/src/Transport/USBTransport.cpp @@ -0,0 +1,155 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ + +USBTransport::USBTransport(boost::asio::io_service& ioService, usb::IAOAPDevice::Pointer aoapDevice) + : aoapDevice_(std::move(aoapDevice)) + , receiveStrand_(ioService) + , sendStrand_(ioService) +{} + +void USBTransport::receive(size_t size, ReceivePromise::Pointer promise) +{ + receiveStrand_.dispatch([this, self = this->shared_from_this(), size, promise = std::move(promise)]() mutable { + receiveQueue_.emplace_back(std::make_pair(size, std::move(promise))); + + if(receiveQueue_.size() == 1) + { + try + { + this->distributeReceivedData(); + } + catch(const error::Error& e) + { + this->rejectReceivePromises(e); + } + } + }); +} + +void USBTransport::receiveHandler(size_t bytesTransferred) +{ + try + { + usbReceivedDataSink_.commit(bytesTransferred); + this->distributeReceivedData(); + } + catch(const error::Error& e) + { + this->rejectReceivePromises(e); + } +} + +void USBTransport::distributeReceivedData() +{ + for(auto queueElement = receiveQueue_.begin(); queueElement != receiveQueue_.end();) + { + if(usbReceivedDataSink_.getAvailableSize() < queueElement->first) + { + auto buffer = usbReceivedDataSink_.fill(); + + auto usbEndpointPromise = usb::IUSBEndpoint::Promise::defer(receiveStrand_); + usbEndpointPromise->then(std::bind(&USBTransport::receiveHandler, this->shared_from_this(), std::placeholders::_1), + std::bind(&USBTransport::rejectReceivePromises, this->shared_from_this(), std::placeholders::_1)); + aoapDevice_->getInEndpoint().bulkTransfer(buffer, cReceiveTimeoutMs, std::move(usbEndpointPromise)); + break; + } + else + { + auto data(usbReceivedDataSink_.consume(queueElement->first)); + queueElement->second->resolve(std::move(data)); + queueElement = receiveQueue_.erase(queueElement); + } + } +} + +void USBTransport::rejectReceivePromises(const error::Error& e) +{ + for(auto& queueElement : receiveQueue_) + { + queueElement.second->reject(e); + } + + receiveQueue_.clear(); +} + +void USBTransport::send(common::Data data, SendPromise::Pointer promise) +{ + sendStrand_.dispatch([this, self = this->shared_from_this(), data = std::move(data), promise = std::move(promise)]() mutable { + sendQueue_.emplace_back(std::make_pair(std::move(data), std::move(promise))); + + if(sendQueue_.size() == 1) + { + this->doSend(sendQueue_.begin(), 0); + } + }); +} + +void USBTransport::doSend(OutTransferQueue::iterator queueElementIter, common::Data::size_type offset) +{ + auto usbEndpointPromise = usb::IUSBEndpoint::Promise::defer(sendStrand_); + usbEndpointPromise->then([this, self = this->shared_from_this(), queueElementIter, offset](size_t bytesTransferred) mutable { + this->sendHandler(queueElementIter, offset, bytesTransferred); + }, + [this, self = this->shared_from_this(), queueElementIter](const error::Error& e) mutable { + queueElementIter->second->reject(e); + sendQueue_.erase(queueElementIter); + + if(!sendQueue_.empty()) + { + this->doSend(sendQueue_.begin(), 0); + } + }); + aoapDevice_->getOutEndpoint().bulkTransfer(common::DataBuffer(queueElementIter->first, offset), cSendTimeoutMs, std::move(usbEndpointPromise)); +} + +void USBTransport::sendHandler(OutTransferQueue::iterator queueElementIter, common::Data::size_type offset, size_t bytesTransferred) +{ + if(offset + bytesTransferred < queueElementIter->first.size()) + { + this->doSend(queueElementIter, offset + bytesTransferred); + } + else + { + queueElementIter->second->resolve(); + sendQueue_.erase(queueElementIter); + + if(!sendQueue_.empty()) + { + this->doSend(sendQueue_.begin(), 0); + } + } +} + +void USBTransport::stop() +{ + aoapDevice_->getInEndpoint().cancelTransfers(); + aoapDevice_->getOutEndpoint().cancelTransfers(); +} + +} +} +} diff --git a/src/Transport/USBTransport.ut.cpp b/src/Transport/USBTransport.ut.cpp new file mode 100644 index 0000000..7205271 --- /dev/null +++ b/src/Transport/USBTransport.ut.cpp @@ -0,0 +1,318 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace transport +{ +namespace ut +{ + +using ::testing::ReturnRef; +using ::testing::SaveArg; +using ::testing::_; +using ::testing::AtLeast; + +class USBTransportUnitTest +{ +protected: + USBTransportUnitTest() + : receivePromise_(ITransport::ReceivePromise::defer(ioService_)) + , sendPromise_(ITransport::SendPromise::defer(ioService_)) + , aoapDevice_(&aoapDeviceMock_, [](auto*) {}) + { + EXPECT_CALL(aoapDeviceMock_, getInEndpoint()).WillRepeatedly(ReturnRef(inEndpointMock_)); + EXPECT_CALL(aoapDeviceMock_, getOutEndpoint()).WillRepeatedly(ReturnRef(outEndpointMock_)); + + receivePromise_->then(std::bind(&TransportReceivePromiseHandlerMock::onResolve, &receivePromiseHandlerMock_, std::placeholders::_1), + std::bind(&TransportReceivePromiseHandlerMock::onReject, &receivePromiseHandlerMock_, std::placeholders::_1)); + + sendPromise_->then(std::bind(&TransportSendPromiseHandlerMock::onResolve, &sendPromiseHandlerMock_), + std::bind(&TransportSendPromiseHandlerMock::onReject, &sendPromiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + usb::ut::USBEndpointMock inEndpointMock_; + usb::ut::USBEndpointMock outEndpointMock_; + TransportReceivePromiseHandlerMock receivePromiseHandlerMock_; + ITransport::ReceivePromise::Pointer receivePromise_; + TransportSendPromiseHandlerMock sendPromiseHandlerMock_; + ITransport::SendPromise::Pointer sendPromise_; + usb::ut::AOAPDeviceMock aoapDeviceMock_; + usb::IAOAPDevice::Pointer aoapDevice_; +}; + +BOOST_FIXTURE_TEST_CASE(USBTransport_ReceiveAtOnce, USBTransportUnitTest) +{ + const size_t receiveSize = 100; + + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer dataBuffer; + EXPECT_CALL(inEndpointMock_, bulkTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&dataBuffer), SaveArg<2>(&usbEndpointPromise))); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + transport->receive(receiveSize, std::move(receivePromise_)); + ioService_.run(); + ioService_.reset(); + + BOOST_TEST(dataBuffer.size >= receiveSize); + common::Data expectedData(receiveSize, 0x5E); + std::copy(expectedData.begin(), expectedData.end(), dataBuffer.data); + + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(expectedData)).Times(1); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + usbEndpointPromise->resolve(receiveSize); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_ReceiveInPieces, USBTransportUnitTest) +{ + const size_t stepsCount = 100; + const size_t receiveSize = 1000 * stepsCount; + const size_t stepSize = receiveSize / stepsCount; + + USBTransport::Pointer transport(std::make_shared(ioService_, std::move(aoapDevice_))); + transport->receive(receiveSize, std::move(receivePromise_)); + + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer dataBuffer; + EXPECT_CALL(inEndpointMock_, bulkTransfer(_, _, _)).Times(AtLeast(stepsCount)) + .WillRepeatedly(DoAll(SaveArg<0>(&dataBuffer), SaveArg<2>(&usbEndpointPromise))); + + common::Data expectedData(receiveSize, 0x5E); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(expectedData)).Times(1); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + + for(size_t i = 0; i < stepsCount; ++i) + { + ioService_.run(); + ioService_.reset(); + + BOOST_TEST(dataBuffer.size >= stepSize); + + std::fill(dataBuffer.data, dataBuffer.data + stepSize, 0x5E); + usbEndpointPromise->resolve(stepSize); + ioService_.run(); + } +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_OnlyOneReceiveAtATime, USBTransportUnitTest) +{ + const size_t receiveSize = 200; + const size_t stepSize = receiveSize / 2; + + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer dataBuffer; + EXPECT_CALL(inEndpointMock_, bulkTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&dataBuffer), SaveArg<2>(&usbEndpointPromise))); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + transport->receive(stepSize, std::move(receivePromise_)); + ioService_.run(); + ioService_.reset(); + + BOOST_TEST(dataBuffer.size >= receiveSize); + std::fill(dataBuffer.data, dataBuffer.data + stepSize, 0x5E); + std::fill(dataBuffer.data + stepSize, dataBuffer.data + receiveSize, 0x5F); + + auto secondPromise = ITransport::ReceivePromise::defer(ioService_); + TransportReceivePromiseHandlerMock secondPromiseHandlerMock; + secondPromise->then(std::bind(&TransportReceivePromiseHandlerMock::onResolve, &secondPromiseHandlerMock, std::placeholders::_1), + std::bind(&TransportReceivePromiseHandlerMock::onReject, &secondPromiseHandlerMock, std::placeholders::_1)); + + transport->receive(stepSize, std::move(secondPromise)); + ioService_.run(); + ioService_.reset(); + + common::Data expectedData(stepSize, 0x5E); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(expectedData)).Times(1); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(_)).Times(0); + + common::Data secondExpectedData(stepSize, 0x5F); + EXPECT_CALL(secondPromiseHandlerMock, onResolve(secondExpectedData)).Times(1); + EXPECT_CALL(secondPromiseHandlerMock, onReject(_)).Times(0); + + usbEndpointPromise->resolve(receiveSize); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_ReceiveError, USBTransportUnitTest) +{ + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(inEndpointMock_, bulkTransfer(_, _, _)).WillOnce(SaveArg<2>(&usbEndpointPromise)); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + transport->receive(1000, std::move(receivePromise_)); + + auto secondPromise = ITransport::ReceivePromise::defer(ioService_); + secondPromise->then(std::bind(&TransportReceivePromiseHandlerMock::onResolve, &receivePromiseHandlerMock_, std::placeholders::_1), + std::bind(&TransportReceivePromiseHandlerMock::onReject, &receivePromiseHandlerMock_, std::placeholders::_1)); + + transport->receive(1000, std::move(secondPromise)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER, 11); + EXPECT_CALL(receivePromiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(receivePromiseHandlerMock_, onReject(e)).Times(2); + + usbEndpointPromise->reject(e); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_Send, USBTransportUnitTest) +{ + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer buffer; + EXPECT_CALL(outEndpointMock_, bulkTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + const common::Data expectedData(1000, 0x5E); + transport->send(expectedData, std::move(sendPromise_)); + ioService_.run(); + ioService_.reset(); + + common::Data actualData(buffer.data, buffer.data + buffer.size); + BOOST_CHECK_EQUAL_COLLECTIONS(actualData.begin(), actualData.end(), expectedData.begin(), expectedData.end()); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + usbEndpointPromise->resolve(expectedData.size()); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_SendInPieces, USBTransportUnitTest) +{ + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer buffer; + EXPECT_CALL(outEndpointMock_, bulkTransfer(_, _, _)).Times(2).WillRepeatedly(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + const common::Data expectedDataPiece1(1000, 0x5E); + const common::Data expectedDataPiece2(2000, 0x5F); + common::Data expectedData(expectedDataPiece1.begin(), expectedDataPiece1.end()); + expectedData.insert(expectedData.end(), expectedDataPiece2.begin(), expectedDataPiece2.end()); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + transport->send(expectedData, std::move(sendPromise_)); + ioService_.run(); + ioService_.reset(); + + common::Data actualDataPiece1(buffer.data, buffer.data + buffer.size); + BOOST_CHECK_EQUAL_COLLECTIONS(actualDataPiece1.begin(), actualDataPiece1.end(), expectedData.begin(), expectedData.end()); + usbEndpointPromise->resolve(expectedDataPiece1.size()); + ioService_.run(); + ioService_.reset(); + + common::Data actualDataPiece2(buffer.data, buffer.data + buffer.size); + BOOST_CHECK_EQUAL_COLLECTIONS(actualDataPiece2.begin(), actualDataPiece2.end(), expectedDataPiece2.begin(), expectedDataPiece2.end()); + usbEndpointPromise->resolve(expectedDataPiece2.size()); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_OnlyOneSendAtATime, USBTransportUnitTest) +{ + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer buffer; + EXPECT_CALL(outEndpointMock_, bulkTransfer(_, _, _)).Times(2).WillRepeatedly(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + const common::Data expectedData1(1000, 0x5E); + transport->send(expectedData1, std::move(sendPromise_)); + ioService_.run(); + ioService_.reset(); + + const common::Data expectedData2(3000, 0x5F); + + auto secondSendPromise = ITransport::SendPromise::defer(ioService_); + TransportSendPromiseHandlerMock secondSendPromiseHandlerMock; + secondSendPromise->then(std::bind(&TransportSendPromiseHandlerMock::onResolve, &secondSendPromiseHandlerMock), + std::bind(&TransportSendPromiseHandlerMock::onReject, &secondSendPromiseHandlerMock, std::placeholders::_1)); + + transport->send(expectedData2, std::move(secondSendPromise)); + ioService_.run(); + ioService_.reset(); + + common::Data actualData1(buffer.data, buffer.data + buffer.size); + BOOST_CHECK_EQUAL_COLLECTIONS(actualData1.begin(), actualData1.end(), expectedData1.begin(), expectedData1.end()); + + EXPECT_CALL(sendPromiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()); + usbEndpointPromise->resolve(expectedData1.size()); + ioService_.run(); + ioService_.reset(); + + common::Data actualData2(buffer.data, buffer.data + buffer.size); + BOOST_CHECK_EQUAL_COLLECTIONS(actualData2.begin(), actualData2.end(), expectedData2.begin(), expectedData2.end()); + + EXPECT_CALL(secondSendPromiseHandlerMock, onReject(_)).Times(0); + EXPECT_CALL(secondSendPromiseHandlerMock, onResolve()); + usbEndpointPromise->resolve(expectedData2.size()); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBTransport_SendError, USBTransportUnitTest) +{ + usb::IUSBEndpoint::Promise::Pointer usbEndpointPromise; + common::DataBuffer buffer; + EXPECT_CALL(outEndpointMock_, bulkTransfer(_, _, _)).Times(2).WillRepeatedly(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + USBTransport::Pointer transport(std::make_shared(ioService_, aoapDevice_)); + const common::Data expectedData1(1000, 0x5E); + transport->send(expectedData1, std::move(sendPromise_)); + ioService_.run(); + ioService_.reset(); + + const common::Data expectedData2(3000, 0x5F); + + auto secondSendPromise = ITransport::SendPromise::defer(ioService_); + TransportSendPromiseHandlerMock secondSendPromiseHandlerMock; + secondSendPromise->then(std::bind(&TransportSendPromiseHandlerMock::onResolve, &secondSendPromiseHandlerMock), + std::bind(&TransportSendPromiseHandlerMock::onReject, &secondSendPromiseHandlerMock, std::placeholders::_1)); + + transport->send(expectedData2, std::move(secondSendPromise)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER, 15); + EXPECT_CALL(sendPromiseHandlerMock_, onReject(e)); + EXPECT_CALL(sendPromiseHandlerMock_, onResolve()).Times(0); + usbEndpointPromise->reject(e); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(secondSendPromiseHandlerMock, onReject(_)).Times(0); + EXPECT_CALL(secondSendPromiseHandlerMock, onResolve()); + usbEndpointPromise->resolve(expectedData2.size()); + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/AOAPDevice.cpp b/src/USB/AOAPDevice.cpp new file mode 100644 index 0000000..f3c9412 --- /dev/null +++ b/src/USB/AOAPDevice.cpp @@ -0,0 +1,127 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AOAPDevice::AOAPDevice(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, DeviceHandle handle, const libusb_interface_descriptor* interfaceDescriptor) + : usbWrapper_(usbWrapper) + , handle_(std::move(handle)) + , interfaceDescriptor_(interfaceDescriptor) +{ + if((interfaceDescriptor->endpoint[0].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) + { + inEndpoint_ = std::make_shared(usbWrapper_, ioService, handle_, interfaceDescriptor_->endpoint[0].bEndpointAddress); + outEndpoint_ = std::make_shared(usbWrapper_, ioService, handle_, interfaceDescriptor_->endpoint[1].bEndpointAddress); + } + else + { + inEndpoint_ = std::make_shared(usbWrapper_, ioService, handle_, interfaceDescriptor_->endpoint[1].bEndpointAddress); + outEndpoint_ = std::make_shared(usbWrapper_, ioService, handle_, interfaceDescriptor_->endpoint[0].bEndpointAddress); + } +} + +AOAPDevice::~AOAPDevice() +{ + inEndpoint_->cancelTransfers(); + outEndpoint_->cancelTransfers(); + usbWrapper_.releaseInterface(handle_, interfaceDescriptor_->bInterfaceNumber); +} + +IUSBEndpoint& AOAPDevice::getInEndpoint() +{ + return *inEndpoint_; +} + +IUSBEndpoint& AOAPDevice::getOutEndpoint() +{ + return *outEndpoint_; +} + +IAOAPDevice::Pointer AOAPDevice::create(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, DeviceHandle handle) +{ + auto configDescriptorHandle = AOAPDevice::getConfigDescriptor(usbWrapper, handle); + auto interface = AOAPDevice::getInterface(configDescriptorHandle); + auto interfaceDescriptor = AOAPDevice::getInterfaceDescriptor(interface); + + if(interfaceDescriptor->bNumEndpoints < 2) + { + throw error::Error(error::ErrorCode::USB_INVALID_DEVICE_ENDPOINTS); + } + + auto result = usbWrapper.claimInterface(handle, interfaceDescriptor->bInterfaceNumber); + + if(result != 0) + { + throw error::Error(error::ErrorCode::USB_CLAIM_INTERFACE, result); + } + + return std::make_unique(usbWrapper, ioService, std::move(handle), interfaceDescriptor); +} + +ConfigDescriptorHandle AOAPDevice::getConfigDescriptor(IUSBWrapper& usbWrapper, DeviceHandle handle) +{ + ConfigDescriptorHandle configDescriptorHandle; + libusb_device* device = usbWrapper.getDevice(handle); + + auto result = usbWrapper.getConfigDescriptor(device, 0, configDescriptorHandle); + if(result != 0) + { + throw error::Error(error::ErrorCode::USB_OBTAIN_CONFIG_DESCRIPTOR, result); + } + + if(configDescriptorHandle == nullptr) + { + throw error::Error(error::ErrorCode::USB_INVALID_CONFIG_DESCRIPTOR, result); + } + + return configDescriptorHandle; +} + +const libusb_interface* AOAPDevice::getInterface(const ConfigDescriptorHandle& configDescriptorHandle) +{ + if(configDescriptorHandle->bNumInterfaces == 0) + { + throw error::Error(error::ErrorCode::USB_EMPTY_INTERFACES); + } + + return &(configDescriptorHandle->interface[0]); +} + +const libusb_interface_descriptor* AOAPDevice::getInterfaceDescriptor(const libusb_interface* interface) +{ + if(interface->num_altsetting == 0) + { + throw error::Error(error::ErrorCode::USB_OBTAIN_INTERFACE_DESCRIPTOR); + } + + return &interface->altsetting[0]; +} + +} +} +} diff --git a/src/USB/AOAPDevice.ut.cpp b/src/USB/AOAPDevice.ut.cpp new file mode 100644 index 0000000..eea6d0b --- /dev/null +++ b/src/USB/AOAPDevice.ut.cpp @@ -0,0 +1,79 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +BOOST_AUTO_TEST_CASE(AOAPDevice_OutEndpointFirst) +{ + USBWrapperMock usbWrapperMock; + boost::asio::io_service ioService; + USBWrapperMock::DummyDeviceHandle dummyDeviceHandle; + DeviceHandle deviceHandle(reinterpret_cast(&dummyDeviceHandle), [](auto*) {}); + + libusb_endpoint_descriptor endpointDescriptor[2]; + endpointDescriptor[0].bEndpointAddress = LIBUSB_ENDPOINT_OUT + 4; + endpointDescriptor[1].bEndpointAddress = LIBUSB_ENDPOINT_IN + 6; + + libusb_interface_descriptor interfaceDescriptor; + interfaceDescriptor.bInterfaceNumber = 55; + interfaceDescriptor.bNumEndpoints = 2; + interfaceDescriptor.endpoint = endpointDescriptor; + + EXPECT_CALL(usbWrapperMock, releaseInterface(deviceHandle, interfaceDescriptor.bInterfaceNumber)); + AOAPDevice aoapDevice(usbWrapperMock, ioService, deviceHandle, &interfaceDescriptor); + BOOST_TEST(endpointDescriptor[0].bEndpointAddress == aoapDevice.getOutEndpoint().getAddress()); + BOOST_TEST(endpointDescriptor[1].bEndpointAddress == aoapDevice.getInEndpoint().getAddress()); +} + +BOOST_AUTO_TEST_CASE(AOAPDevice_InEndpointFirst) +{ + USBWrapperMock usbWrapperMock; + boost::asio::io_service ioService; + USBWrapperMock::DummyDeviceHandle dummyDeviceHandle; + DeviceHandle deviceHandle(reinterpret_cast(&dummyDeviceHandle), [](auto*) {}); + + libusb_endpoint_descriptor endpointDescriptor[2]; + endpointDescriptor[0].bEndpointAddress = LIBUSB_ENDPOINT_IN + 4; + endpointDescriptor[1].bEndpointAddress = LIBUSB_ENDPOINT_OUT + 6; + + libusb_interface_descriptor interfaceDescriptor; + interfaceDescriptor.bInterfaceNumber = 55; + interfaceDescriptor.bNumEndpoints = 2; + interfaceDescriptor.endpoint = endpointDescriptor; + + EXPECT_CALL(usbWrapperMock, releaseInterface(deviceHandle, interfaceDescriptor.bInterfaceNumber)); + AOAPDevice aoapDevice(usbWrapperMock, ioService, deviceHandle, &interfaceDescriptor); + BOOST_TEST(endpointDescriptor[0].bEndpointAddress == aoapDevice.getInEndpoint().getAddress()); + BOOST_TEST(endpointDescriptor[1].bEndpointAddress == aoapDevice.getOutEndpoint().getAddress()); +} + +} +} +} +} diff --git a/src/USB/AccessoryModeProtocolVersionQuery.cpp b/src/USB/AccessoryModeProtocolVersionQuery.cpp new file mode 100644 index 0000000..f2fabc6 --- /dev/null +++ b/src/USB/AccessoryModeProtocolVersionQuery.cpp @@ -0,0 +1,80 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeProtocolVersionQuery::AccessoryModeProtocolVersionQuery(boost::asio::io_service& ioService, IUSBWrapper& usbWrapper, IUSBEndpoint::Pointer usbEndpoint) + : AccessoryModeQuery(ioService, std::move(usbEndpoint)) +{ + data_.resize(8 + sizeof(ProtocolVersion)); + usbWrapper.fillControlSetup(&data_[0], LIBUSB_ENDPOINT_IN | USB_TYPE_VENDOR, ACC_REQ_GET_PROTOCOL, 0, 0, sizeof(ProtocolVersion)); +} + +void AccessoryModeProtocolVersionQuery::start(Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable { + if(promise_ != nullptr) + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + } + else + { + promise_ = std::move(promise); + + auto usbEndpointPromise = IUSBEndpoint::Promise::defer(strand_); + usbEndpointPromise->then([this, self = this->shared_from_this()](size_t bytesTransferred) mutable { + this->protocolVersionHandler(bytesTransferred); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + usbEndpoint_->controlTransfer(common::DataBuffer(data_), cTransferTimeoutMs, std::move(usbEndpointPromise)); + } + }); +} + +void AccessoryModeProtocolVersionQuery::protocolVersionHandler(size_t bytesTransferred) +{ + ProtocolVersion protocolVersion = static_cast(data_[8]); + + if(protocolVersion == 1 || protocolVersion == 2) + { + promise_->resolve(usbEndpoint_); + promise_.reset(); + } + else + { + promise_->reject(error::Error(error::ErrorCode::USB_AOAP_PROTOCOL_VERSION)); + promise_.reset(); + } +} + +} +} +} diff --git a/src/USB/AccessoryModeProtocolVersionQuery.ut.cpp b/src/USB/AccessoryModeProtocolVersionQuery.ut.cpp new file mode 100644 index 0000000..6e654a4 --- /dev/null +++ b/src/USB/AccessoryModeProtocolVersionQuery.ut.cpp @@ -0,0 +1,164 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +using ::testing::_; +using ::testing::SaveArg; +using ::testing::NotNull; + +class AccessoryModeProtocolVersionQueryUnitTest +{ +protected: + AccessoryModeProtocolVersionQueryUnitTest() + : usbEndpointMock_(std::make_shared()) + , usbEndpoint_(usbEndpointMock_.get(), [](auto*) {}) + , promise_(IAccessoryModeQuery::Promise::defer(ioService_)) + { + promise_->then(std::bind(&AccessoryModeQueryPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&AccessoryModeQueryPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + } + + void scenario_ValidProtocolVersion(uint16_t protocolVersion) + { + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_IN | USB_TYPE_VENDOR, ACC_REQ_GET_PROTOCOL, 0, 0, sizeof(protocolVersion))); + + AccessoryModeProtocolVersionQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + reinterpret_cast(buffer.data[8]) = protocolVersion; + usbEndpointPromise->resolve(buffer.size); + + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onResolve(usbEndpoint_)); + ioService_.run(); + } + + boost::asio::io_service ioService_; + USBWrapperMock usbWrapperMock_; + std::shared_ptr usbEndpointMock_; + IUSBEndpoint::Pointer usbEndpoint_; + AccessoryModeQueryPromiseHandlerMock promiseHandlerMock_; + IAccessoryModeQuery::Promise::Pointer promise_; + + static constexpr uint32_t USB_TYPE_VENDOR = 0x40; + static constexpr uint32_t ACC_REQ_GET_PROTOCOL = 51; +}; + +BOOST_FIXTURE_TEST_CASE(AccessoryModeProtocolVersionQuery_ProtcolVersion1, AccessoryModeProtocolVersionQueryUnitTest) +{ + this->scenario_ValidProtocolVersion(1); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeProtocolVersionQuery_ProtcolVersion2, AccessoryModeProtocolVersionQueryUnitTest) +{ + this->scenario_ValidProtocolVersion(2); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeProtocolVersionQuery_InvalidProtocolVersion, AccessoryModeProtocolVersionQueryUnitTest) +{ + const uint16_t protocolVersion = 3; + + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_IN | USB_TYPE_VENDOR, ACC_REQ_GET_PROTOCOL, 0, 0, sizeof(protocolVersion))); + + AccessoryModeProtocolVersionQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + reinterpret_cast(buffer.data[8]) = protocolVersion; + usbEndpointPromise->resolve(buffer.size); + + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_AOAP_PROTOCOL_VERSION))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeProtocolVersionQuery_TransferError, AccessoryModeProtocolVersionQueryUnitTest) +{ + const uint16_t protocolVersion = 1; + + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_IN | USB_TYPE_VENDOR, ACC_REQ_GET_PROTOCOL, 0, 0, sizeof(protocolVersion))); + + AccessoryModeProtocolVersionQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + reinterpret_cast(buffer.data[8]) = protocolVersion; + const error::Error transferError(error::ErrorCode::USB_TRANSFER, LIBUSB_TRANSFER_ERROR); + usbEndpointPromise->reject(transferError); + + EXPECT_CALL(promiseHandlerMock_, onReject(transferError)); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeProtocolVersionQuery_RejectWhenInProgress, AccessoryModeProtocolVersionQueryUnitTest) +{ + const uint16_t protocolVersion = 1; + + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_IN | USB_TYPE_VENDOR, ACC_REQ_GET_PROTOCOL, 0, 0, sizeof(protocolVersion))); + + AccessoryModeProtocolVersionQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + AccessoryModeQueryPromiseHandlerMock secondPromiseHandlerMock; + auto secondPromise = IAccessoryModeQuery::Promise::defer(ioService_); + secondPromise->then(std::bind(&AccessoryModeQueryPromiseHandlerMock::onResolve, &secondPromiseHandlerMock, std::placeholders::_1), + std::bind(&AccessoryModeQueryPromiseHandlerMock::onReject, &secondPromiseHandlerMock, std::placeholders::_1)); + + EXPECT_CALL(secondPromiseHandlerMock, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS))); + EXPECT_CALL(secondPromiseHandlerMock, onResolve(_)).Times(0); + query->start(std::move(secondPromise)); + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/AccessoryModeQuery.cpp b/src/USB/AccessoryModeQuery.cpp new file mode 100644 index 0000000..97cf63a --- /dev/null +++ b/src/USB/AccessoryModeQuery.cpp @@ -0,0 +1,43 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeQuery::AccessoryModeQuery(boost::asio::io_service& ioService, IUSBEndpoint::Pointer usbEndpoint) + : strand_(ioService) + , usbEndpoint_(std::move(usbEndpoint)) +{ + +} + +void AccessoryModeQuery::cancel() +{ + usbEndpoint_->cancelTransfers(); +} + +} +} +} diff --git a/src/USB/AccessoryModeQueryChain.cpp b/src/USB/AccessoryModeQueryChain.cpp new file mode 100644 index 0000000..6ca3ffe --- /dev/null +++ b/src/USB/AccessoryModeQueryChain.cpp @@ -0,0 +1,203 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeQueryChain::AccessoryModeQueryChain(IUSBWrapper& usbWrapper, + boost::asio::io_service& ioService, + IAccessoryModeQueryFactory& queryFactory) + : usbWrapper_(usbWrapper) + , strand_(ioService) + , queryFactory_(queryFactory) +{ + +} + +void AccessoryModeQueryChain::start(DeviceHandle handle, Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), handle = std::move(handle), promise = std::move(promise)]() mutable { + if(promise_ != nullptr) + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + } + else + { + promise_ = std::move(promise); + + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->protocolVersionQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::PROTOCOL_VERSION, + std::make_shared(usbWrapper_, strand_.get_io_service(), std::move(handle)), + std::move(queryPromise)); + } + }); +} + +void AccessoryModeQueryChain::cancel() +{ + if(activeQuery_ != nullptr) + { + activeQuery_->cancel(); + activeQuery_.reset(); + } +} + +void AccessoryModeQueryChain::startQuery(AccessoryModeQueryType queryType, IUSBEndpoint::Pointer usbEndpoint, IAccessoryModeQuery::Promise::Pointer queryPromise) +{ + activeQuery_ = queryFactory_.createQuery(queryType, std::move(usbEndpoint)); + activeQuery_->start(std::move(queryPromise)); +} + +void AccessoryModeQueryChain::protocolVersionQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->manufacturerQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::SEND_MANUFACTURER, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::manufacturerQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->modelQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::SEND_MODEL, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::modelQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->descriptionQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::SEND_DESCRIPTION, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::descriptionQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->versionQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::SEND_VERSION, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::versionQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->uriQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::SEND_URI, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::uriQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->serialQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::SEND_SERIAL, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::serialQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + auto queryPromise = IAccessoryModeQuery::Promise::defer(strand_); + queryPromise->then([this, self = this->shared_from_this()](IUSBEndpoint::Pointer usbEndpoint) mutable { + this->startQueryHandler(std::move(usbEndpoint)); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + this->startQuery(AccessoryModeQueryType::START, + std::move(usbEndpoint), + std::move(queryPromise)); +} + +void AccessoryModeQueryChain::startQueryHandler(IUSBEndpoint::Pointer usbEndpoint) +{ + activeQuery_.reset(); + promise_->resolve(usbEndpoint->getDeviceHandle()); + promise_.reset(); +} + +} +} +} diff --git a/src/USB/AccessoryModeQueryChain.ut.cpp b/src/USB/AccessoryModeQueryChain.ut.cpp new file mode 100644 index 0000000..2f42abd --- /dev/null +++ b/src/USB/AccessoryModeQueryChain.ut.cpp @@ -0,0 +1,476 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +using ::testing::_; +using ::testing::Return; +using ::testing::SaveArg; +using ::testing::NotNull; + +class AccessoryModeQueryChainUnitTest +{ +protected: + AccessoryModeQueryChainUnitTest() + : deviceHandle_(reinterpret_cast(&dummyDeviceHandle_), [](auto*) {}) + , queryMock_(std::make_shared()) + , promise_(IAccessoryModeQueryChain::Promise::defer(ioService_)) + { + promise_->then(std::bind(&AccessoryModeQueryChainPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&AccessoryModeQueryChainPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + USBWrapperMock usbWrapperMock_; + AccessoryModeQueryFactoryMock queryFactoryMock_; + USBWrapperMock::DummyDeviceHandle dummyDeviceHandle_; + DeviceHandle deviceHandle_; + std::shared_ptr queryMock_; + AccessoryModeQueryChainPromiseHandlerMock promiseHandlerMock_; + IAccessoryModeQueryChain::Promise::Pointer promise_; +}; + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_QueryAOAPDevice, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_DESCRIPTION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_VERSION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_URI, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_SERIAL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::START, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(promiseHandlerMock_, onResolve(deviceHandle_)); + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_ProtocolVersionQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_AOAP_PROTOCOL_VERSION); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_ManufacturerQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_ModelQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_DescriptionQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_DESCRIPTION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_VersionQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_DESCRIPTION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_VERSION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_URIQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_DESCRIPTION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_VERSION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_URI, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_SerialQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_DESCRIPTION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_VERSION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_URI, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_SERIAL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_StartQueryFailed, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MODEL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_DESCRIPTION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_VERSION, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_URI, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_SERIAL, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::START, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + const error::Error e(error::ErrorCode::USB_TRANSFER); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_Cancel, AccessoryModeQueryChainUnitTest) +{ + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + + IUSBEndpoint::Pointer usbEndpoint; + IAccessoryModeQuery::Promise::Pointer queryPromise; + EXPECT_CALL(*queryMock_, start(_)).WillRepeatedly(SaveArg<0>(&queryPromise)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(DoAll(SaveArg<1>(&usbEndpoint), Return(queryMock_))); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + queryPromise->resolve(usbEndpoint); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::SEND_MANUFACTURER, usbEndpoint)).WillOnce(Return(queryMock_)); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(*queryMock_, cancel()); + queryChain->cancel(); + + const error::Error e(error::ErrorCode::OPERATION_ABORTED); + queryPromise->reject(e); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(e)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeQueryChain_RejectWhenInProgress, AccessoryModeQueryChainUnitTest) +{ + EXPECT_CALL(*queryMock_, start(_)); + EXPECT_CALL(queryFactoryMock_, createQuery(AccessoryModeQueryType::PROTOCOL_VERSION, _)).WillOnce(Return(queryMock_)); + AccessoryModeQueryChain::Pointer queryChain(std::make_shared(usbWrapperMock_, ioService_, queryFactoryMock_)); + queryChain->start(deviceHandle_, std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + auto secondPromise = IAccessoryModeQueryChain::Promise::defer(ioService_); + secondPromise->then(std::bind(&AccessoryModeQueryChainPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&AccessoryModeQueryChainPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS))); + queryChain->start(deviceHandle_, std::move(secondPromise)); + + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/AccessoryModeQueryChainFactory.cpp b/src/USB/AccessoryModeQueryChainFactory.cpp new file mode 100644 index 0000000..7f9d3d2 --- /dev/null +++ b/src/USB/AccessoryModeQueryChainFactory.cpp @@ -0,0 +1,46 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeQueryChainFactory::AccessoryModeQueryChainFactory(IUSBWrapper& usbWrapper, + boost::asio::io_service& ioService, + IAccessoryModeQueryFactory& queryFactory) + : usbWrapper_(usbWrapper) + , ioService_(ioService) + , queryFactory_(queryFactory) +{ + +} + +IAccessoryModeQueryChain::Pointer AccessoryModeQueryChainFactory::create() +{ + return std::make_shared(usbWrapper_, ioService_, queryFactory_); +} + +} +} +} diff --git a/src/USB/AccessoryModeQueryFactory.cpp b/src/USB/AccessoryModeQueryFactory.cpp new file mode 100644 index 0000000..c3ea65b --- /dev/null +++ b/src/USB/AccessoryModeQueryFactory.cpp @@ -0,0 +1,81 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeQueryFactory::AccessoryModeQueryFactory(usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService) + : usbWrapper_(usbWrapper) + , ioService_(ioService) +{ + +} + +IAccessoryModeQuery::Pointer AccessoryModeQueryFactory::createQuery(AccessoryModeQueryType queryType, IUSBEndpoint::Pointer usbEndpoint) +{ + switch(queryType) + { + case AccessoryModeQueryType::PROTOCOL_VERSION: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint)); + + case AccessoryModeQueryType::SEND_DESCRIPTION: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint), + AccessoryModeSendStringType::DESCRIPTION, "Android Auto"); + + case AccessoryModeQueryType::SEND_MANUFACTURER: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint), + AccessoryModeSendStringType::MANUFACTURER, "Android"); + + case AccessoryModeQueryType::SEND_MODEL: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint), + AccessoryModeSendStringType::MODEL, "Android Auto"); + + case AccessoryModeQueryType::SEND_SERIAL: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint), + AccessoryModeSendStringType::SERIAL, "HU-AAAAAA001"); + + case AccessoryModeQueryType::SEND_URI: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint), + AccessoryModeSendStringType::URI, "https://f1xstudio.com"); + + case AccessoryModeQueryType::SEND_VERSION: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint), + AccessoryModeSendStringType::VERSION, "2.0.1"); + + case AccessoryModeQueryType::START: + return std::make_shared(ioService_, usbWrapper_, std::move(usbEndpoint)); + + default: + return nullptr; + } +} + +} +} +} diff --git a/src/USB/AccessoryModeSendStringQuery.cpp b/src/USB/AccessoryModeSendStringQuery.cpp new file mode 100644 index 0000000..d589261 --- /dev/null +++ b/src/USB/AccessoryModeSendStringQuery.cpp @@ -0,0 +1,70 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeSendStringQuery::AccessoryModeSendStringQuery(boost::asio::io_service& ioService, IUSBWrapper& usbWrapper, IUSBEndpoint::Pointer usbEndpoint, + AccessoryModeSendStringType sendStringType, const std::string& queryValue) + : AccessoryModeQuery(ioService, std::move(usbEndpoint)) + , sendStringType_(std::move(sendStringType)) +{ + data_.resize(8); + data_.insert(data_.end(), queryValue.begin(), queryValue.end()); + data_.push_back('\0'); + + usbWrapper.fillControlSetup(&data_[0], LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_SEND_STRING, 0, static_cast(sendStringType_), data_.size() - 8); +} + +void AccessoryModeSendStringQuery::start(Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable { + if(promise_ != nullptr) + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + } + else + { + promise_ = std::move(promise); + + auto usbEndpointPromise = IUSBEndpoint::Promise::defer(strand_); + usbEndpointPromise->then([this, self = this->shared_from_this()](size_t bytesTransferred) mutable { + promise_->resolve(usbEndpoint_); + promise_.reset(); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + usbEndpoint_->controlTransfer(common::DataBuffer(data_), cTransferTimeoutMs, std::move(usbEndpointPromise)); + } + }); +} + +} +} +} diff --git a/src/USB/AccessoryModeSendStringQuery.ut.cpp b/src/USB/AccessoryModeSendStringQuery.ut.cpp new file mode 100644 index 0000000..3e9b800 --- /dev/null +++ b/src/USB/AccessoryModeSendStringQuery.ut.cpp @@ -0,0 +1,140 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +using ::testing::_; +using ::testing::SaveArg; +using ::testing::NotNull; + +class AccessoryModeSendStringQueryUnitTest +{ +protected: + AccessoryModeSendStringQueryUnitTest() + : usbEndpointMock_(std::make_shared()) + , usbEndpoint_(usbEndpointMock_.get(), [](auto*) {}) + , promise_(IAccessoryModeQuery::Promise::defer(ioService_)) + { + promise_->then(std::bind(&AccessoryModeQueryPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&AccessoryModeQueryPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + USBWrapperMock usbWrapperMock_; + std::shared_ptr usbEndpointMock_; + IUSBEndpoint::Pointer usbEndpoint_; + AccessoryModeQueryPromiseHandlerMock promiseHandlerMock_; + IAccessoryModeQuery::Promise::Pointer promise_; + + static constexpr uint32_t USB_TYPE_VENDOR = 0x40; + static constexpr uint32_t ACC_REQ_SEND_STRING = 52; +}; + +BOOST_FIXTURE_TEST_CASE(AccessoryModeSendStringQuery_SendString, AccessoryModeSendStringQueryUnitTest) +{ + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + const std::string expectedQueryString = "aasdkTest"; + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_SEND_STRING, 0, static_cast(AccessoryModeSendStringType::MANUFACTURER), expectedQueryString.size() + 1)); + + AccessoryModeSendStringQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_, AccessoryModeSendStringType::MANUFACTURER, expectedQueryString)); + + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + BOOST_TEST(buffer.size == expectedQueryString.size() + 1 + 8); + const std::string actualQueryString(buffer.data + 8, buffer.data + buffer.size - 1); + BOOST_TEST(actualQueryString == expectedQueryString); + + usbEndpointPromise->resolve(buffer.size); + + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onResolve(usbEndpoint_)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeSendStringQuery_TransferError, AccessoryModeSendStringQueryUnitTest) +{ + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + const std::string expectedQueryString = "aasdkTest"; + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_SEND_STRING, 0, static_cast(AccessoryModeSendStringType::MANUFACTURER), expectedQueryString.size() + 1)); + + AccessoryModeSendStringQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_, AccessoryModeSendStringType::MANUFACTURER, expectedQueryString)); + + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + const error::Error transferError(error::ErrorCode::USB_TRANSFER, LIBUSB_TRANSFER_ERROR); + usbEndpointPromise->reject(transferError); + + EXPECT_CALL(promiseHandlerMock_, onReject(transferError)); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeSendStringQuery_RejectWhenInProgress, AccessoryModeSendStringQueryUnitTest) +{ + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + + const std::string expectedQueryString = "aasdkTest"; + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_SEND_STRING, 0, static_cast(AccessoryModeSendStringType::MANUFACTURER), expectedQueryString.size() + 1)); + + AccessoryModeSendStringQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_, AccessoryModeSendStringType::MANUFACTURER, expectedQueryString)); + + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + AccessoryModeQueryPromiseHandlerMock secondPromiseHandlerMock; + auto secondPromise = IAccessoryModeQuery::Promise::defer(ioService_); + secondPromise->then(std::bind(&AccessoryModeQueryPromiseHandlerMock::onResolve, &secondPromiseHandlerMock, std::placeholders::_1), + std::bind(&AccessoryModeQueryPromiseHandlerMock::onReject, &secondPromiseHandlerMock, std::placeholders::_1)); + + EXPECT_CALL(secondPromiseHandlerMock, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS))); + EXPECT_CALL(secondPromiseHandlerMock, onResolve(_)).Times(0); + query->start(std::move(secondPromise)); + + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/AccessoryModeStartQuery.cpp b/src/USB/AccessoryModeStartQuery.cpp new file mode 100644 index 0000000..dd695e8 --- /dev/null +++ b/src/USB/AccessoryModeStartQuery.cpp @@ -0,0 +1,65 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +AccessoryModeStartQuery::AccessoryModeStartQuery(boost::asio::io_service& ioService, IUSBWrapper& usbWrapper, IUSBEndpoint::Pointer usbEndpoint) + : AccessoryModeQuery(ioService, std::move(usbEndpoint)) +{ + data_.resize(8); + usbWrapper.fillControlSetup(&data_[0], LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_START, 0, 0, 0); +} + +void AccessoryModeStartQuery::start(Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable { + if(promise_ != nullptr) + { + promise->reject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS)); + } + else + { + promise_ = std::move(promise); + + auto usbEndpointPromise = IUSBEndpoint::Promise::defer(strand_); + usbEndpointPromise->then([this, self = this->shared_from_this()](size_t bytesTransferred) mutable { + promise_->resolve(usbEndpoint_); + promise_.reset(); + }, + [this, self = this->shared_from_this()](const error::Error& e) mutable { + promise_->reject(e); + promise_.reset(); + }); + + usbEndpoint_->controlTransfer(common::DataBuffer(data_), cTransferTimeoutMs, std::move(usbEndpointPromise)); + } + }); +} + +} +} +} diff --git a/src/USB/AccessoryModeStartQuery.ut.cpp b/src/USB/AccessoryModeStartQuery.ut.cpp new file mode 100644 index 0000000..6715c76 --- /dev/null +++ b/src/USB/AccessoryModeStartQuery.ut.cpp @@ -0,0 +1,126 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +using ::testing::_; +using ::testing::SaveArg; +using ::testing::NotNull; + +class AccessoryModeStartQueryUnitTest +{ +protected: + AccessoryModeStartQueryUnitTest() + : usbEndpointMock_(std::make_shared()) + , usbEndpoint_(usbEndpointMock_.get(), [](auto*) {}) + , promise_(IAccessoryModeQuery::Promise::defer(ioService_)) + { + promise_->then(std::bind(&AccessoryModeQueryPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&AccessoryModeQueryPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + USBWrapperMock usbWrapperMock_; + std::shared_ptr usbEndpointMock_; + IUSBEndpoint::Pointer usbEndpoint_; + AccessoryModeQueryPromiseHandlerMock promiseHandlerMock_; + IAccessoryModeQuery::Promise::Pointer promise_; + + static constexpr uint32_t USB_TYPE_VENDOR = 0x40; + static constexpr uint32_t ACC_REQ_START = 53; +}; + +BOOST_FIXTURE_TEST_CASE(AccessoryModeStartQuery_Start, AccessoryModeStartQueryUnitTest) +{ + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_START, 0, 0, 0)); + + AccessoryModeStartQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onResolve(usbEndpoint_)); + + usbEndpointPromise->resolve(buffer.size); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeStartQuery_TransferError, AccessoryModeStartQueryUnitTest) +{ + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_START, 0, 0, 0)); + + AccessoryModeStartQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + const error::Error transferError(error::ErrorCode::USB_TRANSFER, LIBUSB_TRANSFER_ERROR); + EXPECT_CALL(promiseHandlerMock_, onReject(transferError)); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + + usbEndpointPromise->reject(transferError); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(AccessoryModeStartQuery_RejectWhenInProgress, AccessoryModeStartQueryUnitTest) +{ + common::DataBuffer buffer; + IUSBEndpoint::Promise::Pointer usbEndpointPromise; + EXPECT_CALL(*usbEndpointMock_, controlTransfer(_, _, _)).WillOnce(DoAll(SaveArg<0>(&buffer), SaveArg<2>(&usbEndpointPromise))); + EXPECT_CALL(usbWrapperMock_, fillControlSetup(NotNull(), LIBUSB_ENDPOINT_OUT | USB_TYPE_VENDOR, ACC_REQ_START, 0, 0, 0)); + + AccessoryModeStartQuery::Pointer query(std::make_shared(ioService_, usbWrapperMock_, usbEndpointMock_)); + query->start(std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + AccessoryModeQueryPromiseHandlerMock secondPromiseHandlerMock; + auto secondPromise = IAccessoryModeQuery::Promise::defer(ioService_); + secondPromise->then(std::bind(&AccessoryModeQueryPromiseHandlerMock::onResolve, &secondPromiseHandlerMock, std::placeholders::_1), + std::bind(&AccessoryModeQueryPromiseHandlerMock::onReject, &secondPromiseHandlerMock, std::placeholders::_1)); + + EXPECT_CALL(secondPromiseHandlerMock, onReject(error::Error(error::ErrorCode::OPERATION_IN_PROGRESS))); + EXPECT_CALL(secondPromiseHandlerMock, onResolve(_)).Times(0); + query->start(std::move(secondPromise)); + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/USBEndpoint.cpp b/src/USB/USBEndpoint.cpp new file mode 100644 index 0000000..e692da8 --- /dev/null +++ b/src/USB/USBEndpoint.cpp @@ -0,0 +1,177 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +USBEndpoint::USBEndpoint(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, DeviceHandle handle, uint8_t endpointAddress) + : usbWrapper_(usbWrapper) + , strand_(ioService) + , handle_(std::move(handle)) + , endpointAddress_(endpointAddress) +{ +} + +void USBEndpoint::controlTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) +{ + if(endpointAddress_ != 0) + { + promise->reject(error::Error(error::ErrorCode::USB_INVALID_TRANSFER_METHOD)); + } + else + { + auto* transfer = usbWrapper_.allocTransfer(0); + if(transfer == nullptr) + { + promise->reject(error::Error(error::ErrorCode::USB_TRANSFER_ALLOCATION)); + } + else + { + usbWrapper_.fillControlTransfer(transfer, handle_, buffer.data, &USBEndpoint::transferHandler, this, timeout); + this->transfer(transfer, std::move(promise)); + } + } +} + +void USBEndpoint::interruptTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) +{ + if(endpointAddress_ == 0) + { + promise->reject(error::Error(error::ErrorCode::USB_INVALID_TRANSFER_METHOD)); + } + else + { + auto* transfer = usbWrapper_.allocTransfer(0); + if(transfer == nullptr) + { + promise->reject(error::Error(error::ErrorCode::USB_TRANSFER_ALLOCATION)); + } + else + { + usbWrapper_.fillInterruptTransfer(transfer, handle_, endpointAddress_, buffer.data, buffer.size, &USBEndpoint::transferHandler, this, timeout); + this->transfer(transfer, std::move(promise)); + } + } +} + +void USBEndpoint::bulkTransfer(common::DataBuffer buffer, uint32_t timeout, Promise::Pointer promise) +{ + if(endpointAddress_ == 0) + { + promise->reject(error::Error(error::ErrorCode::USB_INVALID_TRANSFER_METHOD)); + } + else + { + auto* transfer = usbWrapper_.allocTransfer(0); + if(transfer == nullptr) + { + promise->reject(error::Error(error::ErrorCode::USB_TRANSFER_ALLOCATION)); + } + else + { + usbWrapper_.fillBulkTransfer(transfer, handle_, endpointAddress_, buffer.data, buffer.size, &USBEndpoint::transferHandler, this, timeout); + this->transfer(transfer, std::move(promise)); + } + } +} + +void USBEndpoint::transfer(libusb_transfer *transfer, Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), transfer, promise = std::move(promise)]() mutable { + auto submitResult = usbWrapper_.submitTransfer(transfer); + + if(submitResult == 0) + { + // guarantee that endpoint will live until all transfers are finished + if(self_ == nullptr) + { + self_ = self; + } + + transfers_.insert(std::make_pair(transfer, std::move(promise))); + } + else + { + promise->reject(error::Error(error::ErrorCode::USB_TRANSFER, submitResult)); + usbWrapper_.freeTransfer(transfer); + } + }); +} + +uint8_t USBEndpoint::getAddress() +{ + return endpointAddress_; +} + +void USBEndpoint::cancelTransfers() +{ + strand_.dispatch([this, self = this->shared_from_this()]() mutable { + for(const auto& transfer : transfers_) + { + usbWrapper_.cancelTransfer(transfer.first); + } + }); +} + +DeviceHandle USBEndpoint::getDeviceHandle() const +{ + return handle_; +} + +void USBEndpoint::transferHandler(libusb_transfer *transfer) +{ + auto self = reinterpret_cast(transfer->user_data)->shared_from_this(); + + self->strand_.dispatch([self, transfer]() mutable { + if(self->transfers_.count(transfer) == 0) + { + return; + } + + auto promise(std::move(self->transfers_.at(transfer))); + + if(transfer->status == LIBUSB_TRANSFER_COMPLETED) + { + promise->resolve(transfer->actual_length); + } + else + { + promise->reject(error::Error(error::ErrorCode::USB_TRANSFER, transfer->status)); + } + + self->usbWrapper_.freeTransfer(transfer); + self->transfers_.erase(transfer); + + if(self->transfers_.empty()) + { + self->self_.reset(); + } + }); +} + +} +} +} diff --git a/src/USB/USBEndpoint.ut.cpp b/src/USB/USBEndpoint.ut.cpp new file mode 100644 index 0000000..e0cf3b3 --- /dev/null +++ b/src/USB/USBEndpoint.ut.cpp @@ -0,0 +1,294 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +using ::testing::_; +using ::testing::Return; +using ::testing::SaveArg; + +class USBEndpointUnitTest +{ +protected: + USBEndpointUnitTest() + : deviceHandle_(reinterpret_cast(&dummyDeviceHandle_), [](auto*) {}) + , promise_(IUSBEndpoint::Promise::defer(ioService_)) + { + promise_->then(std::bind(&USBEndpointPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&USBEndpointPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + } + + USBWrapperMock usbWrapperMock_; + boost::asio::io_service ioService_; + USBWrapperMock::DummyDeviceHandle dummyDeviceHandle_; + DeviceHandle deviceHandle_; + USBEndpointPromiseHandlerMock promiseHandlerMock_; + IUSBEndpoint::Promise::Pointer promise_; +}; + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_ControlTransferForNonControlEndpoint, USBEndpointUnitTest) +{ + common::Data data(10, 0); + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, 0x01)); + + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_INVALID_TRANSFER_METHOD))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + usbEndpoint->controlTransfer(common::DataBuffer(data), 0, std::move(promise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_BulkTransferForControlEndpoint, USBEndpointUnitTest) +{ + common::Data data(10, 0); + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_)); + + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_INVALID_TRANSFER_METHOD))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + usbEndpoint->bulkTransfer(common::DataBuffer(data), 0, std::move(promise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_InterruptTransferForControlEndpoint, USBEndpointUnitTest) +{ + common::Data data(10, 0); + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_)); + + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_INVALID_TRANSFER_METHOD))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + usbEndpoint->interruptTransfer(common::DataBuffer(data), 0, std::move(promise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_ControlTransferAllocationFailed, USBEndpointUnitTest) +{ + common::Data data(10, 0); + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_)); + + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(nullptr)); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_TRANSFER_ALLOCATION))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + usbEndpoint->controlTransfer(common::DataBuffer(data), 0, std::move(promise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_BulkTransferAllocationFailed, USBEndpointUnitTest) +{ + common::Data data(10, 0); + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, 0x01)); + + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(nullptr)); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_TRANSFER_ALLOCATION))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + usbEndpoint->bulkTransfer(common::DataBuffer(data), 0, std::move(promise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_InterruptTransferAllocationFailed, USBEndpointUnitTest) +{ + common::Data data(10, 0); + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, 0x01)); + + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(nullptr)); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_TRANSFER_ALLOCATION))); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + usbEndpoint->interruptTransfer(common::DataBuffer(data), 0, std::move(promise_)); + + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_BulkTransfer, USBEndpointUnitTest) +{ + const uint8_t endpointAddress = 0x55; + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, endpointAddress)); + + libusb_transfer transfer; + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(&transfer)); + + libusb_transfer_cb_fn transferCallback; + common::Data data(1000, 0); + common::DataBuffer buffer(data); + EXPECT_CALL(usbWrapperMock_, fillBulkTransfer(&transfer, _, endpointAddress, buffer.data, buffer.size, _, _, _)) + .WillOnce(DoAll(SaveArg<5>(&transferCallback), SaveArg<6>(&transfer.user_data))); + EXPECT_CALL(usbWrapperMock_, submitTransfer(&transfer)); + + usbEndpoint->bulkTransfer(common::DataBuffer(data), 0, std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + transfer.actual_length = buffer.size; + transfer.status = LIBUSB_TRANSFER_COMPLETED; + transferCallback(&transfer); + + EXPECT_CALL(usbWrapperMock_, freeTransfer(&transfer)); + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onResolve(buffer.size)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_MultipleBulkTransfers, USBEndpointUnitTest) +{ + const uint8_t endpointAddress = 0x55; + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, endpointAddress)); + + libusb_transfer transfer; + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillRepeatedly(Return(&transfer)); + + const size_t attemptsCount = 1000; + + libusb_transfer_cb_fn transferCallback; + + EXPECT_CALL(usbWrapperMock_, submitTransfer(&transfer)).Times(attemptsCount); + EXPECT_CALL(usbWrapperMock_, freeTransfer(&transfer)).Times(attemptsCount); + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + + for(size_t i = 0; i < attemptsCount; ++i) + { + common::Data data(10000 + attemptsCount, 0); + common::DataBuffer buffer(data); + EXPECT_CALL(usbWrapperMock_, fillBulkTransfer(&transfer, _, endpointAddress, buffer.data, buffer.size, _, _, _)) + .WillOnce(DoAll(SaveArg<5>(&transferCallback), SaveArg<6>(&transfer.user_data))); + EXPECT_CALL(promiseHandlerMock_, onResolve(buffer.size)).Times(1); + + transfer.actual_length = 0; + transfer.status = LIBUSB_TRANSFER_ERROR; + + auto promise = IUSBEndpoint::Promise::defer(ioService_); + promise->then(std::bind(&USBEndpointPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&USBEndpointPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + + usbEndpoint->bulkTransfer(common::DataBuffer(data), 0, std::move(promise)); + ioService_.run(); + ioService_.reset(); + + transfer.actual_length = buffer.size; + transfer.status = LIBUSB_TRANSFER_COMPLETED; + transferCallback(&transfer); + ioService_.run(); + ioService_.reset(); + } +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_ControlTransfer, USBEndpointUnitTest) +{ + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_)); + + libusb_transfer transfer; + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(&transfer)); + + libusb_transfer_cb_fn transferCallback; + common::Data data(100, 0); + common::DataBuffer buffer(data); + EXPECT_CALL(usbWrapperMock_, fillControlTransfer(&transfer, _, buffer.data, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&transferCallback), SaveArg<4>(&transfer.user_data))); + EXPECT_CALL(usbWrapperMock_, submitTransfer(&transfer)); + + usbEndpoint->controlTransfer(common::DataBuffer(data), 0, std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + transfer.actual_length = buffer.size; + transfer.status = LIBUSB_TRANSFER_COMPLETED; + transferCallback(&transfer); + + EXPECT_CALL(usbWrapperMock_, freeTransfer(&transfer)); + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onResolve(buffer.size)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_InterruptTransfer, USBEndpointUnitTest) +{ + const uint8_t endpointAddress = 0x35; + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, endpointAddress)); + + libusb_transfer transfer; + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(&transfer)); + + libusb_transfer_cb_fn transferCallback; + common::Data data(150, 0); + common::DataBuffer buffer(data); + EXPECT_CALL(usbWrapperMock_, fillInterruptTransfer(&transfer, _, endpointAddress, buffer.data, buffer.size, _, _, _)) + .WillOnce(DoAll(SaveArg<5>(&transferCallback), SaveArg<6>(&transfer.user_data))); + EXPECT_CALL(usbWrapperMock_, submitTransfer(&transfer)); + + usbEndpoint->interruptTransfer(common::DataBuffer(data), 0, std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + transfer.actual_length = buffer.size; + transfer.status = LIBUSB_TRANSFER_COMPLETED; + transferCallback(&transfer); + + EXPECT_CALL(usbWrapperMock_, freeTransfer(&transfer)); + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onResolve(buffer.size)); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBEndpoint_BulkTransferFailed, USBEndpointUnitTest) +{ + const uint8_t endpointAddress = 0x55; + USBEndpoint::Pointer usbEndpoint(std::make_shared(usbWrapperMock_, ioService_, deviceHandle_, endpointAddress)); + + libusb_transfer transfer; + EXPECT_CALL(usbWrapperMock_, allocTransfer(0)).WillOnce(Return(&transfer)); + + libusb_transfer_cb_fn transferCallback; + common::Data data(10, 0); + common::DataBuffer buffer(data); + EXPECT_CALL(usbWrapperMock_, fillBulkTransfer(&transfer, _, endpointAddress, buffer.data, buffer.size, _, _, _)) + .WillOnce(DoAll(SaveArg<5>(&transferCallback), SaveArg<6>(&transfer.user_data))); + EXPECT_CALL(usbWrapperMock_, submitTransfer(&transfer)); + + usbEndpoint->bulkTransfer(common::DataBuffer(data), 0, std::move(promise_)); + ioService_.run(); + ioService_.reset(); + + transfer.actual_length = buffer.size; + transfer.status = LIBUSB_TRANSFER_CANCELLED; + transferCallback(&transfer); + + EXPECT_CALL(usbWrapperMock_, freeTransfer(&transfer)); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_TRANSFER, transfer.status))).Times(1); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/USBHub.cpp b/src/USB/USBHub.cpp new file mode 100644 index 0000000..a0dbd90 --- /dev/null +++ b/src/USB/USBHub.cpp @@ -0,0 +1,144 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +USBHub::USBHub(IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, IAccessoryModeQueryChainFactory& queryChainFactory) + : usbWrapper_(usbWrapper) + , strand_(ioService) + , queryChainFactory_(queryChainFactory) +{ +} + +void USBHub::start(Promise::Pointer promise) +{ + strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() { + if(hotplugPromise_ != nullptr) + { + hotplugPromise_->reject(error::Error(error::ErrorCode::OPERATION_ABORTED)); + hotplugPromise_.reset(); + } + + hotplugPromise_ = std::move(promise); + + if(self_ == nullptr) + { + self_ = this->shared_from_this(); + hotplugHandle_ = usbWrapper_.hotplugRegisterCallback(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, &USBHub::hotplugEventsHandler, reinterpret_cast(this)); + } + }); +} + +void USBHub::cancel() +{ + strand_.dispatch([this, self = this->shared_from_this()]() mutable { + if(hotplugPromise_ != nullptr) + { + hotplugPromise_->reject(error::Error(error::ErrorCode::OPERATION_ABORTED)); + hotplugPromise_.reset(); + } + + std::for_each(queryChainQueue_.begin(), queryChainQueue_.end(), std::bind(&IAccessoryModeQueryChain::cancel, std::placeholders::_1)); + + if(self_ != nullptr) + { + hotplugHandle_.reset(); + self_.reset(); + } + }); +} + +int USBHub::hotplugEventsHandler(libusb_context* usbContext, libusb_device* device, libusb_hotplug_event event, void* userData) +{ + if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) + { + auto self = reinterpret_cast(userData)->shared_from_this(); + self->strand_.dispatch(std::bind(&USBHub::handleDevice, self, device)); + } + + return 0; +} + +bool USBHub::isAOAPDevice(const libusb_device_descriptor& deviceDescriptor) const +{ + return deviceDescriptor.idVendor == cGoogleVendorId && + (deviceDescriptor.idProduct == cAOAPId || deviceDescriptor.idProduct == cAOAPWithAdbId); +} + +void USBHub::handleDevice(libusb_device* device) +{ + if(hotplugPromise_ == nullptr) + { + return; + } + + libusb_device_descriptor deviceDescriptor; + if(usbWrapper_.getDeviceDescriptor(device, deviceDescriptor) != 0) + { + return; + } + + DeviceHandle handle; + auto openResult = usbWrapper_.open(device, handle); + + if(openResult != 0) + { + return; + } + + if(this->isAOAPDevice(deviceDescriptor)) + { + hotplugPromise_->resolve(std::move(handle)); + hotplugPromise_.reset(); + } + else + { + ////////// Workaround for VMware + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + ////////// + + queryChainQueue_.emplace_back(queryChainFactory_.create()); + + auto queueElementIter = std::prev(queryChainQueue_.end()); + auto queryChainPromise = IAccessoryModeQueryChain::Promise::defer(strand_); + queryChainPromise->then([this, self = this->shared_from_this(), queueElementIter](DeviceHandle handle) mutable { + queryChainQueue_.erase(queueElementIter); + }, + [this, self = this->shared_from_this(), queueElementIter](const error::Error& e) mutable { + queryChainQueue_.erase(queueElementIter); + }); + + queryChainQueue_.back()->start(std::move(handle), std::move(queryChainPromise)); + } +} + +} +} +} diff --git a/src/USB/USBHub.ut.cpp b/src/USB/USBHub.ut.cpp new file mode 100644 index 0000000..35fca4a --- /dev/null +++ b/src/USB/USBHub.ut.cpp @@ -0,0 +1,244 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ +namespace ut +{ + +using ::testing::_; +using ::testing::Return; +using ::testing::SaveArg; +using ::testing::SetArgReferee; + +class USBHubUnitTest +{ +protected: + USBHubUnitTest() + : queryChain_(&queryChainMock_, [](auto*) {}) + , device_(reinterpret_cast(-1)) + , deviceHandle_(reinterpret_cast(&dummyDeviceHandle_), [](auto*) {}) + , promise_(IUSBHub::Promise::defer(ioService_)) + , rawHotplugCallbacHandle_(-1) + , hotplugCallbackHandle_(&rawHotplugCallbacHandle_, [](auto*) {}) + { + promise_->then(std::bind(&USBHubPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1), + std::bind(&USBHubPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1)); + } + + boost::asio::io_service ioService_; + USBWrapperMock usbWrapperMock_; + AccessoryModeQueryChainFactoryMock queryChainFactoryMock_; + AccessoryModeQueryChainMock queryChainMock_; + IAccessoryModeQueryChain::Pointer queryChain_; + libusb_device* device_; + USBWrapperMock::DummyDeviceHandle dummyDeviceHandle_; + DeviceHandle deviceHandle_; + USBHubPromiseHandlerMock promiseHandlerMock_; + IUSBHub::Promise::Pointer promise_; + libusb_hotplug_callback_handle rawHotplugCallbacHandle_; + HotplugCallbackHandle hotplugCallbackHandle_; + libusb_hotplug_callback_fn hotplugCallback_; + + static constexpr uint16_t cGoogleVendorId = 0x18D1; + static constexpr uint16_t cAOAPId = 0x2D00; + static constexpr uint16_t cAOAPWithAdbId = 0x2D01; +}; + +BOOST_FIXTURE_TEST_CASE(USBHub_QueryDevice, USBHubUnitTest) +{ + void* userData = nullptr; + EXPECT_CALL(usbWrapperMock_, hotplugRegisterCallback(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS, + LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, _, _)) + .WillOnce(DoAll(SaveArg<5>(&hotplugCallback_), SaveArg<6>(&userData), Return(hotplugCallbackHandle_))); + + USBHub::Pointer usbHub(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_)); + usbHub->start(std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + libusb_device_descriptor connectedDeviceDescriptor = {0}; + connectedDeviceDescriptor.idVendor = 123; + connectedDeviceDescriptor.idProduct = 456; + + EXPECT_CALL(usbWrapperMock_, getDeviceDescriptor(device_, _)).WillOnce(DoAll(SetArgReferee<1>(connectedDeviceDescriptor), Return(0))); + EXPECT_CALL(usbWrapperMock_, open(device_, _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle_), Return(0))); + EXPECT_CALL(queryChainFactoryMock_, create()).WillOnce(Return(queryChain_)); + + IAccessoryModeQueryChain::Promise::Pointer queryChainPromise; + EXPECT_CALL(queryChainMock_, start(deviceHandle_, _)).WillOnce(SaveArg<1>(&queryChainPromise)); + + hotplugCallback_(nullptr, device_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, userData); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::OPERATION_ABORTED))); + queryChainPromise->resolve(deviceHandle_); + usbHub->cancel(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBHub_AOAPDeviceConnected, USBHubUnitTest) +{ + void* userData = nullptr; + EXPECT_CALL(usbWrapperMock_, hotplugRegisterCallback(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS, + LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, _, _)) + .WillOnce(DoAll(SaveArg<5>(&hotplugCallback_), SaveArg<6>(&userData), Return(hotplugCallbackHandle_))); + + USBHub::Pointer usbHub(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_)); + usbHub->start(std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + libusb_device_descriptor connectedDeviceDescriptor = {0}; + connectedDeviceDescriptor.idVendor = cGoogleVendorId; + connectedDeviceDescriptor.idProduct = cAOAPWithAdbId; + + EXPECT_CALL(usbWrapperMock_, getDeviceDescriptor(device_, _)).WillOnce(DoAll(SetArgReferee<1>(connectedDeviceDescriptor), Return(0))); + EXPECT_CALL(usbWrapperMock_, open(device_, _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle_), Return(0))); + EXPECT_CALL(promiseHandlerMock_, onResolve(deviceHandle_)); + EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0); + + hotplugCallback_(nullptr, device_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, userData); + ioService_.run(); + ioService_.reset(); + + usbHub->cancel(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBHub_GetDeviceDescriptorFailed, USBHubUnitTest) +{ + void* userData = nullptr; + EXPECT_CALL(usbWrapperMock_, hotplugRegisterCallback(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS, + LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, _, _)) + .WillOnce(DoAll(SaveArg<5>(&hotplugCallback_), SaveArg<6>(&userData), Return(hotplugCallbackHandle_))); + + USBHub::Pointer usbHub(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_)); + usbHub->start(std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + libusb_device_descriptor connectedDeviceDescriptor = {0}; + EXPECT_CALL(usbWrapperMock_, getDeviceDescriptor(device_, _)).WillOnce(DoAll(SetArgReferee<1>(connectedDeviceDescriptor), Return(1))); + + hotplugCallback_(nullptr, device_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, userData); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::OPERATION_ABORTED))); + usbHub->cancel(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBHub_OpenDeviceFailed, USBHubUnitTest) +{ + void* userData = nullptr; + EXPECT_CALL(usbWrapperMock_, hotplugRegisterCallback(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS, + LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, _, _)) + .WillOnce(DoAll(SaveArg<5>(&hotplugCallback_), SaveArg<6>(&userData), Return(hotplugCallbackHandle_))); + + USBHub::Pointer usbHub(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_)); + usbHub->start(std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + libusb_device_descriptor connectedDeviceDescriptor = {0}; + EXPECT_CALL(usbWrapperMock_, getDeviceDescriptor(device_, _)).WillOnce(DoAll(SetArgReferee<1>(connectedDeviceDescriptor), Return(0))); + EXPECT_CALL(usbWrapperMock_, open(device_, _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle_), Return(1))); + + hotplugCallback_(nullptr, device_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, userData); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::OPERATION_ABORTED))); + usbHub->cancel(); + ioService_.run(); +} + +BOOST_FIXTURE_TEST_CASE(USBHub_CancelAllQueryChains, USBHubUnitTest) +{ + void* userData = nullptr; + EXPECT_CALL(usbWrapperMock_, hotplugRegisterCallback(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS, + LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, _, _)) + .WillOnce(DoAll(SaveArg<5>(&hotplugCallback_), SaveArg<6>(&userData), Return(hotplugCallbackHandle_))); + + USBHub::Pointer usbHub(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_)); + usbHub->start(std::move(promise_)); + + ioService_.run(); + ioService_.reset(); + + libusb_device_descriptor connectedDeviceDescriptor = {0}; + connectedDeviceDescriptor.idVendor = 123; + connectedDeviceDescriptor.idProduct = 456; + + EXPECT_CALL(usbWrapperMock_, getDeviceDescriptor(device_, _)).Times(2).WillRepeatedly(DoAll(SetArgReferee<1>(connectedDeviceDescriptor), Return(0))); + EXPECT_CALL(usbWrapperMock_, open(device_, _)).Times(2).WillRepeatedly(DoAll(SetArgReferee<1>(deviceHandle_), Return(0))); + EXPECT_CALL(queryChainFactoryMock_, create()).Times(2).WillRepeatedly(Return(queryChain_)); + + IAccessoryModeQueryChain::Promise::Pointer queryChainPromise[2]; + EXPECT_CALL(queryChainMock_, start(deviceHandle_, _)).WillOnce(SaveArg<1>(&queryChainPromise[0])).WillOnce(SaveArg<1>(&queryChainPromise[1])); + + hotplugCallback_(nullptr, device_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, userData); + ioService_.run(); + ioService_.reset(); + + hotplugCallback_(nullptr, device_, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, userData); + ioService_.run(); + ioService_.reset(); + + EXPECT_CALL(queryChainMock_, cancel()).Times(2); + EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0); + EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::OPERATION_ABORTED))); + usbHub->cancel(); + ioService_.run(); + ioService_.reset(); + + queryChainPromise[0]->reject(error::Error(error::ErrorCode::OPERATION_ABORTED)); + queryChainPromise[1]->reject(error::Error(error::ErrorCode::OPERATION_ABORTED)); + ioService_.run(); +} + +} +} +} +} diff --git a/src/USB/USBWrapper.cpp b/src/USB/USBWrapper.cpp new file mode 100644 index 0000000..b251ec2 --- /dev/null +++ b/src/USB/USBWrapper.cpp @@ -0,0 +1,173 @@ +/* +* This file is part of aasdk library project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* aasdk 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. + +* aasdk 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 aasdk. If not, see . +*/ + +#include + +namespace f1x +{ +namespace aasdk +{ +namespace usb +{ + +USBWrapper::USBWrapper(libusb_context* usbContext) + : usbContext_(usbContext) +{ + +} + +int USBWrapper::releaseInterface(const DeviceHandle& dev_handle, int interface_number) +{ + return libusb_release_interface(dev_handle.get(), interface_number); +} + +libusb_device* USBWrapper::getDevice(const DeviceHandle& dev_handle) +{ + return libusb_get_device(dev_handle.get()); +} + +int USBWrapper::claimInterface(const DeviceHandle& dev_handle, int interface_number) +{ + return libusb_claim_interface(dev_handle.get(), interface_number); +} + +DeviceHandle USBWrapper::openDeviceWithVidPid(uint16_t vendor_id, uint16_t product_id) +{ + auto raw_handle = libusb_open_device_with_vid_pid(usbContext_, vendor_id, product_id); + return raw_handle != nullptr ? DeviceHandle(raw_handle, &libusb_close) : DeviceHandle(); +} + +int USBWrapper::getConfigDescriptor(libusb_device *dev, uint8_t config_index, ConfigDescriptorHandle& config_descriptor_handle) +{ + libusb_config_descriptor* raw_handle = nullptr; + auto result = libusb_get_config_descriptor(dev, config_index, &raw_handle); + + config_descriptor_handle = (result == 0 && raw_handle != nullptr) ? ConfigDescriptorHandle(raw_handle, &libusb_free_config_descriptor) : ConfigDescriptorHandle(); + return result; +} + +void USBWrapper::fillBulkTransfer(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + libusb_fill_bulk_transfer(transfer, dev_handle.get(), endpoint, buffer, length, callback, user_data, timeout); +} + +void USBWrapper::fillInterruptTransfer(libusb_transfer *transfer, + const DeviceHandle& dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + libusb_fill_interrupt_transfer(transfer, dev_handle.get(), endpoint, buffer, length, callback, user_data, timeout); +} + +void USBWrapper::fillControlTransfer( + libusb_transfer *transfer, const DeviceHandle& dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) +{ + libusb_fill_control_transfer(transfer, dev_handle.get(), buffer, callback, user_data, timeout); +} + +int USBWrapper::submitTransfer(libusb_transfer *transfer) +{ + return libusb_submit_transfer(transfer); +} + +int USBWrapper::cancelTransfer(libusb_transfer *transfer) +{ + return libusb_cancel_transfer(transfer); +} + +void USBWrapper::freeTransfer(libusb_transfer *transfer) +{ + libusb_free_transfer(transfer); +} + +ssize_t USBWrapper::getDeviceList(DeviceListHandle& handle) +{ + libusb_device** raw_handle; + auto result = libusb_get_device_list(usbContext_, &raw_handle); + + if(result >= 0) + { + handle = DeviceListHandle(new DeviceList(raw_handle, raw_handle + result), + [raw_handle](auto in_device_list) + { + if(!in_device_list->empty()) + { + libusb_free_device_list(raw_handle, 1); + } + + in_device_list->clear(); + delete in_device_list; + }); + } + else + { + handle = DeviceListHandle(); + } + + return result; +} + +int USBWrapper::open(libusb_device *dev, DeviceHandle& dev_handle) +{ + libusb_device_handle* raw_handle; + auto result = libusb_open(dev, &raw_handle); + + dev_handle = (result == 0 && raw_handle != nullptr) ? DeviceHandle(raw_handle, &libusb_close) : DeviceHandle(); + return result; +} + +void USBWrapper::fillControlSetup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) +{ + libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength); +} + +int USBWrapper::getDeviceDescriptor(libusb_device *dev, libusb_device_descriptor &desc) +{ + return libusb_get_device_descriptor(dev, &desc); +} + +void USBWrapper::handleEvents() +{ + libusb_handle_events(usbContext_); +} + +HotplugCallbackHandle USBWrapper::hotplugRegisterCallback(libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data) +{ + libusb_hotplug_callback_handle raw_handle; + libusb_hotplug_register_callback (usbContext_, events, flags, vendor_id, product_id, dev_class, cb_fn, user_data, &raw_handle); + + HotplugCallbackHandle handle(&raw_handle, [this](auto raw_handle) { libusb_hotplug_deregister_callback(usbContext_, *raw_handle); }); + return handle; +} + +libusb_transfer* USBWrapper::allocTransfer(int iso_packets) +{ + return libusb_alloc_transfer(iso_packets); +} + +} +} +}