offline
- savan2
- Građanin
- Pridružio: 15 Jul 2009
- Poruke: 150
|
Napisano: 14 Jan 2015 11:15
Pozdrav! Ne mogu nesto da resim, treba mi pomoc ako je moguce! Pravim neki flasher i nemam ideju kako da napravim safe funkciju za citanje trim area fajla pre nego ga flesujem u telefon. Trim area fajl je jako opasno flesovati jer ako se flesuje pogresno moze trajno da ubije telefon. Posto fajl moze da bude u nekoliko razlicitih formata znaci moram da uradim i safe funkciju koja bi trebala da prepozna to i da iscita fajl i proveri ga pre nego ga flesuje u telefon. Malo cu da objasnim, na primer 4 razlicita scenarija trim fajla:
1: trim fajl
//blabla
//another part:
02
000005DA 0004 FF AA CC DF
000006DA 000A FF FF FF FE FA FF FF FF FE FA
00000853 0002 AB BA
0000099C 0006 AC C8 C5 C3 AC BC
2: trim fajl
//comment line
//partit2:
02
000005DA 0004 FFAACCDF
000006DA 000A FFFFFFFEFAFFFFFFFEFA
00000853 0002 ABBA
0000099C 0006 ACC8C5C3ACBC
3: trim fajl
//another comment
//particija:
02
000005DA 0004 FF AA CC DF
000006DA 000A FF FF FF FE
FA FF FF FF
FE FA
00000853 0002 AB BA
0000099C 0006 AC C8 C5 C3
AC BC
4: trim fajl
//komentar blabla
//pt:
02
000005DA 0004 FFAACCDF
000006DA 000A FFFFFFFE
FAFFFFFF
FEFA
00000853 0002 ABBA
0000099C 0006 ACC8C5C3
ACBC
Kao sto vidite ima 4 razlicita formata trim fajla, svaki od njih sadrzi:
1. partition number (to je ono 02, ili moze biti 0B ili 05 ...itd)
2. unit (prvih 4 bytes)
3. unit size (2 bytes)
4. unit data (odmah posle unit size (problem je sto nekad nije u jednoj liniji nego je u nekim slucajevima rasporedjen u vise linija)
5. comment lines (//)
Znaci ja treba da napravim funkciju koja bi trebala da cita liniju po liniju, da detektuje kometar liniju, broj particije, unit, unit size, i unit data, da u medju vremenu pre nego sto krene flesovanje proveri dali unit data stvarno sadrzi toliko bytes definisanih u unit size... itd.
Ja sam poceo nesto malo ali nemam ideju kako dalje:
#include <stdio.h>
...obrisano
Dopuna: 14 Jan 2015 22:40
Reseno!
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#define MAX_UNIT_LINE_LEN 0x20000
#define ENABLE_TA_DEBUG 0
#if ENABLE_TA_DEBUG
#define LOGT printf
#else
#define LOGT(...)
#endif
static ssize_t g_getline(char **lineptr, size_t *n, FILE *stream) {
char *cur_pos, *new_lineptr;
int c;
size_t new_lineptr_len;
if (lineptr == NULL || n == NULL || stream == NULL) {
errno = EINVAL;
printf("Error: EINVAL!\n");
return -1;
}
if (*lineptr == NULL) {
*n = MAX_UNIT_LINE_LEN;
if ((*lineptr = (char *)malloc(*n)) == NULL) {
errno = ENOMEM;
printf("Error: MAX_UNIT_LINE_LEN reached!\n");
return -1;
}
}
cur_pos = *lineptr;
for (;;) {
c = getc(stream);
if (ferror(stream) || (c == EOF && cur_pos == *lineptr))
return -1;
if (c == EOF)
break;
if ((*lineptr + *n - cur_pos) < 2) {
if (SSIZE_MAX / 2 < *n) {
#ifdef EOVERFLOW
errno = EOVERFLOW;
#else
errno = ERANGE; /* no EOVERFLOW defined */
#endif
printf("Error: EOVERFLOW!\n");
return -1;
}
new_lineptr_len = *n * 2;
if ((new_lineptr = (char *)realloc(*lineptr, new_lineptr_len)) == NULL) {
errno = ENOMEM;
printf("Error: ENOMEM for realloc!\n");
return -1;
}
*lineptr = new_lineptr;
*n = new_lineptr_len;
}
*cur_pos++ = c;
if (c == '\r' || c == '\n')
break;
}
*cur_pos = '\0';
return (ssize_t)(cur_pos - *lineptr);
}
static void trim(char *ptr) {
int i = 0;
int j = 0;
while(ptr[j] != '\0') {
if(ptr[j] == 0x20 || ptr[j] == 0x09 || ptr[j] == '\n' || ptr[j] == '\r') {
++j;
ptr[i] = ptr[j];
} else {
ptr[i] = ptr[j];
++i;
++j;
}
}
ptr[i] = '\0';
}
static void to_uppercase(char *ptr) {
for ( ; *ptr; ++ptr) *ptr = toupper(*ptr);
}
static void to_ascii(char *dest, const char *text) {
unsigned long int ch;
for(; sscanf((const char *)text, "%02lx", &ch)==1; text+=2)
*dest++ = ch;
*dest = '\0';
}
static void display_buffer_hex(char *message, char *buffer, unsigned int size) {
unsigned int i, j, k;
printf("%s[0x%X]:\n", message, (int)size);
for (i=0; i<size; i+=16) {
printf("\n %08X ", i);
for(j=0,k=0; k<16; j++,k++) {
if (i+j < size) {
printf("%02X", buffer[i+j] & 0xff);
} else {
printf(" ");
}
printf(" ");
}
printf(" ");
for(j=0,k=0; k<16; j++,k++) {
if (i+j < size) {
if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
printf(".");
} else {
printf("%c", buffer[i+j]);
}
}
}
}
printf("\n\n" );
}
static int check_valid_unit(char *in) {
int i, ret=0;
if (strlen(in) < 8)
return ret;
for (i=0; i<8; ++i) {
if ((in[i] >= '0' && in[i] <= '9') || (in[i] >= 'A' && in[i] <= 'Z') || (in[i] >= 'a' && in[i] <= 'z'))
ret += 1;
}
if (ret == 8)
return 1;
else
return 0;
}
int main(void) {
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
char unit[9];
char unit_sz_tmp[5];
unsigned int unit_sz;
char unit_data[0x20000];
int ret=1, i, j, the_rest=0, partition_oppened=0, finished=0;
fp = fopen("test.ta", "r");
if (fp == NULL)
return 0;
while((read = g_getline(&line, &len, fp)) != -1) {
switch(read) {
case 1:
LOGT("Skipped empty line.\n\n");
break;
case 3:
if (line[0] >= 0x30 && line[0] <= 0x39 && line[1] >= 0x30 && line[1] <= 0x39) {
LOGT("Found partition: %02x\n", atoi(line));
if (!partition_oppened) {
printf("Sending command to bootloader to open partition: %02x ...\n", atoi(line));
partition_oppened = atoi(line);
printf("Partition %02X opened!\n", partition_oppened);
LOGT("\n");
} else {
printf("Sending command to bootloader to close partition %02X and open new partition: %02x ...\n",
partition_oppened, atoi(line));
partition_oppened = atoi(line);
printf("Partition %02X opened!\n", partition_oppened);
LOGT("\n");
}
}
break;
default:
if (line[0] == '/') {
LOGT("Skipped comment line.\n\n");
} else {
LOGT("Retrieved line of lenght: %lu\n", read);
if (check_valid_unit(line)) {
finished = 0;
memcpy(unit, line, 8);
unit[8] = '\0';
to_uppercase(unit);
trim(line);
LOGT("Line lenght after trim: %lu\n", strlen(line));
LOGT("Found unit: %s\n", unit);
/* unit(8) + unit size(4) + at least one hex(2) */
if (strlen(line) < 14) {
printf("Error: corrupted unit! Skipping this unit!\n\n");
the_rest = 0;
break;
} else {
memcpy(unit_sz_tmp, line+8, 4);
unit_sz_tmp[4] = '\0';
sscanf(unit_sz_tmp, "%X", &unit_sz);
LOGT("Unit size: %02X\n", unit_sz);
memset(unit_data, '\0', sizeof(unit_data));
i = 0;
do {
memcpy(unit_data+i, line+12+i, 1);
} while(++i < strlen(line));
unit_data[i] = '\0';
if ((unsigned int)strlen(line)-12 < unit_sz*2) {
LOGT("Data probably continues in a new line (%u not match %u)!\n",
(unsigned int)strlen(line)-12, unit_sz*2);
the_rest = 1;
} else
the_rest = 0;
if ((unsigned int)strlen(unit_data) == unit_sz*2)
finished = 1;
}
} else {
if (the_rest) {
finished = 0;
trim(line);
LOGT("Line lenght after trim: %lu\n", strlen(line));
LOGT("Found the rest ot the data!\n");
j = strlen(unit_data);
i = 0;
do {
memcpy(unit_data+j+i, line+i, 1);
} while(++i < strlen(line));
unit_data[j+i] = '\0';
if ((unsigned int)strlen(unit_data) == unit_sz*2) {
the_rest = 0;
finished = 1;
}
}
}
if (finished) {
finished = 0;
printf("\n<<-------------------- Retrieval finished! Found unit: %s, Unit size: %04X, Unit data:\n", unit, unit_sz);
to_ascii(unit_data, unit_data);
display_buffer_hex(unit, unit_data, unit_sz);
printf("---------------------->> Writing data to phone...\n");
/*************************************
HERE BOOTLOADER COMMANDS :)
**************************************/
}
LOGT("\n");
}
break;
}
}
if (fp)
fclose(fp);
if (line)
free(line);
if (partition_oppened) {
printf("Sending command to bootloader to close ta.\n");
LOGT("\n");
partition_oppened = 0;
}
return ret;
}
Probane sve kombinacije i rezultat ok Molim nekog ko ima malo vise strpljenja da pogleda da se nije zavukla kakva greska ili ako bilo ko ima neko bolje resenje bilo bi super, hvala!
|