#ifndef __FIBRE_LEGACY_OBJECT_MODEL_HPP #define __FIBRE_LEGACY_OBJECT_MODEL_HPP #include #include #include #include #include #include #include // std::variant and std::optional C++ backport #include struct json_value; namespace fibre { struct EndpointOperationResult { StreamStatus status; const uint8_t* tx_end; uint8_t* rx_end; }; // Lower 16 bits are the seqno. Upper 16 bits are all 1 for valid handles // (such that seqno 0 doesn't cause the handle to be 0) using EndpointOperationHandle = uint32_t; struct LegacyProtocolPacketBased; struct LegacyFibreArg { std::string name; std::string protocol_codec; std::string app_codec; size_t protocol_size; size_t app_size; size_t ep_num; }; struct LegacyObject; struct LegacyFunction : Function { LegacyFunction(std::vector inputs, std::vector outputs) : ep_num(0), obj_(nullptr), inputs(inputs), outputs(outputs) {} LegacyFunction(size_t ep_num, LegacyObject* obj, std::vector inputs, std::vector outputs) : ep_num(ep_num), obj_(obj), inputs(inputs), outputs(outputs) {} std::optional call(void**, CallBuffers, Callback, CallBufferRelease>) final; size_t ep_num; // 0 for property read/write/exchange functions LegacyObject* obj_; // null for property read/write/exchange functions (all other functions are associated with one object only) std::vector inputs; std::vector outputs; }; struct FibreInterface; class LegacyObjectClient; struct LegacyFibreAttribute { std::shared_ptr object; }; struct FibreInterface { std::string name; std::unordered_map functions; std::unordered_map attributes; }; struct LegacyObject { LegacyObjectClient* client; size_t ep_num; std::shared_ptr intf; bool known_to_application; }; struct LegacyCallContext { LegacyFunction* func_; size_t progress = 0; //!< 0: expecting more tx data //!< [1...n_inputs]: endpoint operations for sending inputs //!< n_inputs + 1: trigger endpoint operation //!< [n_inputs + 2, n_inputs + 2 + n_outputs]: endpoint operations for receiving outputs //!< n_inputs + 3 + n_outputs: reporting outputs to application EndpointOperationHandle op_handle_ = 0; std::vector tx_buf_; size_t tx_pos_ = 0; std::vector rx_buf_; size_t rx_pos_ = 0; const uint8_t* app_tx_end_; bufptr_t app_rx_buf_; Callback, CallBufferRelease> callback; std::optional ep_result; LegacyObject* obj_; std::optional resume_from_app(CallBuffers, Callback, CallBufferRelease>); void resume_from_protocol(EndpointOperationResult result); struct ContinueWithProtocol { LegacyProtocolPacketBased* client; size_t ep_num; cbufptr_t tx_buf; bufptr_t rx_buf; }; using ContinueWithApp = CallBufferRelease; using ResultFromProtocol = EndpointOperationResult; using ResultFromApp = CallBuffers; struct InternalError {}; // Returns control either to the application or to the next endpoint operation std::variant get_next_task(std::variant continue_from); }; class LegacyObjectClient { public: LegacyObjectClient(LegacyProtocolPacketBased* protocol) : protocol_(protocol) {} void start(Callback> on_found_root_object, Callback> on_lost_root_object); bool transcode(cbufptr_t src, bufptr_t dst, std::string src_codec, std::string dst_codec); // For direct access by LegacyProtocolPacketBased and libfibre.cpp uint16_t json_crc_ = 0; Callback> on_lost_root_object_; std::shared_ptr root_obj_; std::vector> objects_; void* user_data_; // used by libfibre to store the libfibre context pointer LegacyProtocolPacketBased* protocol_; private: std::shared_ptr get_property_interfaces(std::string codec, bool write); std::shared_ptr load_object(json_value list_val); void receive_more_json(); void on_received_json(EndpointOperationResult result); Callback> on_found_root_object_; uint8_t tx_buf_[4] = {0xff, 0xff, 0xff, 0xff}; EndpointOperationHandle op_handle_ = 0; std::vector json_; //std::vector pending_calls_; std::unordered_map> rw_property_interfaces; std::unordered_map> ro_property_interfaces; }; } #endif // __FIBRE_LEGACY_OBJECT_MODEL_HPP