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