• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #ifndef HDC_SESSION_H
16 #define HDC_SESSION_H
17 #include <shared_mutex>
18 #include <sstream>
19 #include "common.h"
20 #include "uv_status.h"
21 
22 namespace Hdc {
23 enum TaskType { TYPE_UNITY, TYPE_SHELL, TASK_FILE, TASK_FORWARD, TASK_APP, TASK_FLASHD };
24 
25 class HdcSessionBase {
26 public:
27     enum AuthType { AUTH_NONE, AUTH_TOKEN, AUTH_SIGNATURE, AUTH_PUBLICKEY, AUTH_OK, AUTH_FAIL, AUTH_SSL_TLS_PSK };
28     struct SessionHandShake {
29         string banner; // must first index
30         // auth none
31         uint8_t authType;
32         uint32_t sessionId;
33         string connectKey;
34         string buf;
35         string version;
ToDebugStringSessionHandShake36         std::string ToDebugString()
37         {
38             std::ostringstream oss;
39             oss << "SessionHandShake [";
40             oss << " banner:" << banner;
41             oss << " sessionId:" << sessionId;
42             oss << " authType:" << unsigned(authType);
43             oss << " connectKey:" << Hdc::MaskString(connectKey);
44             oss << " version:" << version;
45             oss << "]";
46             return oss.str();
47         }
48     };
49 
50     struct CtrlStruct {
51         InnerCtrlCommand command;
52         uint32_t channelId;
53         uint8_t dataSize;
54         uint8_t data[BUF_SIZE_MICRO];
55     };
56     struct PayloadProtect {  // reserve for encrypt and decrypt
57         uint32_t channelId;
58         uint32_t commandFlag;
59         uint8_t checkSum;  // enable it will be lose about 20% speed
60         uint8_t vCode;
61     };
62     struct HeartbeatMsg {
63         uint64_t heartbeatCount;
64         string reserved;
65     };
66 
67     HdcSessionBase(bool serverOrDaemonIn, size_t uvThreadSize = SIZE_THREAD_POOL);
68     virtual ~HdcSessionBase();
AttachChannel(HSession hSession,const uint32_t channelId)69     virtual void AttachChannel(HSession hSession, const uint32_t channelId)
70     {
71     }
DeatchChannel(HSession hSession,const uint32_t channelId)72     virtual void DeatchChannel(HSession hSession, const uint32_t channelId)
73     {
74     }
NotifyInstanceSessionFree(HSession hSession,bool freeOrClear)75     virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear)
76     {
77     }
RedirectToTask(HTaskInfo hTaskInfo,HSession hSession,const uint32_t channelId,const uint16_t command,uint8_t * payload,const int payloadSize)78     virtual bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId,
79                                 const uint16_t command, uint8_t *payload, const int payloadSize)
80     {
81         return true;
82     }
83     // Thread security interface for global stop programs
84     void PostStopInstanceMessage(bool restart = false);
85     void ReMainLoopForInstanceClear();
86     // server, Two parameters in front of call can be empty
87     void LogMsg(const uint32_t sessionId, const uint32_t channelId, MessageLevel level, const char *msg, ...);
88     static void AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf);
89     static void MainAsyncCallback(uv_async_t *handle);
90     static void FinishWriteSessionTCP(uv_write_t *req, int status);
91     static void SessionWorkThread(uv_work_t *arg);
92     static void ReadCtrlFromSession(uv_poll_t *poll, int status, int events);
93     static void ReadCtrlFromMain(uv_poll_t *poll, int status, int events);
94     static void ParsePeerSupportFeatures(HSession &hSession, std::map<std::string, std::string> &tlvMap);
95     HSession QueryUSBDeviceRegister(void *pDev, uint8_t busIDIn, uint8_t devIDIn);
96     virtual HSession MallocSession(bool serverOrDaemon, const ConnType connType, void *classModule,
97                                    uint32_t sessionId = 0);
98     virtual void FreeSession(const uint32_t sessionId);
99 #ifdef HDC_HOST
100     void PrintAllSessionConnection(const uint32_t sessionId);
101 #endif
102     void WorkerPendding();
103     int OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen);
104     int Send(const uint32_t sessionId, const uint32_t channelId, const uint16_t commandFlag, const uint8_t *data,
105              const int dataSize);
106     int SendByProtocol(HSession hSession, uint8_t *bufPtr, const int bufLen, bool echo = false);
107     virtual HSession AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput);
108     virtual int FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read);
109 #ifdef HDC_SUPPORT_ENCRYPT_TCP
110     virtual int FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read, bool isEncrypted);
111 #endif
112     virtual void PushAsyncMessage(const uint32_t sessionId, const uint8_t method, const void *data, const int dataSize);
113     HTaskInfo AdminTask(const uint8_t op, HSession hSession, const uint32_t channelId, HTaskInfo hInput);
114     bool DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload,
115                           int payloadSize);
116     void EnumUSBDeviceRegister(void (*pCallBack)(HSession hSession));
117 #ifdef HDC_SUPPORT_UART
118     using UartKickoutZombie = const std::function<void(HSession hSession)>;
119     virtual void EnumUARTDeviceRegister(UartKickoutZombie);
120 #endif
121     void ClearOwnTasks(HSession hSession, const uint32_t channelIDInput);
FetchCommand(HSession hSession,const uint32_t channelId,const uint16_t command,uint8_t * payload,int payloadSize)122     virtual bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload,
123                               int payloadSize)
124     {
125         return true;
126     }
ServerCommand(const uint32_t sessionId,const uint32_t channelId,const uint16_t command,uint8_t * bufPtr,const int size)127     virtual bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command,
128                                uint8_t *bufPtr, const int size)
129     {
130         return true;
131     }
RemoveInstanceTask(const uint8_t op,HTaskInfo hTask)132     virtual bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask)
133     {
134         return true;
135     }
WantRestart()136     bool WantRestart()
137     {
138         return wantRestart;
139     }
140     static vector<uint8_t> BuildCtrlString(InnerCtrlCommand command, uint32_t channelId, uint8_t *data, int dataSize);
141     uv_loop_t loopMain;
142     LoopStatus loopMainStatus;
143     bool serverOrDaemon;
144     uv_async_t asyncMainLoop;
145     uv_rwlock_t mainAsync;
146     list<void *> lstMainThreadOP;
147     void *ctxUSB;
148 
149 protected:
150     struct PayloadHead {
151         uint8_t flag[2];
152         uint8_t reserve[2];  // encrypt'flag or others options
153         uint8_t protocolVer;
154         uint16_t headSize;
155         uint32_t dataSize;
156     } __attribute__((packed));
157     void ClearSessions();
158 #ifdef HDC_HOST
159     void PrintSession(const uint32_t sessionId);
160 #endif
161     HSession VoteReset(const uint32_t sessionId);
JdwpNewFileDescriptor(const uint8_t * buf,const int bytesIO)162     virtual void JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO)
163     {
164     }
165     // must be define in haderfile, cannot in cpp file
166     template<class T>
TaskCommandDispatch(HTaskInfo hTaskInfo,uint8_t taskType,const uint16_t command,uint8_t * payload,const int payloadSize)167     bool TaskCommandDispatch(HTaskInfo hTaskInfo, uint8_t taskType, const uint16_t command, uint8_t *payload,
168                              const int payloadSize)
169     {
170         StartTraceScope("HdcSessionBase::TaskCommandDispatch");
171         bool ret = true;
172         T *ptrTask = nullptr;
173         if (!hTaskInfo->hasInitial) {
174             hTaskInfo->taskType = taskType;
175             ptrTask = new(std::nothrow) T(hTaskInfo);
176             if (ptrTask == nullptr) {
177                 return false;
178             }
179             hTaskInfo->hasInitial = true;
180             hTaskInfo->taskClass = ptrTask;
181         } else {
182             ptrTask = static_cast<T *>(hTaskInfo->taskClass);
183         }
184         if (!ptrTask->CommandDispatch(command, payload, payloadSize)) {
185             ptrTask->TaskFinish();
186         }
187         return ret;
188     }
DoTaskRemove(HTaskInfo hTaskInfo,const uint8_t op)189     template<class T> bool DoTaskRemove(HTaskInfo hTaskInfo, const uint8_t op)
190     {
191         T *ptrTask = static_cast<T *>(hTaskInfo->taskClass);
192         if (ptrTask == nullptr) {
193             return true;
194         }
195         if (op == OP_CLEAR) {
196             ptrTask->StopTask();
197         } else if (op == OP_REMOVE) {
198             if (!ptrTask->ReadyForRelease()) {
199                 return false;
200             }
201             delete ptrTask;
202         }
203         return true;
204     }
205     bool wantRestart;
206 
207 private:
ClearInstanceResource()208     virtual void ClearInstanceResource()
209     {
210     }
211     int DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe, uint8_t *encBuf);
212     bool DispatchMainThreadCommand(HSession hSession, const CtrlStruct *ctrl);
213     bool DispatchSessionThreadCommand(HSession hSession, const uint8_t *baseBuf,
214                                       const int bytesIO);
215     void BeginRemoveTask(HTaskInfo hTask);
216     bool TryRemoveTask(HTaskInfo hTask);
217     void ReChildLoopForSessionClear(HSession hSession);
218     void FreeSessionContinue(HSession hSession);
219     static void FreeSessionFinally(uv_idle_t *handle);
220     static void AsyncMainLoopTask(uv_idle_t *handle);
221     static void FreeSessionOpeate(uv_timer_t *handle);
222     static void SendHeartbeatMsg(uv_timer_t *handle);
223     int MallocSessionByConnectType(HSession hSession);
224     void FreeSessionByConnectType(HSession hSession);
225     bool WorkThreadStartSession(HSession hSession);
226     void WorkThreadInitSession(HSession hSession, SessionHandShake &handshake);
227     uint32_t GetSessionPseudoUid();
228     bool NeedNewTaskInfo(const uint16_t command, bool &masterTask);
229     void DumpTasksInfo(map<uint32_t, HTaskInfo> &mapTask);
230     void StartHeartbeatWork(HSession hSession);
231     void SetFeature(SessionHandShake &handshake);
232     void StopHeartbeatWork(HSession hSession);
233 
234     map<uint32_t, HSession> mapSession;
235     uv_rwlock_t lockMapSession;
236     std::atomic<uint32_t> sessionRef = 0;
237     const uint8_t payloadProtectStaticVcode = 0x09;
238     uv_thread_t threadSessionMain;
239     size_t threadPoolCount;
240     std::atomic<uint32_t> taskCount = 0;
241 };
242 }  // namespace Hdc
243 #endif
244