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