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 }; 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 ReadCtrlFromMain(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf); 86 static void ReadCtrlFromSession(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf); 87 HSession QueryUSBDeviceRegister(void *pDev, uint8_t busIDIn, uint8_t devIDIn); 88 virtual HSession MallocSession(bool serverOrDaemon, const ConnType connType, void *classModule, uint32_t sessionId = 0); 89 virtual void FreeSession(const uint32_t sessionId); 90 void WorkerPendding(); 91 int OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen); 92 int Send(const uint32_t sessionId, const uint32_t channelId, const uint16_t commandFlag, const uint8_t *data, 93 const int dataSize); 94 int SendByProtocol(HSession hSession, uint8_t *bufPtr, const int bufLen, bool echo = false); 95 virtual HSession AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput); 96 virtual int FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read); 97 virtual void PushAsyncMessage(const uint32_t sessionId, const uint8_t method, const void *data, const int dataSize); 98 HTaskInfo AdminTask(const uint8_t op, HSession hSession, const uint32_t channelId, HTaskInfo hInput); 99 bool DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, 100 int payloadSize); 101 void EnumUSBDeviceRegister(void (*pCallBack)(HSession hSession)); 102 #ifdef HDC_SUPPORT_UART 103 using UartKickoutZombie = const std::function<void(HSession hSession)>; 104 virtual void EnumUARTDeviceRegister(UartKickoutZombie); 105 #endif 106 void ClearOwnTasks(HSession hSession, const uint32_t channelIDInput); FetchCommand(HSession hSession,const uint32_t channelId,const uint16_t command,uint8_t * payload,int payloadSize)107 virtual bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, 108 int payloadSize) 109 { 110 return true; 111 } ServerCommand(const uint32_t sessionId,const uint32_t channelId,const uint16_t command,uint8_t * bufPtr,const int size)112 virtual bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, 113 uint8_t *bufPtr, const int size) 114 { 115 return true; 116 } RemoveInstanceTask(const uint8_t op,HTaskInfo hTask)117 virtual bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask) 118 { 119 return true; 120 } WantRestart()121 bool WantRestart() 122 { 123 return wantRestart; 124 } 125 static vector<uint8_t> BuildCtrlString(InnerCtrlCommand command, uint32_t channelId, uint8_t *data, int dataSize); 126 uv_loop_t loopMain; 127 bool serverOrDaemon; 128 uv_async_t asyncMainLoop; 129 uv_rwlock_t mainAsync; 130 list<void *> lstMainThreadOP; 131 void *ctxUSB; 132 133 protected: 134 struct PayloadHead { 135 uint8_t flag[2]; 136 uint8_t reserve[2]; // encrypt'flag or others options 137 uint8_t protocolVer; 138 uint16_t headSize; 139 uint32_t dataSize; 140 } __attribute__((packed)); 141 void ClearSessions(); JdwpNewFileDescriptor(const uint8_t * buf,const int bytesIO)142 virtual void JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) 143 { 144 } 145 // must be define in haderfile, cannot in cpp file 146 template<class T> TaskCommandDispatch(HTaskInfo hTaskInfo,uint8_t taskType,const uint16_t command,uint8_t * payload,const int payloadSize)147 bool TaskCommandDispatch(HTaskInfo hTaskInfo, uint8_t taskType, const uint16_t command, uint8_t *payload, 148 const int payloadSize) 149 { 150 bool ret = true; 151 T *ptrTask = nullptr; 152 if (!hTaskInfo->hasInitial) { 153 hTaskInfo->taskType = taskType; 154 ptrTask = new(std::nothrow) T(hTaskInfo); 155 if (ptrTask == nullptr) { 156 return false; 157 } 158 hTaskInfo->hasInitial = true; 159 hTaskInfo->taskClass = ptrTask; 160 } else { 161 ptrTask = static_cast<T *>(hTaskInfo->taskClass); 162 } 163 if (!ptrTask->CommandDispatch(command, payload, payloadSize)) { 164 ptrTask->TaskFinish(); 165 } 166 return ret; 167 } DoTaskRemove(HTaskInfo hTaskInfo,const uint8_t op)168 template<class T> bool DoTaskRemove(HTaskInfo hTaskInfo, const uint8_t op) 169 { 170 T *ptrTask = static_cast<T *>(hTaskInfo->taskClass); 171 if (ptrTask == nullptr) { 172 return true; 173 } 174 if (OP_CLEAR == op) { 175 ptrTask->StopTask(); 176 } else if (OP_REMOVE == op) { 177 if (!ptrTask->ReadyForRelease()) { 178 return false; 179 } 180 delete ptrTask; 181 } 182 return true; 183 } 184 bool wantRestart; 185 186 private: ClearInstanceResource()187 virtual void ClearInstanceResource() 188 { 189 } 190 int DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe, uint8_t *encBuf); 191 bool DispatchMainThreadCommand(HSession hSession, const CtrlStruct *ctrl); 192 bool DispatchSessionThreadCommand(uv_stream_t *uvpipe, HSession hSession, const uint8_t *baseBuf, 193 const int bytesIO); 194 void BeginRemoveTask(HTaskInfo hTask); 195 bool TryRemoveTask(HTaskInfo hTask); 196 void ReChildLoopForSessionClear(HSession hSession); 197 void FreeSessionContinue(HSession hSession); 198 static void FreeSessionFinally(uv_idle_t *handle); 199 static void AsyncMainLoopTask(uv_idle_t *handle); 200 static void FreeSessionOpeate(uv_timer_t *handle); 201 int MallocSessionByConnectType(HSession hSession); 202 void FreeSessionByConnectType(HSession hSession); 203 bool WorkThreadStartSession(HSession hSession); 204 uint32_t GetSessionPseudoUid(); 205 bool NeedNewTaskInfo(const uint16_t command, bool &masterTask); 206 void DumpTasksInfo(map<uint32_t, HTaskInfo> &mapTask); 207 208 map<uint32_t, HSession> mapSession; 209 uv_rwlock_t lockMapSession; 210 std::atomic<uint32_t> sessionRef = 0; 211 const uint8_t payloadProtectStaticVcode = 0x09; 212 uv_thread_t threadSessionMain; 213 size_t threadPoolCount; 214 }; 215 } // namespace Hdc 216 #endif 217