blob: 37199b6a0563a8816349e8962f4f2442c0f99604 [file] [log] [blame]
/*
*Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
*THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
*WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
*ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
*BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
*SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
*WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
*OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
*IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sstream>
#include <iomanip>
#include <string>
#include "file_finder_oem_extension.h"
#define __CLASS__ "FileFinderOemExtn"
#define LOCAL_SOURCE_PATH "/mnt/vendor/persist/display/"
#define FILE_CHUNK_SIZE 8192
namespace sdm {
FileFinderOemExtn *FileFinderOemExtn::file_finder_ = NULL;
uint32_t FileFinderOemExtn::ref_count_ = 0;
std::mutex FileFinderOemExtn::lock_ = {};
FileFinderInterface *GetFileFinderIntf() {
std::lock_guard<std::mutex> g(FileFinderOemExtn::lock_);
if (FileFinderOemExtn::file_finder_ == NULL) {
FileFinderOemExtn::file_finder_ = new FileFinderOemExtn();
}
FileFinderOemExtn::ref_count_++;
return FileFinderOemExtn::file_finder_;
}
void DestroyFileFinderIntf() {
std::lock_guard<std::mutex> g(FileFinderOemExtn::lock_);
FileFinderOemExtn::ref_count_--;
if (FileFinderOemExtn::ref_count_ == 0) {
delete FileFinderOemExtn::file_finder_;
FileFinderOemExtn::file_finder_ = NULL;
}
}
FileFinderOemExtn::FileFinderOemExtn() {
std::function<int(FileFinderOemExtn *, const GenericPayload &, GenericPayload *)> ffd =
&FileFinderOemExtn::FindFileData;
ops_fcns_.emplace(kFileFinderFileData, ffd);
}
int FileFinderOemExtn::Init() {
return 0;
}
int FileFinderOemExtn::Deinit() {
return 0;
}
int FileFinderOemExtn::SetParameter(FileFinderParams param, const GenericPayload &in) {
(void)param;
(void)in;
DLOGE("SetParameter on param %d not supported", param);
return -ENOTSUP;
}
int FileFinderOemExtn::GetParameter(FileFinderParams param, GenericPayload *out) {
(void)param;
(void)out;
DLOGE("GetParameter on param %d not supported", param);
return -ENOTSUP;
}
int FileFinderOemExtn::ProcessOps(FileFinderOps op, const GenericPayload &in, GenericPayload *out) {
if (out == NULL) {
return -EINVAL;
}
if (op < kFileFinderOpMax) {
auto fcn = ops_fcns_.at(op);
return fcn(this, in, out);
} else {
DLOGE("Invalid op %d", op);
return -EINVAL;
}
}
int FileFinderOemExtn::FindFileData(const GenericPayload &in, GenericPayload *out) {
int status = 0;
uint32_t sz = 0;
uint64_t *panel_id = nullptr;
std::string panel_id_hex_str = "";
DemuraFilePaths *file_paths = nullptr;
status = in.GetPayload(panel_id, &sz);
if ((status != 0) || sz != 1) {
return -EINVAL;
}
std::stringstream temp;
uint64_t id = *panel_id;
temp << std::setfill('0') << std::setw(16) << std::hex << id << std::dec;
panel_id_hex_str = temp.str();
status = out->GetPayload(file_paths, &sz);
if ((status != 0) || sz != 1) {
return -EINVAL;
}
errno = 0;
*file_paths = getSrcFilePaths(panel_id_hex_str);
if (file_paths->configFilePath.empty() || file_paths->signatureFilePath.empty() ||
file_paths->publickeyFilePath.empty()) {
DLOGE("Demura missing file - config file %d signature file %d public key file %d",
file_paths->configFilePath.empty(), file_paths->signatureFilePath.empty(),
file_paths->publickeyFilePath.empty());
return -EINVAL;
}
return 0;
}
DemuraFilePaths FileFinderOemExtn::getSrcFilePaths(const std::string &panel_id_hex_str) {
DemuraFilePaths paths = {};
FILE *calib_file = NULL;
FILE *signature_file = NULL;
FILE *publickey_file = NULL;
// Build path strings and check if the file is available
std::string sp = LOCAL_SOURCE_PATH;
errno = 0;
std::string src_path_calib = sp + "demura_config_" + panel_id_hex_str;
calib_file = fopen(src_path_calib.c_str(), "rb");
std::string src_path_sig = sp + "demura_signature_" + panel_id_hex_str;
signature_file = fopen(src_path_sig.c_str(), "rb");
std::string src_path_pk = sp + "demura_publickey_" + panel_id_hex_str;
publickey_file = fopen(src_path_pk.c_str(), "rb");
// Get files OTA if any file is missing
if (calib_file == NULL || signature_file == NULL || publickey_file == NULL) {
DLOGW("Failed to open files locally, attempting OTA");
paths = getFileOTA(panel_id_hex_str);
errno = 0;
calib_file = fopen(paths.configFilePath.c_str(), "rb");
if (calib_file == NULL) {
paths.configFilePath = "";
DLOGE("Failed to open file after OTA at %s. Error = %s", paths.configFilePath.c_str(),
strerror(errno));
}
signature_file = fopen(paths.signatureFilePath.c_str(), "rb");
if (signature_file == NULL) {
paths.signatureFilePath = "";
DLOGE("Failed to open file after OTA at %s. Error = %s", paths.signatureFilePath.c_str(),
strerror(errno));
}
publickey_file = fopen(paths.publickeyFilePath.c_str(), "rb");
if (publickey_file == NULL) {
paths.publickeyFilePath = "";
DLOGE("Failed to open file after OTA at %s. Error = %s", paths.publickeyFilePath.c_str(),
strerror(errno));
}
} else {
paths.configFilePath = src_path_calib;
paths.signatureFilePath = src_path_sig;
paths.publickeyFilePath = src_path_pk;
}
if (calib_file != NULL) {
fclose(calib_file);
}
if (signature_file != NULL) {
fclose(signature_file);
}
if (publickey_file != NULL) {
fclose(publickey_file);
}
return paths;
}
DemuraFilePaths FileFinderOemExtn::getFileOTA(const std::string &panel_id_hex_str) {
/*
* Communication to a server shall begin here.
* API shall securely contact the server and download the data to a file on the device
* and the location must accessible for both read and write by this process.
* This API shall return the paths of the files to the caller.
*/
DemuraFilePaths paths = {};
return paths;
}
} // namespace sdm