| /* | 
 | *    mbtk_mtd.c | 
 | * | 
 | *    MBTK mtd partition utils API. | 
 | * | 
 | */ | 
 | /****************************************************************************** | 
 |  | 
 |                           EDIT HISTORY FOR FILE | 
 |  | 
 |   WHEN        WHO       WHAT,WHERE,WHY | 
 | --------    --------    ------------------------------------------------------- | 
 | 2024/2/26     LiuBin      Initial version | 
 |  | 
 | ******************************************************************************/ | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <unistd.h> | 
 | #include <errno.h> | 
 |  | 
 | #include "mbtk_mtd.h" | 
 | #include "mbtk_log.h" | 
 | #include "mbtk_str.h" | 
 |  | 
 | static mbtk_partition_info_t partition_list[MBTK_PARTITION_NUM_MAX]; | 
 | static bool partition_inited = FALSE; | 
 |  | 
 | mbtk_partition_info_t* mbtk_partition_get() | 
 | { | 
 |     if(partition_inited) { | 
 |         return partition_list; | 
 |     } | 
 |  | 
 |     memset(partition_list, 0x0, sizeof(partition_list)); | 
 |     FILE *fp = fopen("/proc/mtd", "r"); | 
 |     if(fp == NULL) { | 
 |         LOGE("fopen(/proc/mtd) fail:%d", errno); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     char buff[64]; | 
 |     int index = 0; | 
 |     char size_str[16]; | 
 |     char name[32]; | 
 |     char erase_size_str[16]; | 
 |     char name_temp[32]; | 
 |     memset(buff, 0x0, 64); | 
 |     memset(name_temp, 0x0, 32); | 
 |     while(fgets(buff, 64, fp)) { | 
 |         if(str_startwith(buff, "mtd")) { | 
 |             memset(size_str, 0x0, 16); | 
 |             memset(erase_size_str, 0x0, sizeof(erase_size_str)); | 
 |             memset(name, 0x0, 32); | 
 |             if(4 == sscanf(buff, "%s %s %s %s", partition_list[index].dev, size_str, erase_size_str, name)) { | 
 |                 if(name[0] == '\"' && name[strlen(name) - 1] == '\"') { | 
 |                     memcpy(partition_list[index].name, name + 1, strlen(name) - 2); // No copy "" | 
 |                 } else { | 
 |                     LOGE("partition(%s) name error.", buff); | 
 |                     return NULL; | 
 |                 } | 
 |  | 
 |                 if(partition_list[index].dev[strlen(partition_list[index].dev) - 1] == ':') { | 
 |                     partition_list[index].dev[strlen(partition_list[index].dev) - 1] = '\0'; | 
 |                 } | 
 |  | 
 |                 partition_list[index].partition_size = (uint32)strtoul(size_str, NULL, 16); | 
 |                 partition_list[index].erase_size = (uint32)strtoul(erase_size_str, NULL, 16); | 
 |                 // XXX-sdtim or XXX-mount | 
 |                 ssize_t index_sdtim = str_indexof(partition_list[index].name, "-sdtim"); | 
 |                 ssize_t index_mount = str_indexof(partition_list[index].name, "-mount"); | 
 |                 if(index_sdtim > 0 || index_mount > 0) { | 
 |                     if(index_sdtim > 0) { | 
 |                         memcpy(name_temp, partition_list[index].name, index_sdtim); | 
 |                     } else { | 
 |                         memcpy(name_temp, partition_list[index].name, index_mount); | 
 |                     } | 
 |                     if(index > 0) { | 
 |                         partition_list[index].partition_start = partition_list[index - 1].partition_start + partition_list[index - 1].partition_size; | 
 |                     } | 
 |                 } else { | 
 |                     if(strlen(name_temp) > 0) { | 
 |                         memset(name_temp, 0x0, 32); | 
 |                         if(index > 0) { | 
 |                             partition_list[index].partition_start = partition_list[index - 2].partition_start; | 
 |                         } | 
 |                     } else { | 
 |                         if(index > 0) { | 
 |                             partition_list[index].partition_start = partition_list[index - 1].partition_start + partition_list[index - 1].partition_size; | 
 |                         } | 
 |                     } | 
 |                 } | 
 |                 partition_list[index].used = TRUE; | 
 |             } else { | 
 |                 LOGE("sscanf(%s) fail:%d", buff, errno); | 
 |                 return NULL; | 
 |             } | 
 |             index++; | 
 |         } | 
 |         memset(buff, 0x0, 64); | 
 |     } | 
 |     fclose(fp); | 
 |  | 
 |     int i = 0; | 
 |     while(i < MBTK_PARTITION_NUM_MAX) { | 
 |         if(partition_list[i].used) { | 
 |             LOGD("%s(%s) : %08x %08x", partition_list[i].name, partition_list[i].dev, | 
 |                 partition_list[i].partition_start, partition_list[i].partition_size); | 
 |         } | 
 |         i++; | 
 |     } | 
 |  | 
 |     partition_inited = TRUE; | 
 |     return partition_list; | 
 | } | 
 |  | 
 | int mbtk_partition_get_by_name(char *partition_name, mbtk_partition_info_t *info) | 
 | { | 
 |     FILE *fp = fopen("/proc/mtd", "r"); | 
 |     if(fp == NULL) { | 
 |         LOGE("fopen(/proc/mtd) fail:%d", errno); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     char buff[64]; | 
 |     char size_str[16]; | 
 |     char erase_size_str[16]; | 
 |     char name[32]; | 
 |     memset(buff, 0x0, sizeof(buff)); | 
 |     while(fgets(buff, sizeof(buff), fp)) { | 
 |         if(strstr(buff, partition_name)) { | 
 |             memset(size_str, 0x0, sizeof(size_str)); | 
 |             memset(erase_size_str, 0x0, sizeof(erase_size_str)); | 
 |             memset(name, 0x0, sizeof(name)); | 
 |             memcpy(info->dev, "/dev/", 5); | 
 |             if(4 == sscanf(buff, "%s %s %s %s", info->dev + 5, size_str, erase_size_str, name)) { | 
 |                 if(name[0] == '\"' && name[strlen(name) - 1] == '\"') { | 
 |                     memcpy(info->name, name + 1, strlen(name) - 2); // No copy "" | 
 |                 } else { | 
 |                     LOGE("partition(%s) name error.", buff); | 
 |                     return -1; | 
 |                 } | 
 |  | 
 |                 if(info->dev[strlen(info->dev) - 1] == ':') { | 
 |                     info->dev[strlen(info->dev) - 1] = '\0'; | 
 |                 } | 
 |  | 
 |                 info->partition_size = (uint32)strtoul(size_str, NULL, 16); | 
 |                 info->erase_size = (uint32)strtoul(erase_size_str, NULL, 16); | 
 |                 //info->partition_start += info->partition_size; | 
 |                 break; | 
 |             } else { | 
 |                 LOGE("sscanf(%s) fail:%d", buff, errno); | 
 |                 return -1; | 
 |             } | 
 |         } | 
 |         memset(buff, 0x0, sizeof(buff)); | 
 |     } | 
 |     fclose(fp); | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 |  |