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