1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef TMESSENGER_H
17 #define TMESSENGER_H
18 
19 #include <condition_variable>
20 #include <functional>
21 #include <list>
22 #include <memory>
23 #include <mutex>
24 #include <string>
25 
26 #include "common.h"
27 #include "socket.h"
28 
29 #define SEPARATOR "|"
30 
31 namespace OHOS {
32 class Request {
33 public:
34     enum class Cmd {
35         QUERY_RESULT,
36     };
37 
Request(Request::Cmd cmd)38     explicit Request(Request::Cmd cmd) : cmd_(cmd) { }
39     std::string Encode() const;
40     static std::shared_ptr<Request> Decode(const std::string &data);
41 
42     Cmd cmd_;
43 };
44 
45 class Response {
46 public:
Response(bool isEncrypt,const std::string & recvData)47     Response(bool isEncrypt, const std::string &recvData) : isEncrypt_(isEncrypt), recvData_(recvData) { }
48     std::string Encode() const;
49     static std::shared_ptr<Response> Decode(const std::string &data);
50     bool isEncrypt_;
51     std::string recvData_;
52 };
53 
54 class Message {
55 public:
56     enum class MsgType : int32_t {
57         MSG_SEQ,
58         MSG_RSP,
59     };
60 
Message(const Request & req)61     explicit Message(const Request &req) : msgType_(MsgType::MSG_SEQ), request(new Request(req)) { }
Message(const Response & rsp)62     explicit Message(const Response &rsp) : msgType_(MsgType::MSG_RSP), response(new Response(rsp)) { }
63     ~Message();
64     std::string Encode() const;
65     static std::shared_ptr<Message> Decode(const std::string &data);
66 
67     MsgType msgType_;
68     union {
69         Request *request;
70         Response *response;
71     };
72 };
73 
74 // class 'TMessenger' is used to notify test result
75 class TMessenger {
76 public:
GetInstance()77     static TMessenger &GetInstance()
78     {
79         static TMessenger instance;
80         return instance;
81     }
82 
83     // Start a client or server
84     int32_t Open(const std::string &pkgName, const std::string &myName, const std::string &peerName, bool isServer);
85     void Close();
86 
87     std::shared_ptr<Response> QueryResult(uint32_t timeout);
88 
89     using OnQueryCallback = std::function<std::shared_ptr<Response>(void)>;
90     void RegisterOnQuery(OnQueryCallback callback);
91 
92 private:
93     TMessenger() = default;
94     TMessenger(const TMessenger &other) = delete;
95     TMessenger(const TMessenger &&other) = delete;
96     TMessenger &operator=(const TMessenger &other) = delete;
97     TMessenger &operator=(const TMessenger &&other) = delete;
98 
99     int32_t StartListen(const std::string &pkgName, const std::string &myName);
100     int32_t StartConnect(const std::string &pkgName, const std::string &myName, const std::string &peerName);
101 
102     static void OnBind(int32_t socket, PeerSocketInfo info);
103     static void OnMessage(int32_t socket, const void *data, uint32_t dataLen);
104     static void OnShutdown(int32_t socket, ShutdownReason reason);
105 
106     void SetConnectSocket(int32_t socket, PeerSocketInfo info);
107     void OnMessageRecv(const std::string &result);
108     void OnRequest();
109 
110     void CloseSocket(int32_t socket);
111 
112     int32_t Send(const Message &msg);
113     std::shared_ptr<Response> WaitResponse(uint32_t timeout);
114     std::shared_ptr<Response> GetMessageFromRecvList(Message::MsgType type);
115 
116     std::string pkgName_ { "" };
117     std::string myName_ { "" };
118     std::string peerNetworkId_ { "" };
119     std::string peerName_ { "" };
120     bool isServer_ { false };     // Indicates the instance is a client or server.
121     int32_t listenSocket_ { -1 }; // Used to listen the connection from client side.
122     int32_t socket_ { -1 };       // Indicates the client socket.
123 
124     std::mutex recvMutex_;
125     std::condition_variable recvCond_;
126     std::list<std::shared_ptr<Message>> msgList_;
127 
128     OnQueryCallback onQuery_;
129 };
130 } // namespace OHOS
131 #endif // TMESSENGER_H