191 lines
6.7 KiB
C++
191 lines
6.7 KiB
C++
/*
|
|
* Copyright (c) 2023 Fancy Code.
|
|
* 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.
|
|
*/
|
|
#include "SdCardHal.h"
|
|
#include "ILog.h"
|
|
#include "LinuxApi.h"
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/statvfs.h>
|
|
#include <sys/types.h>
|
|
#include <sys/vfs.h>
|
|
#include <unistd.h>
|
|
const char *SD_CARD_DEVICE = SD_CARD_DEV;
|
|
const char *SD_MOUNT_PATH = SD_CARD_MOUNT_PATH;
|
|
SdCardHal::SdCardHal() : mStatus(SdCardHalStatus::END), mThreadRuning(false), mDeviceFd(-1)
|
|
{
|
|
}
|
|
void SdCardHal::SetSdCardMonitor(std::shared_ptr<VSdCardHalMonitor> &monitor)
|
|
{
|
|
LogInfo("SetSdCardMonitor.\n");
|
|
mMonitor = monitor;
|
|
monitor->ReportEvent(mStatus);
|
|
}
|
|
SdCardHalStatus SdCardHal::GetSdCardStatus(void)
|
|
{
|
|
return mStatus;
|
|
}
|
|
StatusCode SdCardHal::GetCapacity(unsigned long long &totalSizeMB, unsigned long long &freeSizeMB,
|
|
unsigned long long &usedSizeMB)
|
|
{
|
|
using SD_SIZE = unsigned long long;
|
|
constexpr SD_SIZE ONE_MB = 1024ULL * 1024;
|
|
if (SdCardHalStatus::MOUNTED != mStatus) {
|
|
LogWarning("SdCardHalStatus::MOUNTED != mStatus\n");
|
|
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
|
}
|
|
struct statfs sd_fs;
|
|
if (statfs(SD_MOUNT_PATH, &sd_fs) != 0) {
|
|
LogError("statfs failed!\n");
|
|
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
|
}
|
|
|
|
totalSizeMB = ((SD_SIZE)sd_fs.f_blocks * (SD_SIZE)sd_fs.f_bsize) / ONE_MB;
|
|
freeSizeMB = ((SD_SIZE)sd_fs.f_bavail * (SD_SIZE)sd_fs.f_bsize) / ONE_MB;
|
|
usedSizeMB = (((SD_SIZE)sd_fs.f_blocks - (SD_SIZE)sd_fs.f_bfree) * (SD_SIZE)sd_fs.f_bsize) / ONE_MB;
|
|
LogInfo("Total size: %llu MB\n", totalSizeMB);
|
|
LogInfo("Free size: %llu MB\n", freeSizeMB);
|
|
LogInfo("Used size: %llu MB\n", usedSizeMB);
|
|
return CreateStatusCode(STATUS_CODE_OK);
|
|
}
|
|
void SdCardHal::Init(void)
|
|
{
|
|
auto detectThread = [](std::shared_ptr<SdCardHal> sdCardHal) {
|
|
LogInfo("sdCardHal DevDetectingThread started.\n");
|
|
sdCardHal->DevDetectingThread();
|
|
};
|
|
mDevDetectingThread = std::thread(detectThread, shared_from_this());
|
|
}
|
|
void SdCardHal::UnInit(void)
|
|
{
|
|
mThreadRuning = false;
|
|
if (mDevDetectingThread.joinable()) {
|
|
mDevDetectingThread.join();
|
|
}
|
|
}
|
|
void SdCardHal::DevDetectingThread(void)
|
|
{
|
|
constexpr int SLEEP_TIME_MS = 100;
|
|
constexpr int DEVICE_EXIST = 0;
|
|
// SdCardHalStatus status = SdCardHalStatus::END;
|
|
// const char *SD_CARD_DEVICE = "/SD_CARD_DEVICE/mmcblk1p1";
|
|
mThreadRuning = true;
|
|
while (mThreadRuning) {
|
|
if (fx_access(SD_CARD_DEVICE, F_OK) != DEVICE_EXIST) {
|
|
if (SdCardHalStatus::PULL_OUT_DEVICE_NOT_EXIST != mStatus) {
|
|
mStatus = SdCardHalStatus::PULL_OUT_DEVICE_NOT_EXIST;
|
|
ReportDetecedChangedResult(mStatus);
|
|
}
|
|
if (mDeviceFd > 0) {
|
|
close(mDeviceFd);
|
|
mDeviceFd = -1;
|
|
}
|
|
goto CONTINUE;
|
|
}
|
|
if (mDeviceFd < 0) {
|
|
mDeviceFd = fx_open(SD_CARD_DEVICE, O_RDONLY);
|
|
if (mDeviceFd < 0) {
|
|
// LogInfo("sdCardHal: %s open failed.\n", SD_CARD_DEVICE);
|
|
if (SdCardHalStatus::PULL_OUT_OPEN_FAILED != mStatus) {
|
|
mStatus = SdCardHalStatus::PULL_OUT_OPEN_FAILED;
|
|
ReportDetecedChangedResult(mStatus);
|
|
}
|
|
goto CONTINUE;
|
|
}
|
|
}
|
|
struct stat sdStat;
|
|
if (fx_fstat(mDeviceFd, &sdStat) < 0) {
|
|
// LogInfo("sdCardHal: %s fstat failed.\n", SD_CARD_DEVICE);
|
|
if (SdCardHalStatus::ERROR != mStatus) {
|
|
mStatus = SdCardHalStatus::ERROR;
|
|
ReportDetecedChangedResult(mStatus);
|
|
}
|
|
close(mDeviceFd);
|
|
mDeviceFd = -1;
|
|
goto CONTINUE;
|
|
}
|
|
if (!S_ISBLK(sdStat.st_mode)) {
|
|
// LogInfo("sdCardHal: %s is not block device.\n", SD_CARD_DEVICE);
|
|
if (SdCardHalStatus::PULL_OUT_NOT_BLOCK_DEVICE != mStatus) {
|
|
mStatus = SdCardHalStatus::PULL_OUT_NOT_BLOCK_DEVICE;
|
|
ReportDetecedChangedResult(mStatus);
|
|
}
|
|
close(mDeviceFd);
|
|
mDeviceFd = -1;
|
|
}
|
|
else {
|
|
// LogInfo("sdCardHal: %s is inserted.\n", SD_CARD_DEVICE);
|
|
if (SdCardHalStatus::INSERTED != mStatus && SdCardHalStatus::MOUNTED != mStatus &&
|
|
SdCardHalStatus::UNMOUNTED != mStatus) {
|
|
mStatus = SdCardHalStatus::INSERTED;
|
|
ReportDetecedChangedResult(mStatus);
|
|
}
|
|
}
|
|
CONTINUE:
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS));
|
|
}
|
|
if (mDeviceFd > 0) {
|
|
close(mDeviceFd);
|
|
mDeviceFd = -1;
|
|
}
|
|
}
|
|
void SdCardHal::ReportDetecedChangedResult(const SdCardHalStatus &status)
|
|
{
|
|
LogInfo("SdCardHalStatus changed: %s.\n", PrintfStatusString(status));
|
|
SdCardHalStatus mountedStatus = SdCardHalStatus::END;
|
|
if (SdCardHalStatus::INSERTED == status) {
|
|
LogInfo("mount sd to %s.\n", SD_CARD_MOUNT_PATH);
|
|
constexpr int BUF_LENGTH = 128;
|
|
char cmd[BUF_LENGTH] = {0};
|
|
snprintf(cmd, BUF_LENGTH, "mount %s %s", SD_CARD_DEV, SD_CARD_MOUNT_PATH);
|
|
fx_system(cmd);
|
|
mountedStatus = SdCardHalStatus::MOUNTED;
|
|
mStatus = SdCardHalStatus::MOUNTED;
|
|
}
|
|
auto monitor = mMonitor.lock();
|
|
if (mMonitor.expired()) {
|
|
LogWarning("SdCardHal: monitor is expired.\n");
|
|
return;
|
|
}
|
|
if (SdCardHalStatus::END != mountedStatus) {
|
|
monitor->ReportEvent(mountedStatus);
|
|
return;
|
|
}
|
|
monitor->ReportEvent(status);
|
|
}
|
|
const char *SdCardHal::PrintfStatusString(const SdCardHalStatus &status)
|
|
{
|
|
switch (status) {
|
|
case SdCardHalStatus::MOUNTED:
|
|
return "MOUNTE\n";
|
|
case SdCardHalStatus::UNMOUNTED:
|
|
return "UNMOUNTED.";
|
|
case SdCardHalStatus::INSERTED:
|
|
return "INSERTED.";
|
|
case SdCardHalStatus::PULL_OUT_DEVICE_NOT_EXIST:
|
|
return "PULL_OUT_DEVICE_NOT_EXIST.";
|
|
case SdCardHalStatus::PULL_OUT_OPEN_FAILED:
|
|
return "PULL_OUT_OPEN_FAILED.";
|
|
case SdCardHalStatus::PULL_OUT_NOT_BLOCK_DEVICE:
|
|
return "PULL_OUT_NOT_BLOCK_DEVICE.";
|
|
case SdCardHalStatus::END:
|
|
return "END.";
|
|
default:
|
|
return "UNDEFINE.";
|
|
}
|
|
} |