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