xref: /OK3568_Linux_fs/external/recovery/update_engine/rktools.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 <unistd.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <stdbool.h>
26 #include "log.h"
27 #include "rktools.h"
28 #include "download.h"
29 #include "../mtdutils/mtdutils.h"
30 
31 
32 
33 #define LOCAL_VERSION_PATH "/etc/version"
34 #define DOWNLOAD_VERSION_PATH "/tmp/version"
35 
getVersionFromfile(const char * filepath,char * version,int maxLength)36 bool getVersionFromfile(const char * filepath, char *version, int maxLength)
37 {
38     if (version == NULL || filepath == NULL) {
39         LOGE("getLocalVersion is error, version == null.\n");
40         return false;
41     }
42     FILE *fp = fopen(filepath, "r");
43     if (fp == NULL) {
44         LOGE("open %s failed, error is %s.\n", filepath, strerror(errno));
45         return false;
46     }
47 
48     char *line = NULL;
49     size_t len = 0;
50     size_t read;
51     while ((read = getline(&line, &len, fp)) != -1) {
52         if (read == 0 || line[0] == '#') {
53             continue;
54         }
55         char *pline = strstr(line, "RK_VERSION");
56         if (pline != NULL && (pline = strstr(pline, "=")) != NULL) {
57             pline++; //过滤掉等于号
58             //过滤掉空格
59             while (*pline == ' ') {
60                 pline++;
61             }
62             int pline_len = strlen(pline) - 1;
63             int version_len = (pline_len > maxLength ? maxLength : pline_len);
64             memcpy(version, pline, version_len);
65             LOGI("version = %s.\n", version);
66             break;
67         }
68     }
69     free(line);
70     fclose(fp);
71     return true;
72 }
73 
74 //下载服务器版本号文件
getRemoteVersion(char * url,char * version,int maxLength)75 bool getRemoteVersion(char *url, char *version, int maxLength)
76 {
77     if (url == NULL) {
78         LOGE("getRemoteVersion url is null.\n");
79         return false;
80     }
81 
82     if (download_file(url, DOWNLOAD_VERSION_PATH) == -1) {
83         LOGE("getRemoteVersion failed, url is %s.\n", url);
84         return false;
85     }
86 
87     return getVersionFromfile(DOWNLOAD_VERSION_PATH, version, maxLength);
88 }
89 
90 //获取本地版本号
getLocalVersion(char * version,int maxLength)91 bool getLocalVersion(char *version, int maxLength)
92 {
93     return getVersionFromfile(LOCAL_VERSION_PATH, version, maxLength);
94 }
95 
96 //判断是MTD还是block 设备
isMtdDevice()97 bool isMtdDevice()
98 {
99     char param[2048];
100     int fd, ret;
101     char *s = NULL;
102     fd = open("/proc/cmdline", O_RDONLY);
103     ret = read(fd, (char*)param, 2048);
104     close(fd);
105     s = strstr(param, "storagemedia");
106     if (s == NULL) {
107         LOGI("no found storagemedia in cmdline, default is not MTD.\n");
108         return false;
109     } else {
110         s = strstr(s, "=");
111         if (s == NULL) {
112             LOGI("no found storagemedia in cmdline, default is not MTD.\n");
113             return false;
114         }
115 
116         s++;
117         while (*s == ' ') {
118             s++;
119         }
120 
121         if (strncmp(s, "mtd", 3) == 0 ) {
122             LOGI("Now is MTD.\n");
123             return true;
124         } else if (strncmp(s, "sd", 2) == 0) {
125             LOGI("Now is SD.\n");
126             if ( !access(MTD_PATH, F_OK) ) {
127                 fd = open(MTD_PATH, O_RDONLY);
128                 ret = read(fd, (char*)param, 2048);
129                 close(fd);
130 
131                 s = strstr(param, "mtd");
132                 if (s == NULL) {
133                     LOGI("no found mtd.\n");
134                     return false;
135                 }
136                 LOGI("Now is MTD.\n");
137                 return true;
138             }
139         }
140     }
141     LOGI("Current device is not MTD\n");
142     return false;
143 }
144 
145 /**
146  * 从cmdline 获取从哪里引导
147  * 返回值:
148  *     0: a分区
149  *     1: b分区
150  *    -1: recovery 模式
151  */
getCurrentSlot()152 int getCurrentSlot()
153 {
154     char cmdline[CMDLINE_LENGTH];
155     int fd = open("/proc/cmdline", O_RDONLY);
156     if (read(fd, (char*)cmdline, CMDLINE_LENGTH) < 1) {
157         close(fd);
158         return -1;
159     }
160     close(fd);
161     char *slot = strstr(cmdline, "android_slotsufix");
162     if (slot == NULL) slot = strstr(cmdline, "androidboot.slot_suffix");
163     if (slot != NULL) {
164         slot = strstr(slot, "=");
165         if (slot != NULL && *(++slot) == '_') {
166             slot += 1;
167             LOGI("Current Mode is '%c' system.\n", (*slot == 'a') ? 'A' : 'B');
168             if ((*slot) == 'a') {
169                 return 0;
170             } else if ((*slot) == 'b') {
171                 return 1;
172             }
173         }
174     }
175     LOGI("Current Mode is recovery.\n");
176     return -1;
177 }
178 
getFlashPoint(char * path)179 void getFlashPoint(char *path)
180 {
181     char *emmc_point = getenv(EMMC_POINT_NAME);
182     LOGI("test Current device is emmc : %s.\n", emmc_point);
183     if ( !access(emmc_point, F_OK) ) {
184         LOGI("Current device is emmc : %s.\n", emmc_point);
185         strcpy(path, emmc_point);
186     } else if (strncmp("emmc", getenv("storagemedia"), 4) == 0) {
187         LOGI("Current device is emmc : /dev/mmcblk0.\n");
188         strcpy(path, "/dev/mmcblk0");
189     } else {
190         LOGI("Current device is nand : %s.\n", NAND_DRIVER_DEV_LBA);
191         strcpy(path, NAND_DRIVER_DEV_LBA);
192     }
193 }
194 /*
195  * 获得flash 的大小,和块数
196  */
getFlashSize(char * path,long long * flash_size,long long * block_num)197 int getFlashSize(char *path, long long* flash_size, long long* block_num)
198 {
199 
200     LOGI("[%s:%d]\n", __func__, __LINE__);
201 
202     off64_t total_size_64 = 0;
203     if (isMtdDevice()) {
204         size_t erase_size;
205         size_t total_size;
206         mtd_scan_partitions();
207         const MtdPartition *part = mtd_find_partition_by_name("rk-nand");
208         if ( part == NULL ) {
209             part = mtd_find_partition_by_name("spi-nand0");
210         }
211         if (part == NULL || mtd_partition_info(part, &total_size, &erase_size, NULL)) {
212             LOGE("Can't find rk-nand or spi-nand0\n");
213             return -1;
214         }
215         total_size = total_size - (erase_size * 4);
216         total_size_64 = total_size;
217     } else {
218         char flash_name[20];
219         getFlashPoint(flash_name);
220         int fd_dest = open(flash_name, O_RDWR | O_LARGEFILE);
221         if (fd_dest < 0) {
222             LOGE("Can't open %s\n", flash_name);
223             return -2;
224         }
225         if ((total_size_64 = lseek64(fd_dest, 0, SEEK_END)) == -1) {
226             LOGE("getFlashInfo lseek64 failed.\n");
227             close(fd_dest);
228             return -2;
229         }
230         lseek64(fd_dest, 0, SEEK_SET);
231         close(fd_dest);
232     }
233     if ( flash_size ) {
234         *flash_size = total_size_64 / 1024; //Kib
235         LOGI("[%s:%d] flash size [%lld] \n", __func__, __LINE__, *flash_size);
236     }
237     if ( block_num ) {
238         *block_num = (total_size_64 / 1024) * 2;
239         LOGI("[%s:%d]  block num [%lld]\n", __func__, __LINE__, *block_num);
240     }
241 
242     return 0;
243 }
244 
getFlashInfo(size_t * total_size,size_t * block_size,size_t * page_size)245 int getFlashInfo (size_t *total_size, size_t *block_size, size_t *page_size)
246 {
247     if (isMtdDevice()) {
248         if (mtd_get_flash_info(total_size, block_size, page_size) != 0) {
249             LOGE("%s-%d: get mtd info error\n", __func__, __LINE__);
250             return -1;
251         }
252         return 0;
253     } else {
254         LOGI("[%s:%d]\n", __func__, __LINE__);
255         if (total_size) {
256             LOGE("%s-%d: get flash total size error. NOT support now.\n", __func__, __LINE__);
257             return -1;
258         }
259         if (block_size) *block_size = 512 * 1024;
260         if (page_size) *page_size = 2 * 1024;
261         return 0;
262     }
263 }
264