diff --git a/ipmitool/lib/ipmi_sdradd.c b/ipmitool/lib/ipmi_sdradd.c index 1ba9347..1ac0d24 100644 --- a/ipmitool/lib/ipmi_sdradd.c +++ b/ipmitool/lib/ipmi_sdradd.c @@ -71,6 +71,8 @@ struct sdr_add_rq { /* This was formerly initialized to 24, reduced this to 19 so the overall message fits into the recommended 32-byte limit */ static int sdr_max_write_len = 19; +int ipmi_parse_range_list(const char *rangeList, unsigned char *pHexList); +int ipmi_hex_to_dec( char * rangeList, unsigned char * pDecValue); static int partial_send(struct ipmi_intf *intf, struct ipmi_rq *req, uint16_t *id) @@ -336,6 +338,231 @@ ipmi_sdr_add_from_sensors(struct ipmi_intf *intf, int maxslot) return rc; } +int ipmi_hex_to_dec( char * strchar, unsigned char * pDecValue) +{ + int rc = -1; + unsigned char retValue = 0; + + if( + (strlen(strchar) == 4) + && + (strchar[0] == '0') + && + (strchar[1] == 'x') + ) + { + rc = 0; + + if((strchar[2] >= '0') && (strchar[2] <= '9')) + { + retValue += ((strchar[2]-'0') * 16); + } + else if((strchar[2] >= 'a') && (strchar[2] <= 'f')) + { + retValue += (((strchar[2]-'a') + 10) * 16); + } + else if((strchar[2] >= 'A') && (strchar[2] <= 'F')) + { + retValue += (((strchar[2]-'A') + 10) * 16); + } + else + { + rc = -1; + } + + if((strchar[3] >= '0') && (strchar[3] <= '9')) + { + retValue += ((strchar[3]-'0')); + } + else if((strchar[3] >= 'a') && (strchar[3] <= 'f')) + { + retValue += (((strchar[3]-'a') + 10)); + } + else if((strchar[3] >= 'A') && (strchar[3] <= 'F')) + { + retValue += (((strchar[3]-'A') + 10)); + } + else + { + rc = -1; + } + } + + if(rc == 0) + { + * pDecValue = retValue; + } + else + { + lprintf(LOG_ERR, "Must be Hex value of 4 characters (Ex.: 0x24)\n"); + } + + return rc; +} + + + +#define MAX_NUM_SLOT 128 +int ipmi_parse_range_list(const char *rangeList, unsigned char * pHexList) +{ + int rc = -1; + + unsigned char listOffset = 0; + char * nextString; + char * rangeString; + char * inProcessString = (char *) rangeList; + + /* Discard empty string */ + if(strlen(rangeList) == 0) + { + return rc; + } + + /* First, cut to comma separated string */ + nextString = strstr( rangeList, "," ); + + if(nextString != rangeList) + { + unsigned char isLast; + /* We get a valid string so far */ + rc = 0; + + do + { + if(nextString != NULL) + { + (*nextString)= 0; + nextString ++; + isLast = 0; + } + else + { + isLast = 1; + } + + /* At this point, it is a single entry or a range */ + rangeString = strstr( inProcessString, "-" ); + if(rangeString == NULL) + { + unsigned char decValue = 0; + + /* Single entry */ + rc = ipmi_hex_to_dec( inProcessString, &decValue); + + if(rc == 0) + { + if((decValue % 2) == 0) + { + pHexList[listOffset++] = decValue; + } + else + { + lprintf(LOG_ERR, "I2c address provided value must be even.\n"); + } + } + } + else + { + unsigned char startValue = 0; + unsigned char endValue = 0; + + + (*rangeString)= 0; /* Cut string*/ + rangeString ++; + + /* Range */ + rc = ipmi_hex_to_dec( inProcessString, &startValue); + if(rc == 0) + rc = ipmi_hex_to_dec( rangeString, &endValue); + + if(rc == 0) + { + if(((startValue % 2) == 0) && ((endValue % 2) == 0)) + { + do + { + pHexList[listOffset++] = startValue; + startValue += 2; + } + while(startValue != endValue); + pHexList[listOffset++] = endValue; + } + else + { + lprintf(LOG_ERR, "I2c address provided value must be even.\n"); + } + } + } + + if(isLast == 0) + { + /* Setup for next string */ + inProcessString = nextString; + nextString = strstr( rangeList, "," ); + } + }while ((isLast == 0) && (rc == 0)); + } + + return rc; +} + +int +ipmi_sdr_add_from_list(struct ipmi_intf *intf, const char *rangeList) +{ + int i; + int rc = 0; + int slave_addr; + int myaddr = intf->target_addr; + unsigned char listValue[MAX_NUM_SLOT]; + + memset( listValue, 0, MAX_NUM_SLOT ); + + /* Build list from string */ + if(ipmi_parse_range_list(rangeList, listValue) != 0) + { + lprintf(LOG_ERR, "Range - List invalid, cannot be parsed."); + return -1; + } + + { + unsigned char counter = 0; + printf("List to scan: (Built-in) "); + while(listValue[counter] != 0) + { + printf("%02x ", listValue[counter]); + counter++; + } + printf("\n"); + } + + printf("Clearing SDR Repository\n"); + if (ipmi_sdr_repo_clear(intf)) { + lprintf(LOG_ERR, "Cannot erase SDRR. Give up."); + return -1; + } + + /* First fill the SDRR from local built-in sensors */ + printf("Sanning built-in sensors..\n"); + rc = sdr_copy_to_sdrr(intf, 1, myaddr, myaddr); + + /* Now fill the SDRR with provided sensors list */ + { + unsigned char counter = 0; + while((rc == 0) && (listValue[counter] != 0)) + { + slave_addr = listValue[counter]; + printf("Scanning %02Xh..\n", slave_addr); + if(sdr_copy_to_sdrr(intf, 0, slave_addr, myaddr) < 0) + { + rc = -1; + } + counter++; + } + } + + return rc; +} + /* * Fill the SDR repository from records stored in a binary file