GCOV Execution Analysis for epath_utils.c
The left column is the number of times the code was executed
during the unit test suites.
Exec | Code | Line # | |
---|---|---|---|
Source:epath_utils.c | 1 | ||
Graph:.libs/epath_utils.gcno | 2 | ||
Data:.libs/epath_utils.gcda | 3 | ||
Runs:378 | 4 | ||
Programs:378 | 5 | ||
/* -*- linux-c -*- | 6 | ||
* | 7 | ||
* (C) Copyright IBM Corp. 2003, 2004 | 8 | ||
* | 9 | ||
* This program is distributed in the hope that it will be useful, | 10 | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This | 12 | ||
* file and program are licensed under a BSD style license. See | 13 | ||
* the Copying file included with the OpenHPI distribution for | 14 | ||
* full licensing terms. | 15 | ||
* | 16 | ||
* Author(s): | 17 | ||
* Steve Sherman < address removed > | 18 | ||
* Renier Morales < address removed > | 19 | ||
* Thomas Kanngieser < address removed > | 20 | ||
* Chris Chia < address removed > | 21 | ||
*/ | 22 | ||
23 | |||
/****************************************************************************** | 24 | ||
* DESCRIPTION: | 25 | ||
* Module contains functions to convert between HPI's SaHpiEntityPathT | 26 | ||
* structure and an OpenHPI canonical string. The canonical string is formed | 27 | ||
* by removing the "SAHPI_ENT_" prefix from the HPI types, and creating | 28 | ||
* tuples for the entity types. Order of significance is inverted to make | 29 | ||
* entity paths look more like Unix directory structure. It is also assumed | 30 | ||
* that {ROOT,0} exists implicitly before all of these entries. For example: | 31 | ||
* | 32 | ||
* {SYSTEM_CHASSIS,2}{PROCESSOR_BOARD,0} | 33 | ||
* | 34 | ||
* FUNCTIONS: | 35 | ||
* string2entitypath - Coverts canonical entity path string to HPI entity path | 36 | ||
* entitypath2string - Coverts HPI entity path to canonical entity path string | 37 | ||
* ep_concat - Concatenates two SaHpiEntityPathT together. | 38 | ||
* | 39 | ||
* NOTES: | 40 | ||
* - SAHPI_ENT_ROOT is used to identify end element of an entity path | 41 | ||
* fully populated entity path may not have a SAHPI_ENT_ROOT. | 42 | ||
* - Duplicate names in SaHPIEntityTypeT enumeration aren't handled | 43 | ||
* Names below won't be preserved across conversion calls: | 44 | ||
* - IPMI_GROUP - IPMI_GROUP + 0x90 | 45 | ||
* - IPMI_GROUP + 0xB0 - IPMI_GROUP + 0xD0 | 46 | ||
* - ROOT_VALUE - SAFHPI_GROUP | 47 | ||
*****************************************************************************/ | 48 | ||
#include <glib.h> | 49 | ||
#include <stdio.h> | 50 | ||
#include <stdlib.h> | 51 | ||
#include <string.h> | 52 | ||
#include <assert.h> | 53 | ||
54 | |||
#include <oh_utils.h> | 55 | ||
56 | |||
static unsigned int index2entitytype(unsigned int i); | 57 | ||
static int entitytype2index(unsigned int i); | 58 | ||
59 | |||
static gchar *eshort_names[] = { | 60 | ||
"UNSPECIFIED", | 61 | ||
"OTHER", | 62 | ||
"UNKNOWN", | 63 | ||
"PROCESSOR", | 64 | ||
"DISK_BAY", | 65 | ||
"PERIPHERAL_BAY", | 66 | ||
"SYS_MGMNT_MODULE", | 67 | ||
"SYSTEM_BOARD", | 68 | ||
"MEMORY_MODULE", | 69 | ||
"PROCESSOR_MODULE", | 70 | ||
"POWER_SUPPLY", | 71 | ||
"ADD_IN_CARD", | 72 | ||
"FRONT_PANEL_BOARD", | 73 | ||
"BACK_PANEL_BOARD", | 74 | ||
"POWER_SYSTEM_BOARD", | 75 | ||
"DRIVE_BACKPLANE", | 76 | ||
"SYS_EXPANSION_BOARD", | 77 | ||
"OTHER_SYSTEM_BOARD", | 78 | ||
"PROCESSOR_BOARD", | 79 | ||
"POWER_UNIT", | 80 | ||
"POWER_MODULE", | 81 | ||
"POWER_MGMNT", | 82 | ||
"CHASSIS_BACK_PANEL_BOARD", | 83 | ||
"SYSTEM_CHASSIS", | 84 | ||
"SUB_CHASSIS", | 85 | ||
"OTHER_CHASSIS_BOARD", | 86 | ||
"DISK_DRIVE_BAY", | 87 | ||
"PERIPHERAL_BAY_2", | 88 | ||
"DEVICE_BAY", | 89 | ||
"COOLING_DEVICE", | 90 | ||
"COOLING_UNIT", | 91 | ||
"INTERCONNECT", | 92 | ||
"MEMORY_DEVICE", | 93 | ||
"SYS_MGMNT_SOFTWARE", | 94 | ||
"BIOS", | 95 | ||
"OPERATING_SYSTEM", | 96 | ||
"SYSTEM_BUS", | 97 | ||
"GROUP", | 98 | ||
"REMOTE", | 99 | ||
"EXTERNAL_ENVIRONMENT", | 100 | ||
"BATTERY", | 101 | ||
"CHASSIS_SPECIFIC", /* Jumps to 144 */ | 102 | ||
"BOARD_SET_SPECIFIC", /* Jumps to 176 */ | 103 | ||
"OEM_SYSINT_SPECIFIC", /* Jumps to 208 */ | 104 | ||
"ROOT", /* Jumps to 65535 and continues from there... */ | 105 | ||
"RACK", | 106 | ||
"SUBRACK", | 107 | ||
"COMPACTPCI_CHASSIS", | 108 | ||
"ADVANCEDTCA_CHASSIS", | 109 | ||
"RACK_MOUNTED_SERVER", | 110 | ||
"SYSTEM_BLADE", | 111 | ||
"SWITCH", | 112 | ||
"SWITCH_BLADE", | 113 | ||
"SBC_BLADE", | 114 | ||
"IO_BLADE", | 115 | ||
"DISK_BLADE", | 116 | ||
"DISK_DRIVE", | 117 | ||
"FAN", | 118 | ||
"POWER_DISTRIBUTION_UNIT", | 119 | ||
"SPEC_PROC_BLADE", | 120 | ||
"IO_SUBBOARD", | 121 | ||
"SBC_SUBBOARD", | 122 | ||
"ALARM_MANAGER", | 123 | ||
"SHELF_MANAGER", | 124 | ||
"DISPLAY_PANEL", | 125 | ||
"SUBBOARD_CARRIER_BLADE", | 126 | ||
"PHYSICAL_SLOT" | 127 | ||
}; | 128 | ||
129 | |||
static unsigned int eshort_num_names = sizeof( eshort_names ) / sizeof( gchar * ); | 130 | ||
131 | |||
static unsigned int index2entitytype(unsigned int i) | 132 | ||
374 | { | 133 | |
374 | if(i <= ESHORTNAMES_BEFORE_JUMP) { | 134 | |
374 | return i; | 135 | |
0 | } else if(i == ESHORTNAMES_FIRST_JUMP) { | 136 | |
0 | return (unsigned int)SAHPI_ENT_CHASSIS_SPECIFIC; | 137 | |
0 | } else if(i == ESHORTNAMES_SECOND_JUMP) { | 138 | |
0 | return (unsigned int)SAHPI_ENT_BOARD_SET_SPECIFIC; | 139 | |
0 | } else if(i == ESHORTNAMES_THIRD_JUMP) { | 140 | |
0 | return (unsigned int)SAHPI_ENT_OEM_SYSINT_SPECIFIC; | 141 | |
} else { | 142 | ||
0 | assert(i >= ESHORTNAMES_LAST_JUMP); | 143 | |
0 | return (i - ESHORTNAMES_LAST_JUMP + (unsigned int)SAHPI_ENT_ROOT); | 144 | |
} | 145 | ||
} | 146 | ||
147 | |||
static int entitytype2index(unsigned int i) | 148 | ||
6660 | { | 149 | |
6660 | if(i <= ESHORTNAMES_BEFORE_JUMP) | 150 | |
4440 | return i; | 151 | |
2220 | else if (i == (unsigned int)SAHPI_ENT_CHASSIS_SPECIFIC) | 152 | |
0 | return ESHORTNAMES_FIRST_JUMP; | 153 | |
2220 | else if (i == (unsigned int)SAHPI_ENT_BOARD_SET_SPECIFIC) | 154 | |
0 | return ESHORTNAMES_SECOND_JUMP; | 155 | |
2220 | else if (i == (unsigned int)SAHPI_ENT_OEM_SYSINT_SPECIFIC) | 156 | |
0 | return ESHORTNAMES_THIRD_JUMP; | 157 | |
2220 | else if (i >= (unsigned int)SAHPI_ENT_ROOT && | 158 | |
i-(unsigned int)SAHPI_ENT_ROOT < eshort_num_names-ESHORTNAMES_LAST_JUMP) | 159 | ||
2220 | return i-(unsigned int)SAHPI_ENT_ROOT+ESHORTNAMES_LAST_JUMP; | 160 | |
161 | |||
0 | return -1; | 162 | |
} | 163 | ||
164 | |||
/** | 165 | ||
* string2entitypath | 166 | ||
* @epathstr: IN. Pointer to canonical entity path string | 167 | ||
* @epathptr: OUT. Pointer to HPI's entity path structure | 168 | ||
* | 169 | ||
* Converts an entity path canonical string into a | 170 | ||
* SaHpiEntityPathT structure. | 171 | ||
* | 172 | ||
* Returns: 0 Successful return, -1 Error return | 173 | ||
*/ | 174 | ||
int string2entitypath(const gchar *epathstr, SaHpiEntityPathT *epathptr) | 175 | ||
374 | { | 176 | |
177 | |||
374 | gchar **epathdefs = NULL, **epathvalues = NULL; | 178 | |
374 | gchar *gstr = NULL, *etype = NULL, *einstance = NULL, *endptr = NULL; | 179 | |
374 | gint rtncode = 0; | 180 | |
374 | guint i, j, match, instance, num_valid_entities = 0; | 181 | |
374 | GSList *epath_list = NULL, *lst = NULL; | 182 | |
374 | SaHpiEntityT *entityptr = NULL; | 183 | |
374 | gint num = 0; | 184 | |
374 | int is_numeric = 0; | 185 | |
186 | |||
374 | if (epathstr == NULL || epathstr[0] == '\0') { | 187 | |
0 | dbg("Input entity path string is NULL"); | 188 | |
0 | return -1; | 189 | |
} | 190 | ||
191 | |||
/* Split out {xxx,yyy} definition pairs */ | 192 | ||
374 | gstr = g_strstrip(g_strdup(epathstr)); | 193 | |
374 | if (gstr == NULL || gstr[0] == '\0') { | 194 | |
0 | dbg("Stripped entity path string is NULL"); | 195 | |
0 | rtncode = -1; | 196 | |
0 | goto CLEANUP; | 197 | |
} | 198 | ||
199 | |||
374 | epathdefs = g_strsplit(gstr, EPATHSTRING_END_DELIMITER, -1); | 200 | |
374 | if (epathdefs == NULL) { | 201 | |
0 | dbg("Could not split entity path string."); | 202 | |
0 | rtncode = -1; | 203 | |
0 | goto CLEANUP; | 204 | |
} | 205 | ||
206 | |||
/* Split out HPI entity type and instance strings */ | 207 | ||
748 | for (i=0; epathdefs[i] != NULL && epathdefs[i][0] != '\0'; i++) { | 208 | |
209 | |||
374 | epathdefs[i] = g_strstrip(epathdefs[i]); | 210 | |
/* Check format - for starting delimiter and a comma */ | 211 | ||
374 | if ((epathdefs[i][0] != EPATHSTRING_START_DELIMITER_CHAR) || | 212 | |
(strpbrk(epathdefs[i], EPATHSTRING_VALUE_DELIMITER) == NULL)) { | 213 | ||
0 | dbg("Invalid entity path format."); | 214 | |
0 | rtncode = -1; | 215 | |
0 | goto CLEANUP; | 216 | |
} | 217 | ||
218 | |||
374 | epathvalues = g_strsplit(epathdefs[i], | 219 | |
EPATHSTRING_VALUE_DELIMITER, | 220 | ||
ELEMENTS_IN_SaHpiEntityT); | 221 | ||
374 | epathvalues[0] = g_strdelimit(epathvalues[0], EPATHSTRING_START_DELIMITER, ' '); | 222 | |
223 | |||
374 | etype = g_strstrip(epathvalues[0]); | 224 | |
374 | einstance = g_strstrip(epathvalues[1]); | 225 | |
226 | |||
374 | instance = strtol(einstance, &endptr, 10); | 227 | |
374 | if (endptr[0] != '\0') { | 228 | |
0 | dbg("Invalid instance character"); | 229 | |
0 | rtncode = -1; | 230 | |
0 | goto CLEANUP; | 231 | |
} | 232 | ||
233 | |||
8976 | for (match=0, j=0; j < eshort_num_names; j++) { | 234 | |
8976 | if (!strcmp(eshort_names[j], etype)) { | 235 | |
374 | match = 1; | 236 | |
374 | break; | 237 | |
} | 238 | ||
} | 239 | ||
240 | |||
374 | is_numeric = 0; | 241 | |
242 | |||
374 | if (!match) { | 243 | |
// check for numeric type | 244 | ||
0 | num = strtol(etype,&endptr, 0); | 245 | |
246 | |||
0 | if (num <= 0 || endptr[0] != '\0') { | 247 | |
0 | dbg("Invalid entity type string"); | 248 | |
0 | rtncode = -1; | 249 | |
0 | goto CLEANUP; | 250 | |
} | 251 | ||
252 | |||
0 | is_numeric = 1; | 253 | |
} | 254 | ||
255 | |||
/* Save entity path definitions; reverse order */ | 256 | ||
374 | if (num_valid_entities < SAHPI_MAX_ENTITY_PATH) { | 257 | |
374 | entityptr = (SaHpiEntityT *)g_malloc0(sizeof(*entityptr)); | 258 | |
374 | if (entityptr == NULL) { | 259 | |
0 | dbg("Out of memory"); | 260 | |
0 | rtncode = -1; | 261 | |
0 | goto CLEANUP; | 262 | |
} | 263 | ||
264 | |||
374 | if (is_numeric) | 265 | |
0 | entityptr->EntityType = num; | 266 | |
else | 267 | ||
374 | entityptr->EntityType = index2entitytype(j); | 268 | |
269 | |||
374 | entityptr->EntityLocation = instance; | 270 | |
374 | epath_list = g_slist_prepend(epath_list, (gpointer)entityptr); | 271 | |
} | 272 | ||
273 | |||
374 | num_valid_entities++; | 274 | |
} | 275 | ||
276 | |||
/* Initialize and write HPI entity path structure */ | 277 | ||
374 | ep_init(epathptr); | 278 | |
279 | |||
748 | for (i = 0; epath_list != NULL; i++) { | 280 | |
374 | lst = epath_list; | 281 | |
374 | if (i < SAHPI_MAX_ENTITY_PATH) { | 282 | |
374 | epathptr->Entry[i].EntityType = | 283 | |
((SaHpiEntityT *)(lst->data))->EntityType; | 284 | ||
374 | epathptr->Entry[i].EntityLocation = | 285 | |
((SaHpiEntityT *)(lst->data))->EntityLocation; | 286 | ||
} | 287 | ||
374 | epath_list = g_slist_remove_link(epath_list,lst); | 288 | |
374 | g_free(lst->data); | 289 | |
374 | g_slist_free(lst); | 290 | |
} | 291 | ||
292 | |||
374 | if (num_valid_entities > SAHPI_MAX_ENTITY_PATH) { | 293 | |
0 | dbg("Too many entity defs"); | 294 | |
0 | rtncode = -1; | 295 | |
} | 296 | ||
297 | |||
CLEANUP: | 298 | ||
374 | g_free(gstr); | 299 | |
374 | g_strfreev(epathdefs); | 300 | |
374 | g_strfreev(epathvalues); | 301 | |
374 | g_slist_free(epath_list); | 302 | |
303 | |||
374 | return(rtncode); | 304 | |
} /* End string2entitypath */ | 305 | ||
306 | |||
/** | 307 | ||
* entitypath2string | 308 | ||
* @epathptr: IN. Pointer to HPI's entity path structure | 309 | ||
* @epathstr: OUT. Pointer to canonical entity path string | 310 | ||
* @strsize: IN. Canonical string length | 311 | ||
* | 312 | ||
* Converts an entity path structure into its | 313 | ||
* canonical string version. | 314 | ||
* | 315 | ||
* Returns: >0 Number of characters written to canonical entity path string, | 316 | ||
* -1 Error return. -2 Entity path has invalid entity types. | 317 | ||
*/ | 318 | ||
int entitypath2string(const SaHpiEntityPathT *epathptr, gchar *epathstr, const gint strsize) | 319 | ||
0 | { | 320 | |
321 | |||
0 | gchar *instance_str, *catstr, *tmpstr; | 322 | |
0 | gint err, i, strcount = 0, rtncode = 0; | 323 | |
0 | int tidx; | 324 | |
0 | gchar *type_str; | 325 | |
0 | gchar type_str_buffer[20]; | 326 | |
327 | |||
0 | if (epathstr == NULL || strsize <= 0) { | 328 | |
0 | dbg("Null string or invalid string size"); | 329 | |
0 | return -1; | 330 | |
} | 331 | ||
332 | |||
0 | if (epathptr == NULL) { | 333 | |
0 | *epathstr = '\0'; | 334 | |
0 | return 0; | 335 | |
} | 336 | ||
337 | |||
/*if (validate_ep(epathptr)) { | 338 | ||
dbg("Entity path contains invalid types. Unable to convert to string."); | 339 | ||
return -2; | 340 | ||
}*/ | 341 | ||
342 | |||
0 | instance_str = (gchar *)g_malloc0(OH_MAX_LOCATION_DIGITS + 1); | 343 | |
0 | tmpstr = (gchar *)g_malloc0(strsize); | 344 | |
0 | if (instance_str == NULL || tmpstr == NULL) { | 345 | |
0 | dbg("Out of memory"); | 346 | |
0 | rtncode = -1; | 347 | |
0 | goto CLEANUP; | 348 | |
} | 349 | ||
350 | |||
/* Find last element of structure. Disregard ROOT element | 351 | ||
* and count as last in entity path. | 352 | ||
*/ | 353 | ||
0 | for (i = 0; i < SAHPI_MAX_ENTITY_PATH; i++) { | 354 | |
0 | if (epathptr->Entry[i].EntityType == SAHPI_ENT_ROOT) { | 355 | |
0 | break; | 356 | |
} | 357 | ||
} | 358 | ||
359 | |||
/* Parse entity path into a string */ | 360 | ||
0 | for (i--; i >= 0; i--) { | 361 | |
0 | guint num_digits, work_instance_num; | 362 | |
363 | |||
/* Validate and convert data */ | 364 | ||
0 | work_instance_num = epathptr->Entry[i].EntityLocation; | 365 | |
0 | for (num_digits = 1; (work_instance_num = work_instance_num/10) > 0; num_digits++); | 366 | |
367 | |||
0 | if (num_digits > OH_MAX_LOCATION_DIGITS) { | 368 | |
0 | dbg("Instance value too big"); | 369 | |
0 | rtncode = -1; | 370 | |
0 | goto CLEANUP; | 371 | |
} | 372 | ||
0 | memset(instance_str, 0, OH_MAX_LOCATION_DIGITS + 1); | 373 | |
0 | err = snprintf(instance_str, OH_MAX_LOCATION_DIGITS + 1, | 374 | |
"%d", epathptr->Entry[i].EntityLocation); | 375 | ||
376 | |||
/* Find string for current entity type */ | 377 | ||
0 | tidx = entitytype2index(epathptr->Entry[i].EntityType); | 378 | |
0 | if ( tidx >= 0 ) | 379 | |
0 | type_str = eshort_names[tidx]; | 380 | |
else { /* String for entity type not found. */ | 381 | ||
0 | err = snprintf(type_str_buffer, 20, "%d", | 382 | |
epathptr->Entry[i].EntityType); | 383 | ||
0 | type_str = type_str_buffer; | 384 | |
} | 385 | ||
386 | |||
0 | strcount = strcount + | 387 | |
strlen(EPATHSTRING_START_DELIMITER) + | 388 | ||
strlen(type_str) + | 389 | ||
strlen(EPATHSTRING_VALUE_DELIMITER) + | 390 | ||
strlen(instance_str) + | 391 | ||
strlen(EPATHSTRING_END_DELIMITER); | 392 | ||
393 | |||
0 | if (strcount > strsize - 1) { | 394 | |
0 | dbg("Not enough space allocated for string"); | 395 | |
0 | rtncode = -1; | 396 | |
0 | goto CLEANUP; | 397 | |
} | 398 | ||
399 | |||
0 | catstr = g_strconcat(EPATHSTRING_START_DELIMITER, | 400 | |
type_str, | 401 | ||
EPATHSTRING_VALUE_DELIMITER, | 402 | ||
instance_str, | 403 | ||
EPATHSTRING_END_DELIMITER, | 404 | ||
NULL); | 405 | ||
406 | |||
0 | strcat(tmpstr, catstr); | 407 | |
0 | g_free(catstr); | 408 | |
} | 409 | ||
0 | rtncode = strcount; | 410 | |
/* Write string */ | 411 | ||
0 | memset(epathstr, 0 , strsize); | 412 | |
0 | strcpy(epathstr, tmpstr); | 413 | |
414 | |||
CLEANUP: | 415 | ||
0 | g_free(instance_str); | 416 | |
0 | g_free(tmpstr); | 417 | |
418 | |||
0 | return(rtncode); | 419 | |
} /* End entitypath2string */ | 420 | ||
421 | |||
/** | 422 | ||
* ep_init | 423 | ||
* @ep: Pointer to SaHpiEntityPathT structure to initialize. | 424 | ||
* | 425 | ||
* Initializes the given entity path to all {ROOT,0} elements. | 426 | ||
* | 427 | ||
* Returns: void. | 428 | ||
**/ | 429 | ||
4488 | void ep_init(SaHpiEntityPathT *ep) { | 430 | |
4488 | int i; | 431 | |
432 | |||
4488 | if (!ep) return; | 433 | |
434 | |||
76296 | for (i = 0; i < SAHPI_MAX_ENTITY_PATH; i++) { | 435 | |
71808 | ep->Entry[i].EntityType = SAHPI_ENT_ROOT; | 436 | |
71808 | ep->Entry[i].EntityLocation = 0; | 437 | |
} | 438 | ||
} | 439 | ||
440 | |||
/** | 441 | ||
* ep_concat | 442 | ||
* @dest: IN,OUT Left-hand entity path. Gets appended with @append. | 443 | ||
* @append: IN Right-hand entity path. Pointer entity path to be appended. | 444 | ||
* | 445 | ||
* Concatenate two entity path structures (SaHpiEntityPathT). | 446 | ||
* @dest is assumed to be the least significant entity path in the operation. | 447 | ||
* append will be truncated into @dest, if it doesn't fit completely in the space | 448 | ||
* that @dest has available relative to SAHPI_MAX_ENTITY_PATH. | 449 | ||
* | 450 | ||
* Returns: 0 on Success, -1 if dest is NULL. | 451 | ||
**/ | 452 | ||
int ep_concat(SaHpiEntityPathT *dest, const SaHpiEntityPathT *append) | 453 | ||
8228 | { | 454 | |
8228 | unsigned int i, j; | 455 | |
456 | |||
8228 | if (!dest) return -1; | 457 | |
8228 | if (!append) return 0; | 458 | |
459 | |||
12342 | for (i = 0; i < SAHPI_MAX_ENTITY_PATH; i++) { | 460 | |
12342 | if (dest->Entry[i].EntityType == SAHPI_ENT_ROOT) { | 461 | |
8228 | break; | 462 | |
} | 463 | ||
} | 464 | ||
465 | |||
20570 | for (j = 0; i < SAHPI_MAX_ENTITY_PATH; i++) { | 466 | |
20570 | dest->Entry[i].EntityLocation = append->Entry[j].EntityLocation; | 467 | |
20570 | dest->Entry[i].EntityType = append->Entry[j].EntityType; | 468 | |
20570 | if (append->Entry[j].EntityType == SAHPI_ENT_ROOT) break; | 469 | |
12342 | j++; | 470 | |
} | 471 | ||
472 | |||
8228 | return 0; | 473 | |
} | 474 | ||
475 | |||
/** | 476 | ||
* validate_ep | 477 | ||
* @ep: Pointer to an SaHpiEntityPathT structure. | 478 | ||
* | 479 | ||
* This will check the entity path to make sure it does not contain | 480 | ||
* any invalid entity types in it up to the root element if it has it. | 481 | ||
* | 482 | ||
* Returns: 0 if entity path is valid, -1 otherwise. | 483 | ||
**/ | 484 | ||
int validate_ep(const SaHpiEntityPathT *ep) | 485 | ||
2220 | { | 486 | |
2220 | int check = 0; | 487 | |
2220 | int i; | 488 | |
489 | |||
6660 | for (i = 0; i < SAHPI_MAX_ENTITY_PATH; i++) { | 490 | |
6660 | if ( entitytype2index(ep->Entry[i].EntityType) < 0 | 491 | |
&& ep->Entry[i].EntityType > 255) { | 492 | ||
0 | check = -1; | 493 | |
0 | break; | 494 | |
6660 | } else if (ep->Entry[i].EntityType == SAHPI_ENT_ROOT) break; | 495 | |
} | 496 | ||
497 | |||
2220 | return check; | 498 | |
} | 499 | ||
500 | |||
/** | 501 | ||
* set_ep_instance | 502 | ||
* @ep: Pointer to entity path to work on | 503 | ||
* @et: entity type to look for | 504 | ||
* @ei: entity instance to set when entity type is found | 505 | ||
* | 506 | ||
* Set an instance number in the entity path given at the first | 507 | ||
* position (from least significant to most) the specified entity type is found. | 508 | ||
* | 509 | ||
* Returns: 0 on Success, -1 if the entity type was not found. | 510 | ||
**/ | 511 | ||
int set_ep_instance(SaHpiEntityPathT *ep, SaHpiEntityTypeT et, SaHpiEntityLocationT ei) | 512 | ||
0 | { | 513 | |
0 | int i; | 514 | |
0 | int retval = -1; | 515 | |
516 | |||
0 | if (!ep) return retval; | 517 | |
518 | |||
0 | for (i = 0; i < SAHPI_MAX_ENTITY_PATH; i++) { | 519 | |
0 | if (ep->Entry[i].EntityType == et) { | 520 | |
0 | ep->Entry[i].EntityLocation = ei; | 521 | |
0 | retval = 0; | 522 | |
0 | break; | 523 | |
0 | } else if (ep->Entry[i].EntityType == SAHPI_ENT_ROOT) { | 524 | |
0 | break; | 525 | |
} | 526 | ||
} | 527 | ||
0 | return retval; | 528 | |
} | 529 | ||
530 | |||
/** | 531 | ||
* ep_cmp | 532 | ||
* @ep1: Pointer to entity path struct | 533 | ||
* @ep2: Pointer to entity path struct | 534 | ||
* | 535 | ||
* Compare two entity paths up to their root element. | 536 | ||
* To be equal, they must have the same number of elements and each element | 537 | ||
* (type and instance pair) must be equal to the corresponding element | 538 | ||
* in the other entity path. | 539 | ||
* | 540 | ||
* Returns: 0 if equal, -1 if not. | 541 | ||
**/ | 542 | ||
int ep_cmp(const SaHpiEntityPathT *ep1, const SaHpiEntityPathT *ep2) | 543 | ||
10104 | { | 544 | |
10104 | unsigned int i, j; | 545 | |
546 | |||
10104 | if ((!ep1) || (!ep2)) { | 547 | |
0 | dbg("ep_cmp error - null pointer\n"); | 548 | |
0 | return -1; | 549 | |
} | 550 | ||
551 | |||
20588 | for ( i = 0; i < SAHPI_MAX_ENTITY_PATH; i++ ) { | 552 | |
20588 | if (ep1->Entry[i].EntityType == SAHPI_ENT_ROOT) { | 553 | |
10104 | i++; | 554 | |
10104 | break; | 555 | |
} | 556 | ||
} | 557 | ||
558 | |||
27308 | for ( j = 0; j < SAHPI_MAX_ENTITY_PATH; j++ ) { | 559 | |
27308 | if (ep2->Entry[j].EntityType == SAHPI_ENT_ROOT) { | 560 | |
10104 | j++; | 561 | |
10104 | break; | 562 | |
} | 563 | ||
} | 564 | ||
565 | |||
10104 | if ( i != j ) { | 566 | |
/* dbg("ep1 element count %d != ep2 %d\n", i, j); */ | 567 | ||
4120 | return -1; | 568 | |
} | 569 | ||
570 | |||
18326 | for ( i = 0; i < j; i++ ) { | 571 | |
14212 | if (ep1->Entry[i].EntityType != ep2->Entry[i].EntityType || | 572 | |
ep1->Entry[i].EntityLocation != ep2->Entry[i].EntityLocation) { | 573 | ||
/* dbg("Entity element %d: EP1 {%d,%d} != EP2 {%d,%d}", i, | 574 | ||
ep1->Entry[i].EntityType, | 575 | ||
ep1->Entry[i].EntityLocation, | 576 | ||
ep2->Entry[i].EntityType, | 577 | ||
ep2->Entry[i].EntityLocation); */ | 578 | ||
1870 | return -1; | 579 | |
} | 580 | ||
} | 581 | ||
582 | |||
4114 | return 0; | 583 | |
} | 584 | ||
585 | |||
/** | 586 | ||
* print_ep | 587 | ||
* @ep: Pointer to entity path stucture. | 588 | ||
* | 589 | ||
* Print the string form of an entity path structure. | 590 | ||
* | 591 | ||
* Returns: 0 on Success, -1 on Failure. | 592 | ||
**/ | 593 | ||
int print_ep(const SaHpiEntityPathT *ep) | 594 | ||
0 | { | 595 | |
0 | const int buffer_size = 512; | 596 | |
0 | gchar epstr[buffer_size]; | 597 | |
0 | int len; | 598 | |
599 | |||
0 | memset(epstr,0,buffer_size); | 600 | |
601 | |||
0 | if (!ep) { | 602 | |
0 | dbg("Error: null pointer \n"); | 603 | |
0 | return -1; | 604 | |
} | 605 | ||
606 | |||
0 | len = entitypath2string(ep, epstr, sizeof(epstr)); | 607 | |
608 | |||
0 | if (len < 0) return -1; | 609 | |
/* Entity path with a sole root element will be an empty string */ | 610 | ||
611 | |||
0 | printf("Entity Path=\"%s\"\n", epstr); | 612 | |
613 | |||
0 | return 0; | 614 | |
} | 615 | ||
616 | |||
/********************************************************************** | 617 | ||
* oh_derive_string: | 618 | ||
* @ep - Pointer to entity's HPI SaHpiEntityPathT. | 619 | ||
* @str - Un-normalized character string. | 620 | ||
* | 621 | ||
* This function "normalizes" a string (such as an SNMP OID) | 622 | ||
* based on entity path. Starting from the end of @str, this routine | 623 | ||
* replaces the letter 'x', with the last instance number of entity path, | 624 | ||
* the process is repeated until all 'x' are replaced by an instance number. | 625 | ||
* For example, | 626 | ||
* | 627 | ||
* @str = ".1.3.6.1.4.1.2.3.x.2.22.1.5.1.1.5.x" | 628 | ||
* @ep = {SAHPI_ENT_CHASSIS, 51}{SAHPI_ENT_SBC_BLADE, 3} | 629 | ||
* | 630 | ||
* Returns a normalized string of ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.5.3". | 631 | ||
* | 632 | ||
* If @str does not contain any 'x' characters, this routine still | 633 | ||
* allocates memory and returns a "normalized" string. In this case, | 634 | ||
* the normalized string is identical to @str. | 635 | ||
* | 636 | ||
* Note! | 637 | ||
* Caller of this routine MUST g_free() the returned normalized string | 638 | ||
* when finished with it. | 639 | ||
* | 640 | ||
* Returns: | 641 | ||
* Pointer to normalize string - Normal case. | 642 | ||
* NULL - Error. | 643 | ||
**********************************************************************/ | 644 | ||
gchar * oh_derive_string(SaHpiEntityPathT *ep, const gchar *str) | 645 | ||
0 | { | 646 | |
0 | gchar *new_str = NULL, *str_walker = NULL; | 647 | |
0 | gchar **fragments = NULL, **str_nodes = NULL; | 648 | |
0 | guint num_epe, num_blanks, str_strlen = 0; | 649 | |
0 | guint total_num_digits, i, work_instance_num, num_digits; | 650 | |
651 | |||
0 | if (!ep || !str) return(NULL); | 652 | |
653 | |||
0 | for (num_epe = 0; | 654 | |
ep->Entry[num_epe].EntityType != SAHPI_ENT_ROOT && num_epe < SAHPI_MAX_ENTITY_PATH; | 655 | ||
num_epe++); | 656 | ||
/* trace("Number of elements in entity path: %d", num_epe); */ | 657 | ||
658 | |||
0 | if (num_epe == 0) { | 659 | |
0 | dbg("Entity Path is null."); | 660 | |
0 | return(NULL); | 661 | |
} | 662 | ||
0 | if ((str_strlen = strlen(str)) == 0) return(NULL); /* Str is zero length */ | 663 | |
0 | if (!strrchr(str, OH_DERIVE_BLANK_CHAR)) return(g_strdup(str)); /* Nothing to replace */ | 664 | |
665 | |||
0 | for (num_blanks=0, i=0; i<str_strlen; i++) { | 666 | |
0 | if (str[i] == OH_DERIVE_BLANK_CHAR) num_blanks++; | 667 | |
} | 668 | ||
/* trace("Number of blanks in str: %d, %s", num_blanks, str); */ | 669 | ||
0 | if (num_blanks > num_epe) { | 670 | |
0 | dbg("Number of replacments=%d > entity path elements=%d", num_blanks, num_epe); | 671 | |
0 | return(NULL); | 672 | |
} | 673 | ||
674 | |||
0 | fragments = g_strsplit(str, OH_DERIVE_BLANK_STR, - 1); | 675 | |
0 | if (!fragments) { dbg("Cannot split string"); goto CLEANUP; } | 676 | |
0 | str_nodes = g_malloc0((num_blanks + 1) * sizeof(gchar **)); | 677 | |
0 | if (!str_nodes) { dbg("Out of memory."); goto CLEANUP; } | 678 | |
0 | total_num_digits = 0; | 679 | |
0 | for (i=0; i<num_blanks; i++) { | 680 | |
0 | work_instance_num = ep->Entry[num_blanks-1-i].EntityLocation; | 681 | |
0 | for (num_digits = 1; | 682 | |
(work_instance_num = work_instance_num/10) > 0; num_digits++); | 683 | ||
0 | str_nodes[i] = g_malloc0((num_digits+1) * sizeof(gchar)); | 684 | |
0 | if (!str_nodes[i]) {dbg("Out of memory."); goto CLEANUP;} | 685 | |
0 | snprintf(str_nodes[i], (num_digits + 1) * sizeof(gchar), "%d", | 686 | |
ep->Entry[num_blanks - 1 - i].EntityLocation); | 687 | ||
/* trace("Instance number: %s", str_nodes[i]); */ | 688 | ||
0 | total_num_digits = total_num_digits + num_digits; | 689 | |
} | 690 | ||
691 | |||
0 | new_str = g_malloc0((str_strlen-num_blanks + total_num_digits + 1) * sizeof(gchar)); | 692 | |
0 | if (!new_str) { dbg("Out of memory."); goto CLEANUP; } | 693 | |
0 | str_walker = new_str; | 694 | |
0 | for (i=0; fragments[i]; i++) { | 695 | |
0 | str_walker = strcpy(str_walker, fragments[i]); | 696 | |
0 | str_walker = str_walker + strlen(fragments[i]); | 697 | |
0 | if (str_nodes[i]) { | 698 | |
0 | str_walker = strcpy(str_walker, str_nodes[i]); | 699 | |
/* trace("Instance number: %s", str_nodes[i]); */ | 700 | ||
0 | str_walker = str_walker + strlen(str_nodes[i]); | 701 | |
} | 702 | ||
/* trace("New str: %s", new_str); */ | 703 | ||
} | 704 | ||
705 | |||
CLEANUP: | 706 | ||
0 | g_strfreev(fragments); | 707 | |
0 | g_strfreev(str_nodes); | 708 | |
709 | |||
0 | return(new_str); | 710 | |
} | 711 |