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