* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HDC_TRANSFER_H
#define HDC_TRANSFER_H
#include "common.h"
namespace Hdc {
class HdcTransferBase : public HdcTaskBase {
public:
enum CompressType { COMPRESS_NONE, COMPRESS_LZ4, COMPRESS_LZ77, COMPRESS_LZMA, COMPRESS_BROTLI };
struct TransferConfig {
uint64_t fileSize;
uint64_t atime;
uint64_t mtime;
string options;
string path;
string optionalName;
bool updateIfNew;
uint8_t compressType;
bool holdTimestamp;
string functionName;
string clientCwd;
string reserve1;
string reserve2;
};
struct FileMode {
uint64_t perm;
uint64_t uId;
uint64_t gId;
string context;
string fullName;
};
struct TransferPayload {
uint64_t index;
uint8_t compressType;
uint32_t compressSize;
uint32_t uncompressSize;
};
union FeatureFlagsUnion {
struct {
uint8_t hugeBuf : 1;
uint8_t compressLz4 : 1;
uint8_t reserveBits1 : 6;
uint8_t reserveBits2 : 8;
uint16_t reserveBits3 : 16;
uint32_t reserveBits4 : 32;
} bits;
uint8_t raw[FEATURE_FLAG_MAX_SIZE];
};
HdcTransferBase(HTaskInfo hTaskInfo);
virtual ~HdcTransferBase();
virtual void StopTask()
{
}
bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize);
const string cmdOptionTstmp = "-a";
const string cmdOptionSync = "-sync";
const string cmdOptionZip = "-z";
const string cmdOptionModeSync = "-m";
const string cmdBundleName = "-b";
protected:
struct CtxFile {
uint64_t fileSize;
uint64_t dirSize;
uint64_t indexIO;
uint32_t fileCnt;
bool isDir;
bool targetDirNotExist;
uint64_t transferBegin;
uint64_t transferDirBegin;
string localName;
string localPath;
string remotePath;
string localDirName;
bool fileModeSync;
bool master;
bool closeNotify;
bool ioFinish;
bool closeReqSubmitted;
bool isStableBufSize;
bool isFdOpen;
void *thisClass;
uint32_t lastErrno;
uv_loop_t *loop;
uv_fs_t fsOpenReq;
uv_fs_t fsCloseReq;
uv_fs_t fsSyncReq;
uv_fs_cb cb;
vector<string> taskQueue;
TransferConfig transferConfig;
FileMode fileMode;
vector<FileMode> dirMode;
map<string, FileMode> dirModeMap;
ssize_t openFd;
bool sandboxMode;
string bundleName;
string inputLocalPath;
bool isOtherSideSandboxSupported;
bool isSend = false;
};
enum AppModType {
APPMOD_NONE,
APPMOD_INSTALL,
APPMOD_UNINSTALL,
APPMOD_SIDELOAD,
};
static void OnFileOpen(uv_fs_t *req);
static void OnFileOpenFailed(CtxFile *context);
static void OnFileClose(CtxFile *context);
bool CheckSandboxOptionCompatibility(const string &option, CtxFile *context);
int GetSubFiles(const char *path, string filter, vector<string> *out);
int GetSubFilesRecursively(string path, string currentDirname, vector<string> *out);
virtual void CheckMaster(CtxFile* )
{
}
virtual void WhenTransferFinish(CtxFile* )
{
}
bool MatchPackageExtendName(string fileName, string extName);
bool ResetCtx(CtxFile *context, bool full = false);
bool SmartSlavePath(string &cwd, string &localPath, const char *optName);
bool CheckLocalPath(string &localPath, string &optName, string &errStr);
bool CheckFilename(string &localPath, string &optName, string &errStr);
void SetFileTime(CtxFile *context);
void ExtractRelativePath(string &cwd, string &path);
bool AddFeatures(FeatureFlagsUnion &feature);
bool CheckFeatures(CtxFile *context, uint8_t *payload, const int payloadSize);
static void CloseCtxFd(CtxFile *context)
{
if (context == nullptr || !context->isFdOpen) {
return;
}
if (Base::GetCaller() == Base::Caller::CLIENT) {
WRITE_LOG(LOG_DEBUG, "CloseCtxFd, localPath:%s result:%d, closeReqSubmitted:%d",
context->localPath.c_str(), context->openFd, context->closeReqSubmitted);
} else {
WRITE_LOG(LOG_DEBUG, "CloseCtxFd, localPath:%s result:%d, closeReqSubmitted:%d",
Hdc::MaskString(context->localPath).c_str(), context->openFd, context->closeReqSubmitted);
}
uv_fs_t fs;
uv_fs_close(nullptr, &fs, context->openFd, nullptr);
uv_fs_req_cleanup(&fs);
context->isFdOpen = false;
}
void RemoveSandboxRootPath(std::string &srcStr, const std::string &bundleName);
bool IsValidBundlePath(const string &bundleName);
CtxFile ctxNow;
uint16_t commandBegin;
uint16_t commandData;
bool isStableBuf;
const string CMD_OPTION_CLIENTCWD = "-cwd";
const string SANDBOX_ROOT_DIR = "/mnt/debug/100/debug_hap/";
#ifndef CONFIG_USE_JEMALLOC_DFX_INIF
CircleBuffer cirbuf;
#endif
private:
struct CtxFileIO {
uv_fs_t fs;
uint8_t *bufIO;
CtxFile *context;
uint64_t bytes;
};
static const uint8_t payloadPrefixReserve = 64;
static void OnFileIO(uv_fs_t *req);
static bool IODelayed(uv_fs_t *req);
static bool ProcressFileIO(uv_fs_t *req, CtxFile *context, HdcTransferBase *thisClass, uint64_t bytes);
static bool ProcressFileIORead(uv_fs_t *req, CtxFile *context, HdcTransferBase *thisClass);
static bool ProcressFileIOWrite(uv_fs_t *req, CtxFile *context, HdcTransferBase *thisClass);
static void ProcressFileIOFinish(uv_fs_t *req, CtxFile *context, HdcTransferBase *thisClass);
static bool ProcressFileIOIsSuccess(uv_fs_t *req, CtxFile *context, uint64_t bytes);
int SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytes);
bool SendIOPayload(CtxFile *context, uint64_t index, uint8_t *data, int dataSize);
bool RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize);
bool InitTransferPayload(TransferPayload &payloadHead, uint64_t index, uint8_t compressType,
uint32_t dataSize);
double maxTransferBufFactor = 0.8;
};
}
#endif