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