2025-05-10 21:49:39 +08:00

227 lines
6.6 KiB
C

/*
* Copyright (C) 2023 Rockchip Electronics 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include "common.h"
#include "install.h"
#include "bootloader.h"
#define URL_MAX_LENGTH 512
#define CMDLINE_LENGTH 2048
extern bool bSDBootUpdate;
static int start_main (const char *binary, char *args[], int* pipefd)
{
pid_t pid = fork();
if (pid == 0) {
close(pipefd[0]);
execv(binary, args);
LOGI("E:Can't run %s (%s)\n", binary, strerror(errno));
_exit(-1);
}
close(pipefd[1]);
char buffer[1024];
FILE* from_child = fdopen(pipefd[0], "r");
while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
char* command = strtok(buffer, " \n");
if (command == NULL) {
continue;
} else if (strcmp(command, "progress") == 0) {
char* fraction_s = strtok(NULL, " \n");
char* seconds_s = strtok(NULL, " \n");
float fraction = strtof(fraction_s, NULL);
int seconds = strtol(seconds_s, NULL, 10);
ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
} else if (strcmp(command, "set_progress") == 0) {
char* fraction_s = strtok(NULL, " \n");
float fraction = strtof(fraction_s, NULL);
ui_set_progress(fraction);
} else if (strcmp(command, "ui_print") == 0) {
char* str = strtok(NULL, "\n");
if (str) {
LOGI(" >>>>>> %s <<<<<<\n", str);
ui_print("%s", str);
} else {
ui_print("\n");
}
} else {
LOGE("unknown command [%s]\n", command);
}
}
fclose(from_child);
int status;
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
LOGE("Error in %s\n(Status %d)\n", binary, WEXITSTATUS(status));
return INSTALL_ERROR;
}
return INSTALL_SUCCESS;
}
int do_rk_updateEngine(const char *binary, const char *path)
{
LOGI("[%s] start with main.\n", __func__);
char *update = "--update";
char *update_sdboot = "--update=sdboot";
int pipefd[2];
if (pipe(pipefd) == -1) {
LOGE("pipe error");
}
//updateEngine --update --image_url=path --partition=0x3a0000
char *args[6];
char args_1[20] = {0};
char args_2[URL_MAX_LENGTH] = {0};
char args_4[32] = {0};
args[0] = (char* )binary;
args[1] = args_1;
sprintf(args[1], "--pipefd=%d", pipefd[1]);
args[2] = args_2;
sprintf(args[2], "--image_url=%s", path);
if (bSDBootUpdate) {
char path_second[64] = {0};
char path_second_dir[64] = {0};
sprintf(path_second_dir, "%s", path);
dirname(path_second_dir);
sprintf(path_second, "%s/update_ab.img", path_second_dir);
if (access(path_second, F_OK) == 0) {
sprintf(args[2], "--image_url=%s", path_second);
} else {
sprintf(path_second, "%s/update_ota.img", path_second_dir);
if (access(path_second, F_OK) == 0) {
sprintf(args[2], "--image_url=%s", path_second);
}
}
}
LOGI("SDcard update data: [%s]\n", args[2]);
if (bSDBootUpdate) {
args[3] = (char *)update_sdboot;
} else {
args[3] = (char *)update;
}
args[4] = args_4;
args[5] = NULL;
if (bSDBootUpdate) {
// If SD boot, ignore --partition
sprintf(args[4], "--partition=0x%s", "FFFF00");
} else {
struct bootloader_message boot;
get_bootloader_message(&boot);
sprintf(args[4], "--partition=0x%X", *((int *)(boot.needupdate)));
}
return start_main(binary, args, pipefd);
}
int do_rk_update(const char *binary, const char *path)
{
LOGI("[%s] start with main.\n", __func__);
int pipefd[2];
if (pipe(pipefd) == -1) {
LOGE("pipe error");
}
char* args[6];
args[0] = (char* )binary;
args[1] = "Version 1.0";
char args_2[10] = {0};
args[2] = args_2;
sprintf(args[2], "%d", pipefd[1]);
args[3] = (char*)path;
char args_4[8] = {0};
args[4] = args_4;
sprintf(args[4], "%d", (int)bSDBootUpdate);
args[5] = NULL;
return start_main(binary, args, pipefd);
#if 0
pid_t pid = fork();
if (pid == 0) {
close(pipefd[0]);
execv(binary, args);
printf("E:Can't run %s (%s)\n", binary, strerror(errno));
fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
_exit(-1);
}
close(pipefd[1]);
char buffer[1024];
FILE* from_child = fdopen(pipefd[0], "r");
while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
char* command = strtok(buffer, " \n");
if (command == NULL) {
continue;
} else if (strcmp(command, "progress") == 0) {
char* fraction_s = strtok(NULL, " \n");
char* seconds_s = strtok(NULL, " \n");
float fraction = strtof(fraction_s, NULL);
int seconds = strtol(seconds_s, NULL, 10);
ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
} else if (strcmp(command, "set_progress") == 0) {
char* fraction_s = strtok(NULL, " \n");
float fraction = strtof(fraction_s, NULL);
ui_set_progress(fraction);
} else if (strcmp(command, "ui_print") == 0) {
char* str = strtok(NULL, "\n");
if (str) {
printf("ui_print = %s.\n", str);
ui_print("%s", str);
} else {
ui_print("\n");
}
} else {
LOGE("unknown command [%s]\n", command);
}
}
fclose(from_child);
int status;
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
return INSTALL_ERROR;
}
return INSTALL_SUCCESS;
#endif
}