blob: 9e495895c9511e4824271af6f49a01d41333418f [file] [log] [blame]
b.liua76c9612025-03-28 13:58:09 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <string.h>
9#include <sys/ioctl.h>
10#include <mtd/mtd-user.h>
11
12#include "otad.h"
13#include "mbtk_type.h"
14#include "mbtk_device.h"
15
16typedef struct {
17 char name[32];
18 char dev[16];
19 uint32 partition_start;
20 uint32 partition_size;
21 uint32 erase_size;
22} partition_info_t;
23
24/*
25* revision_out start from 0x1000.
26*/
27#define REVISION_OUT_ADDR 0x1000
28
29char revision_out[48] = {0};
30static bool revision_out_found = FALSE;
31
32static int partition_get(char *partition_name, partition_info_t *info)
33{
34 FILE *fp = fopen("/proc/mtd", "r");
35 if(fp == NULL) {
36 OTA_ERR("fopen(/proc/mtd) fail:%d", errno);
37 return -1;
38 }
39
40 char buff[64];
41 char size_str[16];
42 char erase_size_str[16];
43 char name[32];
44 memset(buff, 0x0, sizeof(buff));
45 while(fgets(buff, sizeof(buff), fp)) {
46 if(strstr(buff, partition_name)) {
47 memset(size_str, 0x0, sizeof(size_str));
48 memset(erase_size_str, 0x0, sizeof(erase_size_str));
49 memset(name, 0x0, sizeof(name));
50 memcpy(info->dev, "/dev/", 5);
51 if(4 == sscanf(buff, "%s %s %s %s", info->dev + 5, size_str, erase_size_str, name)) {
52 if(name[0] == '\"' && name[strlen(name) - 1] == '\"') {
53 memcpy(info->name, name + 1, strlen(name) - 2); // No copy ""
54 } else {
55 OTA_ERR("partition(%s) name error.", buff);
56 return -1;
57 }
58
59 if(info->dev[strlen(info->dev) - 1] == ':') {
60 info->dev[strlen(info->dev) - 1] = '\0';
61 }
62
63 info->partition_size = (uint32)strtoul(size_str, NULL, 16);
64 info->erase_size = (uint32)strtoul(erase_size_str, NULL, 16);
65 //info->partition_start += info->partition_size;
66 break;
67 } else {
68 OTA_ERR("sscanf(%s) fail:%d", buff, errno);
69 return -1;
70 }
71 }
72 memset(buff, 0x0, sizeof(buff));
73 }
74 fclose(fp);
75
76 return 0;
77}
78
79
80void revision_out_find(char *data, int len, unsigned int processed_cnt)
81{
82 if(!revision_out_found) {
83 if(processed_cnt + len > REVISION_OUT_ADDR) { // µ½´ï 0x1000
84 char *start = NULL;
85 if(strlen(revision_out) > 0) {
86 start = data;
87 } else {
88 start = data + REVISION_OUT_ADDR - processed_cnt;
89 }
90
91 if(data[len - 1] == '\0') { // Last char is '\0',get the complete version.
92 if(strlen(start) > 0) {
93 memcpy(revision_out + strlen(revision_out), start, strlen(start));
94 }
95 revision_out_found = TRUE;
96 OTA_DEBUG("Found complete version : %s", revision_out);
97 } else {
98 memcpy(revision_out + strlen(revision_out), start, data + len - start);
99 OTA_DEBUG("Found version : %s", revision_out);
100 }
101 }
102 }
103}
104
105int revision_out_update()
106{
107 if(strlen(revision_out) == 0) {
108 OTA_ERR("revision_out not set.");
109 revision_out_found = FALSE;
110 return -1;
111 }
112
113 partition_info_t info;
114 memset(&info, 0x0, sizeof(partition_info_t));
115 if(partition_get("device_info", &info)) {
116 OTA_ERR("partition_get() fail.");
117 return -1;
118 }
119
120 OTA_DEBUG("device_info name : %s, dev : %s, addr : %08x, size : %08x, erase_size : %08x", info.name,
121 info.dev, info.partition_start, info.partition_size, info.erase_size);
122
123 if(info.erase_size <= 0 || info.partition_size <= 0) {
124 OTA_ERR("partition info error.");
125 return -1;
126 }
127
128#if 0
129 int fd = open(dev, O_RDWR);
130 if (fd < 0) {
131 OTA_ERR("Fatal error: can't open device_info %s\n", dev);
132 return -1;
133 }
134
135 mbtk_device_info_header_t info_header;
136 memset(&info_header, 0x0, sizeof(mbtk_device_info_header_t));
137 int len = read(fd, &info_header, sizeof(mbtk_device_info_header_t));
138 if (len != sizeof(mbtk_device_info_header_t)) {
139 OTA_ERR("Fatal error: read %d bytes(expect %d)\n", len, sizeof(mbtk_device_info_header_t));
140 goto fail;
141 }
142
143 if(info_header.tag != MBTK_DEVICE_INFO_PARTITION_TAG) {
144 OTA_ERR("TAG error : %08x", info_header.tag);
145 goto fail;
146 }
147
148 if(info_header.version != MBTK_DEVICE_INFO_CURR_VERSION) {
149 OTA_ERR("Version error : %d", info_header.version);
150 goto fail;
151 }
152
153 if(info_header.item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr == 0) {
154 OTA_ERR("No found item : %d", MBTK_DEVICE_INFO_ITEM_BASIC);
155 goto fail;
156 }
157
158 lseek(fd, info_header.item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr, SEEK_SET);
159 mbtk_device_info_basic_t info_basic;
160 memset(&info_basic, 0, sizeof(mbtk_device_info_basic_t));
161 if (read(fd, &info_basic, sizeof(mbtk_device_info_basic_t)) != sizeof(mbtk_device_info_basic_t)) {
162 OTA_ERR("Read fail:%d", errno);
163 goto fail;
164 }
165
166 memset(info_basic.revision_out, 0, sizeof(info_basic.revision_out));
167 memcpy(info_basic.revision_out, revision_out, strlen(revision_out));
168
169 lseek(fd, info_header.item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr, SEEK_SET);
170 if (write(fd, &info_basic, sizeof(mbtk_device_info_basic_t)) != sizeof(mbtk_device_info_basic_t)) {
171 OTA_ERR("Write fail:%d", errno);
172 goto fail;
173 }
174#else
175 int fd = open(info.dev, O_RDWR);
176 if (fd < 0) {
177 OTA_ERR("Fatal error: can't open device_info %s\n", info.dev);
178 return -1;
179 }
180
181 char *mtd_buff = (char*)malloc(info.erase_size);
182 if(mtd_buff == NULL) {
183 OTA_ERR("malloc() failed\n");
184 return -1;
185 }
186 memset(mtd_buff, 0, info.erase_size);
187 int len = read(fd, mtd_buff, info.erase_size);
188 if (len != info.erase_size) {
189 OTA_ERR("Fatal error: read %d[%d] bytes(expect %d)\n", len, errno, info.erase_size);
190 goto fail;
191 }
192
193 struct erase_info_user mtdEraseInfo;
194 if (lseek(fd, 0, SEEK_SET) < 0)
195 {
196 OTA_ERR("seek failed\n");
197 return -1;
198 }
199
200 mtdEraseInfo.length = info.partition_size;
201 mtdEraseInfo.start = 0;
202 ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
203 ioctl(fd, MEMERASE, &mtdEraseInfo);
204
205 mbtk_device_info_header_t *info_header = (mbtk_device_info_header_t*)mtd_buff;
206 mbtk_device_info_basic_t *info_basic = (mbtk_device_info_basic_t*)(mtd_buff + info_header->item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr);
207 OTA_DEBUG("Old version : %s", info_basic->revision_out);
208 memset(info_basic->revision_out, 0, sizeof(info_basic->revision_out));
209 memcpy(info_basic->revision_out, revision_out, strlen(revision_out));
210
211 lseek(fd, 0, SEEK_SET);
212 if (write(fd, mtd_buff, info.erase_size) != info.erase_size) {
213 OTA_ERR("Write fail:%d", errno);
214 goto fail;
215 }
216
217 if(mtd_buff) {
218 free(mtd_buff);
219 }
220
221#endif
222
223 close(fd);
224
225 OTA_DEBUG("Set revision_out : %s", revision_out);
226
227 memset(revision_out, 0x0, sizeof(revision_out));
228 revision_out_found = FALSE;
229
230 return 0;
231
232fail:
233 close(fd);
234 return -1;
235}