xref: /OK3568_Linux_fs/external/recovery/rkupdate.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdbool.h>
20 #include <unistd.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <limits.h>
25 #include <libgen.h>
26 #include <sys/stat.h>
27 #include <sys/wait.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include "common.h"
31 #include "install.h"
32 #include "bootloader.h"
33 
34 #define URL_MAX_LENGTH 512
35 #define CMDLINE_LENGTH 2048
36 extern bool bSDBootUpdate;
start_main(const char * binary,char * args[],int * pipefd)37 static int start_main (const char *binary, char *args[], int* pipefd)
38 {
39     pid_t pid = fork();
40     if (pid == 0) {
41         close(pipefd[0]);
42         execv(binary, args);
43         LOGI("E:Can't run %s (%s)\n", binary, strerror(errno));
44         _exit(-1);
45     }
46     close(pipefd[1]);
47 
48     char buffer[1024];
49     FILE* from_child = fdopen(pipefd[0], "r");
50     while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
51         char* command = strtok(buffer, " \n");
52         if (command == NULL) {
53             continue;
54         } else if (strcmp(command, "progress") == 0) {
55             char* fraction_s = strtok(NULL, " \n");
56             char* seconds_s = strtok(NULL, " \n");
57 
58             float fraction = strtof(fraction_s, NULL);
59             int seconds = strtol(seconds_s, NULL, 10);
60 
61             ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
62         } else if (strcmp(command, "set_progress") == 0) {
63             char* fraction_s = strtok(NULL, " \n");
64             float fraction = strtof(fraction_s, NULL);
65 
66             ui_set_progress(fraction);
67         } else if (strcmp(command, "ui_print") == 0) {
68             char* str = strtok(NULL, "\n");
69             if (str) {
70                 LOGI(" >>>>>> %s <<<<<<\n", str);
71                 ui_print("%s", str);
72             } else {
73                 ui_print("\n");
74             }
75         } else {
76             LOGE("unknown command [%s]\n", command);
77         }
78     }
79 
80     fclose(from_child);
81 
82     int status;
83     waitpid(pid, &status, 0);
84     if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
85         LOGE("Error in %s\n(Status %d)\n", binary, WEXITSTATUS(status));
86         return INSTALL_ERROR;
87     }
88     return INSTALL_SUCCESS;
89 
90 }
91 
do_rk_updateEngine(const char * binary,const char * path)92 int do_rk_updateEngine(const char *binary, const char *path)
93 {
94     LOGI("[%s] start with main.\n", __func__);
95     char *update = "--update";
96     char *update_sdboot = "--update=sdboot";
97     int pipefd[2];
98     if (pipe(pipefd) == -1) {
99         LOGE("pipe error");
100     }
101 
102     //updateEngine --update --image_url=path --partition=0x3a0000
103     char *args[6];
104     char args_1[20] = {0};
105     char args_2[URL_MAX_LENGTH] = {0};
106     char args_4[32] = {0};
107     args[0] = (char* )binary;
108     args[1] = args_1;
109     sprintf(args[1], "--pipefd=%d", pipefd[1]);
110     args[2] = args_2;
111     sprintf(args[2], "--image_url=%s", path);
112 
113     if (bSDBootUpdate) {
114         char path_second[64] = {0};
115         char path_second_dir[64] = {0};
116 
117         sprintf(path_second_dir, "%s", path);
118         dirname(path_second_dir);
119 
120         sprintf(path_second, "%s/update_ab.img", path_second_dir);
121         if (access(path_second, F_OK) == 0) {
122             sprintf(args[2], "--image_url=%s", path_second);
123         } else {
124             sprintf(path_second, "%s/update_ota.img", path_second_dir);
125             if (access(path_second, F_OK) == 0) {
126                 sprintf(args[2], "--image_url=%s", path_second);
127             }
128         }
129     }
130     LOGI("SDcard update data: [%s]\n", args[2]);
131 
132     if (bSDBootUpdate) {
133         args[3] = (char *)update_sdboot;
134     } else {
135         args[3] = (char *)update;
136     }
137 
138     args[4] = args_4;
139     args[5] = NULL;
140 
141     if (bSDBootUpdate) {
142         // If SD boot, ignore --partition
143         sprintf(args[4], "--partition=0x%s", "FFFF00");
144     } else {
145         struct bootloader_message boot;
146         get_bootloader_message(&boot);
147         sprintf(args[4], "--partition=0x%X", *((int *)(boot.needupdate)));
148     }
149 
150     return start_main(binary, args, pipefd);
151 
152 }
do_rk_update(const char * binary,const char * path)153 int do_rk_update(const char *binary, const char *path)
154 {
155     LOGI("[%s] start with main.\n", __func__);
156     int pipefd[2];
157     if (pipe(pipefd) == -1) {
158         LOGE("pipe error");
159     }
160 
161     char* args[6];
162     args[0] = (char* )binary;
163     args[1] = "Version 1.0";
164     char args_2[10] = {0};
165     args[2] = args_2;
166     sprintf(args[2], "%d", pipefd[1]);
167     args[3] = (char*)path;
168     char args_4[8] = {0};
169     args[4] = args_4;
170     sprintf(args[4], "%d", (int)bSDBootUpdate);
171     args[5] = NULL;
172     return start_main(binary, args, pipefd);
173 
174 #if 0
175     pid_t pid = fork();
176     if (pid == 0) {
177         close(pipefd[0]);
178         execv(binary, args);
179         printf("E:Can't run %s (%s)\n", binary, strerror(errno));
180         fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
181         _exit(-1);
182     }
183     close(pipefd[1]);
184 
185     char buffer[1024];
186     FILE* from_child = fdopen(pipefd[0], "r");
187     while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
188         char* command = strtok(buffer, " \n");
189         if (command == NULL) {
190             continue;
191         } else if (strcmp(command, "progress") == 0) {
192             char* fraction_s = strtok(NULL, " \n");
193             char* seconds_s = strtok(NULL, " \n");
194 
195             float fraction = strtof(fraction_s, NULL);
196             int seconds = strtol(seconds_s, NULL, 10);
197 
198             ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
199         } else if (strcmp(command, "set_progress") == 0) {
200             char* fraction_s = strtok(NULL, " \n");
201             float fraction = strtof(fraction_s, NULL);
202             ui_set_progress(fraction);
203         } else if (strcmp(command, "ui_print") == 0) {
204             char* str = strtok(NULL, "\n");
205             if (str) {
206                 printf("ui_print = %s.\n", str);
207                 ui_print("%s", str);
208             } else {
209                 ui_print("\n");
210             }
211         } else {
212             LOGE("unknown command [%s]\n", command);
213         }
214     }
215 
216     fclose(from_child);
217 
218     int status;
219     waitpid(pid, &status, 0);
220     if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
221         LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
222         return INSTALL_ERROR;
223     }
224     return INSTALL_SUCCESS;
225 #endif
226 }
227