1 /*
2  * Copyright (C) 2008-2015 FreeIPMI Core Team
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
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.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #if HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #if STDC_HEADERS
26 #include <string.h>
27 #endif /* STDC_HEADERS */
28 #include <assert.h>
29 
30 #include "ipmi-config.h"
31 #include "ipmi-config-section.h"
32 #include "ipmi-config-category-sensors-utils.h"
33 #include "ipmi-config-utils.h"
34 #include "ipmi-config-validate.h"
35 
36 #include "freeipmi-portability.h"
37 #include "pstdout.h"
38 #include "tool-sdr-cache-common.h"
39 
40 /* event field strings */
41 
42 /* achu: making a generic "convert event message string into
43  * key_name" for this tool was difficult.  There are too many
44  * conversions and exceptions to the rules (abbreviations, slashes,
45  * spaces, hypens, spaces w/ hyphens, single quotes, double quotes,
46  * examples, parentheses, strings that are too long, wierd
47  * capitalization, need lower cases, etc.)  that strings never
48  * turned out right.  I decided to just hard code names in at the
49  * end of the day.
50  */
51 
52 char *threshold_event_strings[] =
53   {
54     "Lower_Non_Critical_Going_Low",
55     "Lower_Non_Critical_Going_High",
56     "Lower_Critical_Going_Low",
57     "Lower_Critical_Going_High",
58     "Lower_Non_Recoverable_Going_Low",
59     "Lower_Non_Recoverable_Going_High",
60     "Upper_Non_Critical_Going_Low",
61     "Upper_Non_Critical_Going_High",
62     "Upper_Critical_Going_Low",
63     "Upper_Critical_Going_High",
64     "Upper_Non_Recoverable_Going_Low",
65     "Upper_Non_Recoverable_Going_High",
66     NULL,
67   };
68 
69 char *generic_event_strings_0x02[] =
70   {
71     "Transition_to_Idle",
72     "Transition_to_Active",
73     "Transition_to_Busy",
74     NULL,
75   };
76 
77 char *generic_event_strings_0x03[] =
78   {
79     "State_Deasserted",
80     "State_Asserted",
81     NULL,
82   };
83 
84 char *generic_event_strings_0x04[] =
85   {
86     "Predictive_Failure_Deasserted",
87     "Predictive_Failure_Asserted",
88     NULL,
89   };
90 
91 char *generic_event_strings_0x05[] =
92   {
93     "Limit_Not_Exceeded",
94     "Limit_Exceeded",
95     NULL,
96   };
97 
98 char *generic_event_strings_0x06[] =
99   {
100     "Performance_Met",
101     "Performance_Lags",
102     NULL,
103   };
104 
105 char *generic_event_strings_0x07[] =
106   {
107     "Transition_to_OK",
108     "Transition_to_Non_Critical_from_OK",
109     "Transition_to_Critical_from_Less_Severe",
110     "Transition_to_Non_Recoverable_from_Less_Severe",
111     "Transition_to_Non_Critical_from_More_Severe",
112     "Transition_to_Critical_from_Non_Recoverable",
113     "Transition_to_Non_Recoverable",
114     "Monitor",
115     "Informational",
116     NULL,
117   };
118 
119 char *generic_event_strings_0x08[] =
120   {
121     "Device_Removed_or_Device_Absent",
122     "Device_Inserted_or_Device_Present",
123     NULL,
124   };
125 
126 char *generic_event_strings_0x09[] =
127   {
128     "Device_Disabled",
129     "Device_Enabled",
130     NULL,
131   };
132 
133 char *generic_event_strings_0x0A[] =
134   {
135     "Transition_to_Running",
136     "Transition_to_In_Test",
137     "Transition_to_Power_Off",
138     "Transition_to_On_Line",
139     "Transition_to_Off_Line",
140     "Transition_to_Off_Duty",
141     "Transition_to_Degraded",
142     "Transition_to_Power_Save",
143     "Install_Error",
144     NULL,
145   };
146 
147 char *generic_event_strings_0x0B[] =
148   {
149     "Fully_Redundant",
150     "Redundancy_Lost",
151     "Redundancy_Degraded",
152     "Entered_from_Redundancy_Degraded_or_Fully_Redundant",
153     "Entered_from_Non_Redundant_Insufficient_Resources",
154     "Non_Redundant_Insufficient_Resources",
155     "Redundancy_Degraded_from_Fully_Redundant",
156     "Redundancy_Degraded_from_Non_Redundant",
157     NULL,
158   };
159 
160 char *generic_event_strings_0x0C[] =
161   {
162     "D0_Power_State",
163     "D1_Power_State",
164     "D2_Power_State",
165     "D3_Power_State",
166     NULL,
167   };
168 
169 char *sensor_specific_event_strings_physical_security_chassis_intrusion[] =
170   {
171     "General_Chassis_Intrusion",
172     "Drive_Bay_Intrusion",
173     "IO_Card_Area_Intrusion",
174     "Processor_Area_Intrusion",
175     "LAN_Leash_Lost",
176     "Unauthorized_Dock",
177     "FAN_Area_Intrusion",
178     NULL,
179   };
180 
181 char *sensor_specific_event_strings_platform_security_violation_attempt[] =
182   {
183     "Secure_Mode_Violation_Attempt",
184     "Pre_Boot_Password_Violation_User_Password",
185     "Pre_Boot_Password_Violation_Attempt_Setup_Password",
186     "Pre_Boot_Password_Violation_Network_Boot_Password",
187     "Other_Pre_Boot_Password_Violation",
188     "Out_of_Band_Access_Password_Violation",
189     NULL,
190   };
191 
192 char *sensor_specific_event_strings_processor[] =
193   {
194     "IERR",
195     "Thermal_Trip",
196     "FRB1_BIST_failure",
197     "FRB2_Hang_In_POST_Failure",
198     "FRB3_Processor_Startup_Initialization_Failure",
199     "Configuration_Error",
200     "SM_BIOS_Uncorrectable_CPU_Complex_Error",
201     "Processor_Presence_detected",
202     "Processor_Disabled",
203     "Terminator_Presence_Detected",
204     "Processor_Automatically_Throttled",
205     NULL,
206   };
207 
208 char *sensor_specific_event_strings_power_supply[] =
209   {
210     "Presence_Detected",
211     "Power_Supply_Failure_Detected",
212     "Predictive_Failure",
213     "Power_Supply_Input_Lost_AC_DC",
214     "Power_Supply_Input_Lost_or_Out_of_Range",
215     "Power_Supply_Input_Out_of_Range_but_Present",
216     "Configuration_Error",
217     NULL,
218   };
219 
220 char *sensor_specific_event_strings_power_unit[] =
221   {
222     "Power_Off_or_Power_Down",
223     "Power_Cycle",
224     "240VA_Power_Down",
225     "Interlock_Power_Down",
226     "AC_Lost",
227     "Soft_Power_Control_Failure",
228     "Power_Unit_Failure_Detected",
229     "Predictive_Failure",
230     NULL,
231   };
232 
233 char *sensor_specific_event_strings_memory[] =
234   {
235     "Correctable_ECC",
236     "Uncorrectable_ECC",
237     "Parity",
238     "Memory_Scrub_Failed",
239     "Memory_Device_Disabled",
240     "Correctable_ECC_Logging_Limit_Reached",
241     "Presence_Detected",
242     "Configuration_Error",
243     "Spare",
244     "Memory_Automatically_Throttled",
245     "Critical_Overtemperature",
246     NULL,
247   };
248 
249 char *sensor_specific_event_strings_drive_slot[] =
250   {
251     "Drive_Presence",
252     "Drive_Fault",
253     "Predictive_Failure",
254     "Hot_Spare",
255     "Consistency_Check_In_Progress",
256     "In_Critical_Array",
257     "In_Failed_Array",
258     "Rebuild_or_Remap_In_Progress",
259     "Rebuild_or_Remap_Aborted",
260     NULL,
261   };
262 
263 char *sensor_specific_event_strings_system_firmware_progress[] =
264   {
265     "System_Firmware_Error",
266     "System_Firmware_Hang",
267     "System_Firmware_Progress",
268     NULL,
269   };
270 
271 char *sensor_specific_event_strings_event_logging_disabled[] =
272   {
273     "Correctable_Memory_Error_Logging_Disabled",
274     "Event_Type_Logging_Disabled",
275     "Log_Area_Reset_or_Cleared",
276     "All_Event_Logging_Disabled",
277     "SEL_Full",
278     "SEL_Almost_Full",
279     NULL,
280   };
281 
282 char *sensor_specific_event_strings_system_event[] =
283   {
284     "System_Reconfigured",
285     "OEM_System_Boot_Event",
286     "Undetermined_System_Hardware_Failure",
287     "Entry_Added_to_Auxiliary_Log",
288     "PEF_Action",
289     "Timestamp_Clock_Synch",
290     NULL,
291   };
292 
293 char *sensor_specific_event_strings_critical_interrupt[] =
294   {
295     "Front_Panel_NMI_or_Diagnostic_Interrupt",
296     "Bus_Timeout",
297     "IO_Channel_Check_NMI",
298     "Software_NMI",
299     "PCI_PERR",
300     "PCI_SERR",
301     "EISA_Fail_Safe_Timeout",
302     "Bus_Correctable_Error",
303     "Bus_Uncorrectable_Error",
304     "Fatal_NMI",
305     "Bus_Fatal_Error",
306     "Bus_Degraded",
307     NULL,
308   };
309 
310 char *sensor_specific_event_strings_cable_interconnect[] =
311   {
312     "Cable_Interconnect_Is_Connected",
313     "Configuration_Error_Incorrect_Cable_Connected_or_Incorrect_Interconnection",
314     NULL,
315   };
316 
317 char *sensor_specific_event_strings_boot_error[] =
318   {
319     "No_Bootable_Media",
320     "Non_Bootable_Diskette_Left_In_Drive",
321     "PXE_Server_Not_Found",
322     "Invalid_Boot_Sector",
323     "Timeout_Waiting_For_User_Selection_Of_Boot_Source",
324     NULL,
325   };
326 
327 char *sensor_specific_event_strings_slot_connector[] =
328   {
329     "Fault_Status_Asserted",
330     "Identify_Status_Asserted",
331     "Slot_Connector_Device_Installed_or_Attached",
332     "Slot_Connector_Ready_For_Device_Installation",
333     "Slot_Connector_Ready_For_Device_Removal",
334     "Slot_Power_Is_Off",
335     "Slot_Connector_Device_Removal_Request",
336     "Interlock_Asserted",
337     "Slot_Is_Disabled",
338     "Slot_Holds_Spare_Device",
339     NULL,
340   };
341 
342 /* event state 4-7 are "reserved" and useless */
343 char *sensor_specific_event_strings_watchdog2[] =
344   {
345     "Timer_Expired",
346     "Hard_Reset",
347     "Power_Down",
348     "Power_Cycle",
349     "reserved",
350     "reserved",
351     "reserved",
352     "reserved",
353     "Timer_Interrupt",
354     NULL,
355   };
356 int sensor_specific_event_strings_watchdog2_indexes[] = { 0, 1, 2, 3, 8, -1};
357 
358 char *sensor_specific_event_strings_entity_presence[] =
359   {
360     "Entity_Present",
361     "Entity_Absent",
362     "Entity_Disabled",
363     NULL,
364   };
365 
366 char *sensor_specific_event_strings_management_subsystem_health[] =
367   {
368     "Sensor_Access_Degraded_or_Unavailable",
369     "Controller_Access_Degraded_or_Unavailable",
370     "Management_Controller_Off_Line",
371     "Management_Controller_Unavailable",
372     "Sensor_Failure",
373     "FRU_Failure",
374     NULL,
375   };
376 
377 char *sensor_specific_event_strings_battery[] =
378   {
379     "Battery_Low",
380     "Battery_Failed",
381     "Battery_Presence_Detected",
382     NULL,
383   };
384 
385 char *sensor_specific_event_strings_fru_state[] =
386   {
387     "FRU_Not_Installed",
388     "FRU_Inactive",
389     "FRU_Activation_Requested",
390     "FRU_Activation_In_Progress",
391     "FRU_Active",
392     "FRU_Deactivation_Requested",
393     "FRU_Deactivation_In_Progress",
394     "FRU_Communication_Lost",
395     NULL,
396   };
397 
398 /* convenience structs */
399 
400 struct sensor_event_enable_data {
401   uint8_t all_event_messages;
402   uint8_t scanning_on_this_sensor;
403   uint16_t assertion_bits;
404   uint16_t deassertion_bits;
405 };
406 
407 #define KEY_NAME_MAX_LEN 1024
408 
409 typedef int (*Sdr_event_flags_func)(ipmi_sdr_ctx_t ctx,
410                                     const void *sdr_record,
411                                     unsigned int sdr_record_len,
412                                     uint8_t *event_state_0,
413                                     uint8_t *event_state_1,
414                                     uint8_t *event_state_2,
415                                     uint8_t *event_state_3,
416                                     uint8_t *event_state_4,
417                                     uint8_t *event_state_5,
418                                     uint8_t *event_state_6,
419                                     uint8_t *event_state_7,
420                                     uint8_t *event_state_8,
421                                     uint8_t *event_state_9,
422                                     uint8_t *event_state_10,
423                                     uint8_t *event_state_11,
424                                     uint8_t *event_state_12,
425                                     uint8_t *event_state_13,
426                                     uint8_t *event_state_14);
427 
428 typedef int (*Sdr_threshold_event_flags_func)(ipmi_sdr_ctx_t ctx,
429                                               const void *sdr_record,
430                                               unsigned int sdr_record_len,
431                                               uint8_t *lower_non_critical_going_low,
432                                               uint8_t *lower_non_critical_going_high,
433                                               uint8_t *lower_critical_going_low,
434                                               uint8_t *lower_critical_going_high,
435                                               uint8_t *lower_non_recoverable_going_low,
436                                               uint8_t *lower_non_recoverable_going_high,
437                                               uint8_t *upper_non_critical_going_low,
438                                               uint8_t *upper_non_critical_going_high,
439                                               uint8_t *upper_critical_going_low,
440                                               uint8_t *upper_critical_going_high,
441                                               uint8_t *upper_non_recoverable_going_low,
442                                               uint8_t *upper_non_recoverable_going_high);
443 
444 static ipmi_config_err_t
_get_sensor_event_enable(ipmi_config_state_data_t * state_data,const char * section_name,struct sensor_event_enable_data * data)445 _get_sensor_event_enable (ipmi_config_state_data_t *state_data,
446                           const char *section_name,
447                           struct sensor_event_enable_data *data)
448 {
449   fiid_obj_t obj_cmd_rs = NULL;
450   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
451   ipmi_config_err_t ret;
452   uint8_t sensor_number;
453   int field_flag;
454   uint64_t val;
455 
456   assert (state_data);
457   assert (section_name);
458   assert (data);
459 
460   if ((ret = ipmi_config_sensors_seek_to_sdr_record (state_data,
461                                                      section_name)) != IPMI_CONFIG_ERR_SUCCESS)
462     {
463       rv = ret;
464       goto cleanup;
465     }
466 
467   if (ipmi_sdr_parse_sensor_number (state_data->sdr_ctx,
468                                     NULL,
469                                     0,
470                                     &sensor_number) < 0)
471     {
472       pstdout_fprintf (state_data->pstate,
473                        stderr,
474                        "ipmi_sdr_parse_sensor_number: %s\n",
475                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
476       goto cleanup;
477     }
478 
479   if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_sensor_event_enable_rs)))
480     {
481       pstdout_fprintf (state_data->pstate,
482                        stderr,
483                        "fiid_obj_create: %s\n",
484                        strerror (errno));
485       goto cleanup;
486     }
487 
488   if (ipmi_cmd_get_sensor_event_enable (state_data->ipmi_ctx,
489                                         sensor_number,
490                                         obj_cmd_rs) < 0)
491     {
492       if (ipmi_errnum_is_non_fatal (state_data,
493                                     obj_cmd_rs,
494                                     &ret))
495         rv = ret;
496 
497       if (rv == IPMI_CONFIG_ERR_FATAL_ERROR
498           || state_data->prog_data->args->common_args.debug)
499         pstdout_fprintf (state_data->pstate,
500                          stderr,
501                          "ipmi_cmd_get_sensor_event_enable: %s\n",
502                          ipmi_ctx_errormsg (state_data->ipmi_ctx));
503 
504       goto cleanup;
505     }
506 
507   if (FIID_OBJ_GET (obj_cmd_rs, "all_event_messages", &val) < 0)
508     {
509       pstdout_fprintf (state_data->pstate,
510                        stderr,
511                        "fiid_obj_get: 'all_event_messages': %s\n",
512                        fiid_obj_errormsg (obj_cmd_rs));
513       goto cleanup;
514     }
515   data->all_event_messages = val;
516 
517   if (FIID_OBJ_GET (obj_cmd_rs, "scanning_on_this_sensor", &val) < 0)
518     {
519       pstdout_fprintf (state_data->pstate,
520                        stderr,
521                        "fiid_obj_get: 'scanning_on_this_sensor': %s\n",
522                        fiid_obj_errormsg (obj_cmd_rs));
523       goto cleanup;
524     }
525   data->scanning_on_this_sensor = val;
526 
527   if (data->all_event_messages == IPMI_SENSOR_ALL_EVENT_MESSAGES_DISABLE)
528     {
529       data->assertion_bits = 0;
530       data->deassertion_bits = 0;
531       goto out;
532     }
533 
534   if ((field_flag = fiid_obj_get (obj_cmd_rs,
535                                   "assertion_event_bitmask",
536                                   &val)) < 0)
537     {
538       pstdout_fprintf (state_data->pstate,
539                        stderr,
540                        "fiid_obj_get: 'assertion_event_bitmask': %s\n",
541                        fiid_obj_errormsg (obj_cmd_rs));
542       goto cleanup;
543     }
544 
545   /* assertion event bitmask need not be returned */
546   if (field_flag)
547     data->assertion_bits = val;
548   else
549     data->assertion_bits = 0;
550 
551   if ((field_flag = fiid_obj_get (obj_cmd_rs,
552                                   "deassertion_event_bitmask",
553                                   &val)) < 0)
554     {
555       pstdout_fprintf (state_data->pstate,
556                        stderr,
557                        "fiid_obj_get: 'deassertion_event_bitmask': %s\n",
558                        fiid_obj_errormsg (obj_cmd_rs));
559       goto cleanup;
560     }
561 
562   /* deassertion event bitmask need not be returned */
563   if (field_flag)
564     data->deassertion_bits = val;
565   else
566     data->deassertion_bits = 0;
567 
568  out:
569   rv = IPMI_CONFIG_ERR_SUCCESS;
570  cleanup:
571   fiid_obj_destroy (obj_cmd_rs);
572   return (rv);
573 }
574 
575 static ipmi_config_err_t
_set_sensor_event_enable(ipmi_config_state_data_t * state_data,const char * section_name,struct sensor_event_enable_data * data,uint8_t event_message_action)576 _set_sensor_event_enable (ipmi_config_state_data_t *state_data,
577                           const char *section_name,
578                           struct sensor_event_enable_data *data,
579                           uint8_t event_message_action)
580 {
581   fiid_obj_t obj_cmd_rs = NULL;
582   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
583   ipmi_config_err_t ret;
584   uint8_t sensor_number;
585 
586   assert (state_data);
587   assert (section_name);
588   assert (data);
589 
590   if ((ret = ipmi_config_sensors_seek_to_sdr_record (state_data,
591                                                      section_name)) != IPMI_CONFIG_ERR_SUCCESS)
592     {
593       rv = ret;
594       goto cleanup;
595     }
596 
597   if (ipmi_sdr_parse_sensor_number (state_data->sdr_ctx,
598                                     NULL,
599                                     0,
600                                     &sensor_number) < 0)
601     {
602       pstdout_fprintf (state_data->pstate,
603                        stderr,
604                        "ipmi_sdr_parse_sensor_number: %s\n",
605                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
606       goto cleanup;
607     }
608 
609   if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_set_sensor_event_enable_rs)))
610     {
611       pstdout_fprintf (state_data->pstate,
612                        stderr,
613                        "fiid_obj_create: %s\n",
614                        strerror (errno));
615       goto cleanup;
616     }
617 
618   if (ipmi_cmd_set_sensor_event_enable (state_data->ipmi_ctx,
619                                         sensor_number,
620                                         event_message_action,
621                                         data->scanning_on_this_sensor,
622                                         data->all_event_messages,
623                                         data->assertion_bits,
624                                         data->deassertion_bits,
625                                         obj_cmd_rs) < 0)
626     {
627       if (ipmi_errnum_is_non_fatal (state_data,
628                                     obj_cmd_rs,
629                                     &ret))
630         rv = ret;
631 
632       if (rv == IPMI_CONFIG_ERR_FATAL_ERROR
633           || state_data->prog_data->args->common_args.debug)
634         pstdout_fprintf (state_data->pstate,
635                          stderr,
636                          "ipmi_cmd_set_sensor_event_enable: %s\n",
637                          ipmi_ctx_errormsg (state_data->ipmi_ctx));
638 
639       goto cleanup;
640     }
641 
642   rv = IPMI_CONFIG_ERR_SUCCESS;
643  cleanup:
644   fiid_obj_destroy (obj_cmd_rs);
645   return (rv);
646 }
647 
648 ipmi_config_err_t
sensor_event_enable_enable_all_event_messages_checkout(ipmi_config_state_data_t * state_data,const char * section_name,struct ipmi_config_keyvalue * kv)649 sensor_event_enable_enable_all_event_messages_checkout (ipmi_config_state_data_t *state_data,
650                                                         const char *section_name,
651                                                         struct ipmi_config_keyvalue *kv)
652 {
653   struct sensor_event_enable_data data;
654   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
655   ipmi_config_err_t ret;
656 
657   assert (state_data);
658   assert (section_name);
659   assert (kv);
660 
661   if ((ret = _get_sensor_event_enable (state_data,
662                                        section_name,
663                                        &data)) != IPMI_CONFIG_ERR_SUCCESS)
664     {
665       rv = ret;
666       goto cleanup;
667     }
668 
669   if (ipmi_config_section_update_keyvalue_output (state_data,
670                                                   kv,
671                                                   data.all_event_messages ? "Yes" : "No") < 0)
672     goto cleanup;
673 
674   rv = IPMI_CONFIG_ERR_SUCCESS;
675  cleanup:
676   return (rv);
677 }
678 
679 ipmi_config_err_t
sensor_event_enable_enable_all_event_messages_commit(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv)680 sensor_event_enable_enable_all_event_messages_commit (ipmi_config_state_data_t *state_data,
681                                                       const char *section_name,
682                                                       const struct ipmi_config_keyvalue *kv)
683 {
684   struct sensor_event_enable_data data;
685   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
686   ipmi_config_err_t ret;
687 
688   assert (state_data);
689   assert (section_name);
690   assert (kv);
691 
692   if ((ret = _get_sensor_event_enable (state_data,
693                                        section_name,
694                                        &data)) != IPMI_CONFIG_ERR_SUCCESS)
695     {
696       rv = ret;
697       goto cleanup;
698     }
699 
700   /* clear bits just in case, we're not setting anything here */
701   data.assertion_bits = 0;
702   data.deassertion_bits = 0;
703 
704   data.all_event_messages = same (kv->value_input, "yes");
705 
706   if ((ret = _set_sensor_event_enable (state_data,
707                                        section_name,
708                                        &data,
709                                        IPMI_SENSOR_EVENT_MESSAGE_ACTION_DO_NOT_CHANGE_INDIVIDUAL_ENABLES)) != IPMI_CONFIG_ERR_SUCCESS)
710     {
711       rv = ret;
712       goto cleanup;
713     }
714 
715   rv = IPMI_CONFIG_ERR_SUCCESS;
716  cleanup:
717   return (rv);
718 }
719 
720 ipmi_config_err_t
sensor_event_enable_enable_scanning_on_this_sensor_checkout(ipmi_config_state_data_t * state_data,const char * section_name,struct ipmi_config_keyvalue * kv)721 sensor_event_enable_enable_scanning_on_this_sensor_checkout (ipmi_config_state_data_t *state_data,
722                                                              const char *section_name,
723                                                              struct ipmi_config_keyvalue *kv)
724 {
725   struct sensor_event_enable_data data;
726   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
727   ipmi_config_err_t ret;
728 
729   assert (state_data);
730   assert (section_name);
731   assert (kv);
732 
733   if ((ret = _get_sensor_event_enable (state_data,
734                                        section_name,
735                                        &data)) != IPMI_CONFIG_ERR_SUCCESS)
736     {
737       rv = ret;
738       goto cleanup;
739     }
740 
741   if (ipmi_config_section_update_keyvalue_output (state_data,
742                                                   kv,
743                                                   data.scanning_on_this_sensor ? "Yes" : "No") < 0)
744     goto cleanup;
745 
746   rv = IPMI_CONFIG_ERR_SUCCESS;
747  cleanup:
748   return (rv);
749 }
750 
751 ipmi_config_err_t
sensor_event_enable_enable_scanning_on_this_sensor_commit(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv)752 sensor_event_enable_enable_scanning_on_this_sensor_commit (ipmi_config_state_data_t *state_data,
753                                                            const char *section_name,
754                                                            const struct ipmi_config_keyvalue *kv)
755 {
756   struct sensor_event_enable_data data;
757   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
758   ipmi_config_err_t ret;
759 
760   assert (state_data);
761   assert (section_name);
762   assert (kv);
763 
764   if ((ret = _get_sensor_event_enable (state_data,
765                                        section_name,
766                                        &data)) != IPMI_CONFIG_ERR_SUCCESS)
767     {
768       rv = ret;
769       goto cleanup;
770     }
771 
772   /* clear bits just in case, we're not setting anything here */
773   data.assertion_bits = 0;
774   data.deassertion_bits = 0;
775 
776   data.scanning_on_this_sensor = same (kv->value_input, "yes");
777 
778   if ((ret = _set_sensor_event_enable (state_data,
779                                        section_name,
780                                        &data,
781                                        IPMI_SENSOR_EVENT_MESSAGE_ACTION_DO_NOT_CHANGE_INDIVIDUAL_ENABLES)) != IPMI_CONFIG_ERR_SUCCESS)
782     {
783       rv = ret;
784       goto cleanup;
785     }
786 
787   rv = IPMI_CONFIG_ERR_SUCCESS;
788  cleanup:
789   return (rv);
790 }
791 
792 int
_setup_event_enable_key(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section,const char * key_name,uint8_t event_supported,Key_Checkout checkout_func,Key_Commit commit_func)793 _setup_event_enable_key (ipmi_config_state_data_t *state_data,
794                          struct ipmi_config_section *section,
795                          const char *key_name,
796                          uint8_t event_supported,
797                          Key_Checkout checkout_func,
798                          Key_Commit commit_func)
799 {
800   unsigned int flags = 0;
801 
802   assert (state_data);
803   assert (section);
804   assert (key_name);
805   assert (checkout_func);
806   assert (commit_func);
807 
808   if (event_supported
809       || state_data->prog_data->args->verbose_count)
810     {
811       if (!event_supported)
812         flags |= IPMI_CONFIG_UNDEFINED;
813 
814       if (ipmi_config_section_add_key (state_data,
815                                        section,
816                                        key_name,
817                                        "Possible values: Yes/No",
818                                        flags,
819                                        checkout_func,
820                                        commit_func,
821                                        yes_no_validate) < 0)
822         goto cleanup;
823     }
824 
825   return (0);
826 
827  cleanup:
828   return (-1);
829 }
830 
831 static ipmi_config_err_t
_threshold_event_enable_verify(ipmi_config_state_data_t * state_data,const char * section_name)832 _threshold_event_enable_verify (ipmi_config_state_data_t *state_data,
833                                 const char *section_name)
834 {
835   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
836   ipmi_config_err_t ret;
837   uint8_t event_reading_type_code;
838   int event_reading_type_code_class;
839 
840   assert (state_data);
841   assert (section_name);
842 
843   if ((ret = ipmi_config_sensors_seek_to_sdr_record (state_data,
844                                                      section_name)) != IPMI_CONFIG_ERR_SUCCESS)
845     {
846       rv = ret;
847       goto cleanup;
848     }
849 
850   if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
851                                               NULL,
852                                               0,
853                                               &event_reading_type_code) < 0)
854     {
855       pstdout_fprintf (state_data->pstate,
856                        stderr,
857                        "ipmi_sdr_parse_event_reading_type_code: %s\n",
858                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
859       goto cleanup;
860     }
861 
862   event_reading_type_code_class = ipmi_event_reading_type_code_class (event_reading_type_code);
863 
864   if (event_reading_type_code_class != IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD)
865     {
866       if (state_data->prog_data->args->common_args.debug)
867         pstdout_fprintf (state_data->pstate,
868                          stderr,
869                          "Attempting to access threshold event in non-threshold sensor\n");
870 
871       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
872       goto cleanup;
873     }
874 
875   rv = IPMI_CONFIG_ERR_SUCCESS;
876  cleanup:
877   return (rv);
878 }
879 
880 static ipmi_config_err_t
_threshold_event_enable_get_data(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv,struct sensor_event_enable_data * data,uint16_t * bits,uint8_t * bitposition)881 _threshold_event_enable_get_data (ipmi_config_state_data_t *state_data,
882                                   const char *section_name,
883                                   const struct ipmi_config_keyvalue *kv,
884                                   struct sensor_event_enable_data *data,
885                                   uint16_t *bits,
886                                   uint8_t *bitposition)
887 {
888   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
889   ipmi_config_err_t ret;
890   int found = 0;
891   int i;
892 
893   assert (state_data);
894   assert (section_name);
895   assert (kv);
896   assert (data);
897   assert (bits);
898   assert (bitposition);
899 
900   if ((ret = _get_sensor_event_enable (state_data,
901                                        section_name,
902                                        data)) != IPMI_CONFIG_ERR_SUCCESS)
903     {
904       rv = ret;
905       goto cleanup;
906     }
907 
908   if (stristr (kv->key->key_name, "Deassertion"))
909     (*bits) = data->deassertion_bits;
910   else
911     (*bits) = data->assertion_bits;
912 
913   i = 0;
914   while (threshold_event_strings[i])
915     {
916       if (stristr (kv->key->key_name, threshold_event_strings[i]))
917         {
918           (*bitposition) = i;
919           found++;
920           break;
921         }
922       i++;
923     }
924 
925   if (!found)
926     {
927       if (state_data->prog_data->args->verbose_count)
928         pstdout_printf (state_data->pstate,
929                         "## Unrecognized section:key_name: %s:%s\n",
930                         section_name,
931                         kv->key->key_name);
932       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
933       goto cleanup;
934     }
935 
936   rv = IPMI_CONFIG_ERR_SUCCESS;
937  cleanup:
938   return (rv);
939 }
940 
941 ipmi_config_err_t
threshold_event_enable_checkout(ipmi_config_state_data_t * state_data,const char * section_name,struct ipmi_config_keyvalue * kv)942 threshold_event_enable_checkout (ipmi_config_state_data_t *state_data,
943                                  const char *section_name,
944                                  struct ipmi_config_keyvalue *kv)
945 {
946   struct sensor_event_enable_data data;
947   uint16_t bits = 0;
948   uint8_t bitposition = 0;
949   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
950   ipmi_config_err_t ret;
951 
952   assert (state_data);
953   assert (section_name);
954   assert (kv);
955 
956   if ((ret = _threshold_event_enable_verify (state_data,
957                                              section_name)) != IPMI_CONFIG_ERR_SUCCESS)
958     {
959       rv = ret;
960       goto cleanup;
961     }
962 
963   if ((ret = _threshold_event_enable_get_data (state_data,
964                                                section_name,
965                                                kv,
966                                                &data,
967                                                &bits,
968                                                &bitposition)) != IPMI_CONFIG_ERR_SUCCESS)
969     {
970       rv = ret;
971       goto cleanup;
972     }
973 
974   if (ipmi_config_section_update_keyvalue_output (state_data,
975                                                   kv,
976                                                   ((bits >> bitposition) & 0x1) ? "Yes" : "No") < 0)
977     goto cleanup;
978 
979   rv = IPMI_CONFIG_ERR_SUCCESS;
980  cleanup:
981   return (rv);
982 }
983 
984 ipmi_config_err_t
threshold_event_enable_commit(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv)985 threshold_event_enable_commit (ipmi_config_state_data_t *state_data,
986                                const char *section_name,
987                                const struct ipmi_config_keyvalue *kv)
988 {
989   struct sensor_event_enable_data data;
990   uint16_t bits = 0;
991   uint8_t bitposition = 0;
992   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
993   ipmi_config_err_t ret;
994   uint8_t event_message_action;
995 
996   assert (state_data);
997   assert (section_name);
998   assert (kv);
999 
1000   if ((ret = _threshold_event_enable_verify (state_data,
1001                                              section_name)) != IPMI_CONFIG_ERR_SUCCESS)
1002     {
1003       rv = ret;
1004       goto cleanup;
1005     }
1006 
1007   if ((ret = _threshold_event_enable_get_data (state_data,
1008                                                section_name,
1009                                                kv,
1010                                                &data,
1011                                                &bits,
1012                                                &bitposition)) != IPMI_CONFIG_ERR_SUCCESS)
1013     {
1014       rv = ret;
1015       goto cleanup;
1016     }
1017 
1018   /* due to set sensor event enable mechanics, we need to clear the bits */
1019   data.assertion_bits = 0;
1020   data.deassertion_bits = 0;
1021 
1022   if (stristr (kv->key->key_name, "Deassertion"))
1023     data.deassertion_bits = (0x1 << bitposition);
1024   else
1025     data.assertion_bits = (0x1 << bitposition);
1026 
1027   if (same (kv->value_input, "yes"))
1028     event_message_action = IPMI_SENSOR_EVENT_MESSAGE_ACTION_ENABLE_SELECTED_EVENT_MESSAGES;
1029   else
1030     event_message_action = IPMI_SENSOR_EVENT_MESSAGE_ACTION_DISABLE_SELECTED_EVENT_MESSAGES;
1031 
1032   if ((ret = _set_sensor_event_enable (state_data,
1033                                        section_name,
1034                                        &data,
1035                                        event_message_action)) != IPMI_CONFIG_ERR_SUCCESS)
1036     {
1037       rv = ret;
1038       goto cleanup;
1039     }
1040 
1041   rv = IPMI_CONFIG_ERR_SUCCESS;
1042  cleanup:
1043   return (rv);
1044 }
1045 
1046 static int
_setup_threshold_event_enable_wrapper(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section,const char * type_str,Sdr_threshold_event_flags_func sdr_call)1047 _setup_threshold_event_enable_wrapper (ipmi_config_state_data_t *state_data,
1048                                        struct ipmi_config_section *section,
1049                                        const char *type_str,
1050                                        Sdr_threshold_event_flags_func sdr_call)
1051 {
1052   uint8_t lower_non_critical_going_low = 0;
1053   uint8_t lower_non_critical_going_high = 0;
1054   uint8_t lower_critical_going_low = 0;
1055   uint8_t lower_critical_going_high = 0;
1056   uint8_t lower_non_recoverable_going_low = 0;
1057   uint8_t lower_non_recoverable_going_high = 0;
1058   uint8_t upper_non_critical_going_low = 0;
1059   uint8_t upper_non_critical_going_high = 0;
1060   uint8_t upper_critical_going_low = 0;
1061   uint8_t upper_critical_going_high = 0;
1062   uint8_t upper_non_recoverable_going_low = 0;
1063   uint8_t upper_non_recoverable_going_high = 0;
1064   char key_name[KEY_NAME_MAX_LEN];
1065   uint16_t bitmask = 0;
1066   int rv = -1;
1067   int i;
1068 
1069   assert (state_data);
1070   assert (section);
1071   assert (type_str);
1072   assert (sdr_call);
1073 
1074   if (((*sdr_call)(state_data->sdr_ctx,
1075                    NULL,
1076                    0,
1077                    &lower_non_critical_going_low,
1078                    &lower_non_critical_going_high,
1079                    &lower_critical_going_low,
1080                    &lower_critical_going_high,
1081                    &lower_non_recoverable_going_low,
1082                    &lower_non_recoverable_going_high,
1083                    &upper_non_critical_going_low,
1084                    &upper_non_critical_going_high,
1085                    &upper_critical_going_low,
1086                    &upper_critical_going_high,
1087                    &upper_non_recoverable_going_low,
1088                    &upper_non_recoverable_going_high)) < 0)
1089     goto cleanup;
1090 
1091   /* create bitmask to make things easier */
1092   bitmask |= (lower_non_critical_going_low & 0x1);
1093   bitmask |= ((lower_non_critical_going_high & 0x1) << 1);
1094   bitmask |= ((lower_critical_going_low & 0x1) << 2);
1095   bitmask |= ((lower_critical_going_high & 0x1) << 3);
1096   bitmask |= ((lower_non_recoverable_going_low & 0x1) << 4);
1097   bitmask |= ((lower_non_recoverable_going_high & 0x1) << 5);
1098   bitmask |= ((upper_non_critical_going_low & 0x1) << 6);
1099   bitmask |= ((upper_non_critical_going_high & 0x1) << 7);
1100   bitmask |= ((upper_critical_going_low & 0x1) << 8);
1101   bitmask |= ((upper_critical_going_high & 0x1) << 9);
1102   bitmask |= ((upper_non_recoverable_going_low & 0x1) << 10);
1103   bitmask |= ((upper_non_recoverable_going_high & 0x1) << 11);
1104 
1105   i = 0;
1106   while (threshold_event_strings[i])
1107     {
1108       snprintf (key_name,
1109                 KEY_NAME_MAX_LEN,
1110                 "Enable_%s_Event_%s",
1111                 type_str,
1112                 threshold_event_strings[i]);
1113 
1114       if (_setup_event_enable_key (state_data,
1115                                    section,
1116                                    key_name,
1117                                    ((bitmask >> i) & 0x1),
1118                                    threshold_event_enable_checkout,
1119                                    threshold_event_enable_commit) < 0)
1120         goto cleanup;
1121 
1122       i++;
1123     }
1124 
1125   rv = 0;
1126  cleanup:
1127   return (rv);
1128 }
1129 
1130 int
_setup_threshold_event_enable(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section)1131 _setup_threshold_event_enable (ipmi_config_state_data_t *state_data,
1132                                struct ipmi_config_section *section)
1133 {
1134   int rv = -1;
1135 
1136   assert (state_data);
1137   assert (section);
1138 
1139   if (_setup_threshold_event_enable_wrapper (state_data,
1140                                              section,
1141                                              "Assertion",
1142                                              &ipmi_sdr_parse_threshold_assertion_supported) < 0)
1143     goto cleanup;
1144 
1145   if (_setup_threshold_event_enable_wrapper (state_data,
1146                                              section,
1147                                              "Deassertion",
1148                                              &ipmi_sdr_parse_threshold_deassertion_supported) < 0)
1149     goto cleanup;
1150 
1151   rv = 0;
1152  cleanup:
1153   return (rv);
1154 }
1155 
1156 static int
_get_event_state_bitmask(ipmi_config_state_data_t * state_data,Sdr_event_flags_func sdr_call,uint16_t * bitmask)1157 _get_event_state_bitmask (ipmi_config_state_data_t *state_data,
1158                           Sdr_event_flags_func sdr_call,
1159                           uint16_t *bitmask)
1160 {
1161   uint8_t event_state_0 = 0;
1162   uint8_t event_state_1 = 0;
1163   uint8_t event_state_2 = 0;
1164   uint8_t event_state_3 = 0;
1165   uint8_t event_state_4 = 0;
1166   uint8_t event_state_5 = 0;
1167   uint8_t event_state_6 = 0;
1168   uint8_t event_state_7 = 0;
1169   uint8_t event_state_8 = 0;
1170   uint8_t event_state_9 = 0;
1171   uint8_t event_state_10 = 0;
1172   uint8_t event_state_11 = 0;
1173   uint8_t event_state_12 = 0;
1174   uint8_t event_state_13 = 0;
1175   uint8_t event_state_14 = 0;
1176   int rv = -1;
1177 
1178   assert (state_data);
1179   assert (sdr_call);
1180   assert (bitmask);
1181 
1182   if (((*sdr_call)(state_data->sdr_ctx,
1183                    NULL,
1184                    0,
1185                    &event_state_0,
1186                    &event_state_1,
1187                    &event_state_2,
1188                    &event_state_3,
1189                    &event_state_4,
1190                    &event_state_5,
1191                    &event_state_6,
1192                    &event_state_7,
1193                    &event_state_8,
1194                    &event_state_9,
1195                    &event_state_10,
1196                    &event_state_11,
1197                    &event_state_12,
1198                    &event_state_13,
1199                    &event_state_14)) < 0)
1200     goto cleanup;
1201 
1202   (*bitmask) = 0;
1203   (*bitmask) |= (event_state_0 & 0x1);
1204   (*bitmask) |= ((event_state_1 & 0x1) << 1);
1205   (*bitmask) |= ((event_state_2 & 0x1) << 2);
1206   (*bitmask) |= ((event_state_3 & 0x1) << 3);
1207   (*bitmask) |= ((event_state_4 & 0x1) << 4);
1208   (*bitmask) |= ((event_state_5 & 0x1) << 5);
1209   (*bitmask) |= ((event_state_6 & 0x1) << 6);
1210   (*bitmask) |= ((event_state_7 & 0x1) << 7);
1211   (*bitmask) |= ((event_state_8 & 0x1) << 8);
1212   (*bitmask) |= ((event_state_9 & 0x1) << 9);
1213   (*bitmask) |= ((event_state_10 & 0x1) << 10);
1214   (*bitmask) |= ((event_state_11 & 0x1) << 11);
1215   (*bitmask) |= ((event_state_12 & 0x1) << 12);
1216   (*bitmask) |= ((event_state_13 & 0x1) << 13);
1217   (*bitmask) |= ((event_state_14 & 0x1) << 14);
1218 
1219   rv = 0;
1220  cleanup:
1221   return (rv);
1222 }
1223 
1224 static ipmi_config_err_t
_generic_event_enable_verify(ipmi_config_state_data_t * state_data,const char * section_name,uint8_t * event_reading_type_code_ptr)1225 _generic_event_enable_verify (ipmi_config_state_data_t *state_data,
1226                               const char *section_name,
1227                               uint8_t *event_reading_type_code_ptr)
1228 {
1229   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1230   ipmi_config_err_t ret;
1231   uint8_t event_reading_type_code;
1232   int event_reading_type_code_class;
1233 
1234   assert (state_data);
1235   assert (section_name);
1236   assert (event_reading_type_code_ptr);
1237 
1238   if ((ret = ipmi_config_sensors_seek_to_sdr_record (state_data,
1239                                                      section_name)) != IPMI_CONFIG_ERR_SUCCESS)
1240     {
1241       rv = ret;
1242       goto cleanup;
1243     }
1244 
1245   if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
1246                                               NULL,
1247                                               0,
1248                                               &event_reading_type_code) < 0)
1249     {
1250       pstdout_fprintf (state_data->pstate,
1251                        stderr,
1252                        "ipmi_sdr_parse_event_reading_type_code: %s\n",
1253                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1254       goto cleanup;
1255     }
1256 
1257   event_reading_type_code_class = ipmi_event_reading_type_code_class (event_reading_type_code);
1258 
1259   if (event_reading_type_code_class != IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE)
1260     {
1261       if (state_data->prog_data->args->common_args.debug)
1262         pstdout_fprintf (state_data->pstate,
1263                          stderr,
1264                          "Attempting to access generic event in non-generic sensor\n");
1265 
1266       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
1267       goto cleanup;
1268     }
1269 
1270   (*event_reading_type_code_ptr) = event_reading_type_code;
1271 
1272   rv = IPMI_CONFIG_ERR_SUCCESS;
1273  cleanup:
1274   return (rv);
1275 }
1276 
1277 static char **
_generic_event_enable_get_event_strings(ipmi_config_state_data_t * state_data,uint8_t event_reading_type_code)1278 _generic_event_enable_get_event_strings (ipmi_config_state_data_t *state_data,
1279                                          uint8_t event_reading_type_code)
1280 {
1281   assert (state_data);
1282 
1283   /* achu: I'm sorry.  But these fields have no description in the
1284    * IPMI spec, so there is no macro for them.  So I'm hard coding
1285    * hex in.  Please see see Table 42-2 in the IPMI spec.
1286    */
1287 
1288   switch (event_reading_type_code)
1289     {
1290     case 0x02:
1291       return (&generic_event_strings_0x02[0]);
1292     case 0x03:
1293       return (&generic_event_strings_0x03[0]);
1294     case 0x04:
1295       return (&generic_event_strings_0x04[0]);
1296     case 0x05:
1297       return (&generic_event_strings_0x05[0]);
1298     case 0x06:
1299       return (&generic_event_strings_0x06[0]);
1300     case 0x07:
1301       return (&generic_event_strings_0x07[0]);
1302     case 0x08:
1303       return (&generic_event_strings_0x08[0]);
1304     case 0x09:
1305       return (&generic_event_strings_0x09[0]);
1306     case 0x0A:
1307       return (&generic_event_strings_0x0A[0]);
1308     case 0x0B:
1309       return (&generic_event_strings_0x0B[0]);
1310     case 0x0C:
1311       return (&generic_event_strings_0x0C[0]);
1312     }
1313 
1314   return (NULL);
1315 }
1316 
1317 static ipmi_config_err_t
_generic_event_enable_get_data(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv,uint8_t event_reading_type_code,struct sensor_event_enable_data * data,uint16_t * bits,uint8_t * bitposition)1318 _generic_event_enable_get_data (ipmi_config_state_data_t *state_data,
1319                                 const char *section_name,
1320                                 const struct ipmi_config_keyvalue *kv,
1321                                 uint8_t event_reading_type_code,
1322                                 struct sensor_event_enable_data *data,
1323                                 uint16_t *bits,
1324                                 uint8_t *bitposition)
1325 {
1326   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1327   ipmi_config_err_t ret;
1328   char **event_strings = NULL;
1329   int found = 0;
1330   int i;
1331 
1332   assert (state_data);
1333   assert (section_name);
1334   assert (kv);
1335   assert (data);
1336   assert (bits);
1337   assert (bitposition);
1338 
1339   if ((ret = _get_sensor_event_enable (state_data,
1340                                        section_name,
1341                                        data)) != IPMI_CONFIG_ERR_SUCCESS)
1342     {
1343       rv = ret;
1344       goto cleanup;
1345     }
1346 
1347   if (stristr (kv->key->key_name, "Deassertion"))
1348     (*bits) = data->deassertion_bits;
1349   else
1350     (*bits) = data->assertion_bits;
1351 
1352   event_strings = _generic_event_enable_get_event_strings (state_data,
1353                                                            event_reading_type_code);
1354   if (!event_strings)
1355     {
1356       if (state_data->prog_data->args->verbose_count)
1357         pstdout_printf (state_data->pstate,
1358                         "## Unable to handle event flags for event reading type code 0x%X\n",
1359                         event_reading_type_code);
1360       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
1361       goto cleanup;
1362     }
1363 
1364   i = 0;
1365   while (event_strings[i])
1366     {
1367       if (stristr (kv->key->key_name, event_strings[i]))
1368         {
1369           (*bitposition) = i;
1370           found++;
1371           break;
1372         }
1373       i++;
1374     }
1375 
1376   if (!found)
1377     {
1378       if (state_data->prog_data->args->verbose_count)
1379         pstdout_printf (state_data->pstate,
1380                         "## Unrecognized section:key_name: %s:%s\n",
1381                         section_name,
1382                         kv->key->key_name);
1383       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
1384       goto cleanup;
1385     }
1386 
1387   rv = IPMI_CONFIG_ERR_SUCCESS;
1388  cleanup:
1389   return (rv);
1390 }
1391 
1392 ipmi_config_err_t
generic_event_enable_checkout(ipmi_config_state_data_t * state_data,const char * section_name,struct ipmi_config_keyvalue * kv)1393 generic_event_enable_checkout (ipmi_config_state_data_t *state_data,
1394                                const char *section_name,
1395                                struct ipmi_config_keyvalue *kv)
1396 {
1397   struct sensor_event_enable_data data;
1398   uint16_t bits = 0;
1399   uint8_t bitposition = 0;
1400   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1401   ipmi_config_err_t ret;
1402   uint8_t event_reading_type_code;
1403 
1404   assert (state_data);
1405   assert (section_name);
1406   assert (kv);
1407 
1408   if ((ret = _generic_event_enable_verify (state_data,
1409                                            section_name,
1410                                            &event_reading_type_code)) != IPMI_CONFIG_ERR_SUCCESS)
1411     {
1412       rv = ret;
1413       goto cleanup;
1414     }
1415 
1416   if ((ret = _generic_event_enable_get_data (state_data,
1417                                              section_name,
1418                                              kv,
1419                                              event_reading_type_code,
1420                                              &data,
1421                                              &bits,
1422                                              &bitposition)) != IPMI_CONFIG_ERR_SUCCESS)
1423     {
1424       rv = ret;
1425       goto cleanup;
1426     }
1427 
1428   if (ipmi_config_section_update_keyvalue_output (state_data,
1429                                                   kv,
1430                                                   ((bits >> bitposition) & 0x1) ? "Yes" : "No") < 0)
1431     goto cleanup;
1432 
1433   rv = IPMI_CONFIG_ERR_SUCCESS;
1434  cleanup:
1435   return (rv);
1436 }
1437 
1438 ipmi_config_err_t
generic_event_enable_commit(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv)1439 generic_event_enable_commit (ipmi_config_state_data_t *state_data,
1440                              const char *section_name,
1441                              const struct ipmi_config_keyvalue *kv)
1442 {
1443   struct sensor_event_enable_data data;
1444   uint16_t bits = 0;
1445   uint8_t bitposition = 0;
1446   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1447   ipmi_config_err_t ret;
1448   uint8_t event_reading_type_code;
1449   uint8_t event_message_action;
1450 
1451   assert (state_data);
1452   assert (section_name);
1453   assert (kv);
1454 
1455   if ((ret = _generic_event_enable_verify (state_data,
1456                                            section_name,
1457                                            &event_reading_type_code)) != IPMI_CONFIG_ERR_SUCCESS)
1458     {
1459       rv = ret;
1460       goto cleanup;
1461     }
1462 
1463   if ((ret = _generic_event_enable_get_data (state_data,
1464                                              section_name,
1465                                              kv,
1466                                              event_reading_type_code,
1467                                              &data,
1468                                              &bits,
1469                                              &bitposition)) != IPMI_CONFIG_ERR_SUCCESS)
1470     {
1471       rv = ret;
1472       goto cleanup;
1473     }
1474 
1475   /* due to set sensor event enable mechanics, we need to clear the bits */
1476   data.assertion_bits = 0;
1477   data.deassertion_bits = 0;
1478 
1479   if (stristr (kv->key->key_name, "Deassertion"))
1480     data.deassertion_bits = (0x1 << bitposition);
1481   else
1482     data.assertion_bits = (0x1 << bitposition);
1483 
1484   if (same (kv->value_input, "yes"))
1485     event_message_action = IPMI_SENSOR_EVENT_MESSAGE_ACTION_ENABLE_SELECTED_EVENT_MESSAGES;
1486   else
1487     event_message_action = IPMI_SENSOR_EVENT_MESSAGE_ACTION_DISABLE_SELECTED_EVENT_MESSAGES;
1488 
1489   if ((ret = _set_sensor_event_enable (state_data,
1490                                        section_name,
1491                                        &data,
1492                                        event_message_action)) != IPMI_CONFIG_ERR_SUCCESS)
1493     {
1494       rv = ret;
1495       goto cleanup;
1496     }
1497 
1498   rv = IPMI_CONFIG_ERR_SUCCESS;
1499  cleanup:
1500   return (rv);
1501 }
1502 
1503 static int
_setup_generic_event_enable_wrapper(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section,const char * type_str,Sdr_event_flags_func sdr_call,uint8_t event_reading_type_code)1504 _setup_generic_event_enable_wrapper (ipmi_config_state_data_t *state_data,
1505                                      struct ipmi_config_section *section,
1506                                      const char *type_str,
1507                                      Sdr_event_flags_func sdr_call,
1508                                      uint8_t event_reading_type_code)
1509 {
1510   char key_name[KEY_NAME_MAX_LEN];
1511   char **event_strings = NULL;
1512   uint16_t bitmask = 0;
1513   int rv = -1;
1514   int i;
1515 
1516   assert (state_data);
1517   assert (section);
1518   assert (type_str);
1519   assert (sdr_call);
1520 
1521   if (_get_event_state_bitmask (state_data,
1522                                 sdr_call,
1523                                 &bitmask) < 0)
1524     goto cleanup;
1525 
1526   event_strings = _generic_event_enable_get_event_strings (state_data,
1527                                                            event_reading_type_code);
1528   if (!event_strings)
1529     {
1530       if (state_data->prog_data->args->verbose_count)
1531         pstdout_printf (state_data->pstate,
1532                         "## Unable to handle event flags for event reading type code 0x%X\n",
1533                         event_reading_type_code);
1534       rv = 0;
1535       goto cleanup;
1536     }
1537 
1538   i = 0;
1539   while (event_strings[i])
1540     {
1541       snprintf (key_name,
1542                 KEY_NAME_MAX_LEN,
1543                 "Enable_%s_Event_%s",
1544                 type_str,
1545                 event_strings[i]);
1546 
1547       if (_setup_event_enable_key (state_data,
1548                                    section,
1549                                    key_name,
1550                                    ((bitmask >> i) & 0x1),
1551                                    generic_event_enable_checkout,
1552                                    generic_event_enable_commit) < 0)
1553         goto cleanup;
1554 
1555       i++;
1556     }
1557 
1558   rv = 0;
1559  cleanup:
1560   return (rv);
1561 }
1562 
1563 int
_setup_generic_event_enable(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section,uint8_t event_reading_type_code)1564 _setup_generic_event_enable (ipmi_config_state_data_t *state_data,
1565                              struct ipmi_config_section *section,
1566                              uint8_t event_reading_type_code)
1567 {
1568   int rv = -1;
1569 
1570   assert (state_data);
1571   assert (section);
1572 
1573   if (_setup_generic_event_enable_wrapper (state_data,
1574                                            section,
1575                                            "Assertion",
1576                                            &ipmi_sdr_parse_assertion_supported,
1577                                            event_reading_type_code) < 0)
1578     goto cleanup;
1579 
1580   if (_setup_generic_event_enable_wrapper (state_data,
1581                                            section,
1582                                            "Deassertion",
1583                                            &ipmi_sdr_parse_deassertion_supported,
1584                                            event_reading_type_code) < 0)
1585     goto cleanup;
1586 
1587   rv = 0;
1588  cleanup:
1589   return (rv);
1590 }
1591 
1592 static ipmi_config_err_t
_sensor_specific_event_enable_verify(ipmi_config_state_data_t * state_data,const char * section_name,uint8_t * sensor_type_ptr)1593 _sensor_specific_event_enable_verify (ipmi_config_state_data_t *state_data,
1594                                       const char *section_name,
1595                                       uint8_t *sensor_type_ptr)
1596 {
1597   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1598   ipmi_config_err_t ret;
1599   uint8_t event_reading_type_code;
1600   uint8_t sensor_type;
1601   int event_reading_type_code_class;
1602 
1603   assert (state_data);
1604   assert (section_name);
1605   assert (sensor_type_ptr);
1606 
1607   if ((ret = ipmi_config_sensors_seek_to_sdr_record (state_data,
1608                                                      section_name)) != IPMI_CONFIG_ERR_SUCCESS)
1609     {
1610       rv = ret;
1611       goto cleanup;
1612     }
1613 
1614   if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
1615                                               NULL,
1616                                               0,
1617                                               &event_reading_type_code) < 0)
1618     {
1619       pstdout_fprintf (state_data->pstate,
1620                        stderr,
1621                        "ipmi_sdr_parse_event_reading_type_code: %s\n",
1622                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1623       goto cleanup;
1624     }
1625 
1626   event_reading_type_code_class = ipmi_event_reading_type_code_class (event_reading_type_code);
1627 
1628   if (event_reading_type_code_class != IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE)
1629     {
1630       if (state_data->prog_data->args->common_args.debug)
1631         pstdout_fprintf (state_data->pstate,
1632                          stderr,
1633                          "Attempting to access sensor-specific event in non-sensor-specific sensor\n");
1634 
1635       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
1636       goto cleanup;
1637     }
1638 
1639   if (ipmi_sdr_parse_sensor_type (state_data->sdr_ctx,
1640                                   NULL,
1641                                   0,
1642                                   &sensor_type) < 0)
1643     {
1644       pstdout_fprintf (state_data->pstate,
1645                        stderr,
1646                        "ipmi_sdr_parse_sensor_type: %s\n",
1647                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1648       goto cleanup;
1649     }
1650 
1651   (*sensor_type_ptr) = sensor_type;
1652 
1653   rv = IPMI_CONFIG_ERR_SUCCESS;
1654  cleanup:
1655   return (rv);
1656 }
1657 
1658 static char **
_sensor_specific_event_enable_get_event_strings(ipmi_config_state_data_t * state_data,uint8_t sensor_type)1659 _sensor_specific_event_enable_get_event_strings (ipmi_config_state_data_t *state_data,
1660                                                  uint8_t sensor_type)
1661 {
1662   assert (state_data);
1663 
1664   switch (sensor_type)
1665     {
1666     case IPMI_SENSOR_TYPE_PHYSICAL_SECURITY:
1667       return (&sensor_specific_event_strings_physical_security_chassis_intrusion[0]);
1668     case IPMI_SENSOR_TYPE_PLATFORM_SECURITY_VIOLATION_ATTEMPT:
1669       return (&sensor_specific_event_strings_platform_security_violation_attempt[0]);
1670     case IPMI_SENSOR_TYPE_PROCESSOR:
1671       return (&sensor_specific_event_strings_processor[0]);
1672     case IPMI_SENSOR_TYPE_POWER_SUPPLY:
1673       return (&sensor_specific_event_strings_power_supply[0]);
1674     case IPMI_SENSOR_TYPE_POWER_UNIT:
1675       return (&sensor_specific_event_strings_power_unit[0]);
1676     case IPMI_SENSOR_TYPE_MEMORY:
1677       return (&sensor_specific_event_strings_memory[0]);
1678     case IPMI_SENSOR_TYPE_DRIVE_SLOT:
1679       return (&sensor_specific_event_strings_drive_slot[0]);
1680     case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS:
1681       return (&sensor_specific_event_strings_system_firmware_progress[0]);
1682     case IPMI_SENSOR_TYPE_EVENT_LOGGING_DISABLED:
1683       return (&sensor_specific_event_strings_event_logging_disabled[0]);
1684     case IPMI_SENSOR_TYPE_SYSTEM_EVENT:
1685       return (&sensor_specific_event_strings_system_event[0]);
1686     case IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT:
1687       return (&sensor_specific_event_strings_critical_interrupt[0]);
1688     case IPMI_SENSOR_TYPE_CABLE_INTERCONNECT:
1689       return (&sensor_specific_event_strings_cable_interconnect[0]);
1690     case IPMI_SENSOR_TYPE_BOOT_ERROR:
1691       return (&sensor_specific_event_strings_boot_error[0]);
1692     case IPMI_SENSOR_TYPE_SLOT_CONNECTOR:
1693       return (&sensor_specific_event_strings_slot_connector[0]);
1694     case IPMI_SENSOR_TYPE_WATCHDOG2:
1695       return (&sensor_specific_event_strings_watchdog2[0]);
1696     case IPMI_SENSOR_TYPE_ENTITY_PRESENCE:
1697       return (&sensor_specific_event_strings_entity_presence[0]);
1698     case IPMI_SENSOR_TYPE_MANAGEMENT_SUBSYSTEM_HEALTH:
1699       return (&sensor_specific_event_strings_management_subsystem_health[0]);
1700     case IPMI_SENSOR_TYPE_BATTERY:
1701       return (&sensor_specific_event_strings_battery[0]);
1702     case IPMI_SENSOR_TYPE_FRU_STATE:
1703       return (&sensor_specific_event_strings_fru_state[0]);
1704     }
1705 
1706   return (NULL);
1707 }
1708 
1709 static ipmi_config_err_t
_sensor_specific_event_enable_get_data(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv,uint8_t sensor_type,struct sensor_event_enable_data * data,uint16_t * bits,uint8_t * bitposition)1710 _sensor_specific_event_enable_get_data (ipmi_config_state_data_t *state_data,
1711                                         const char *section_name,
1712                                         const struct ipmi_config_keyvalue *kv,
1713                                         uint8_t sensor_type,
1714                                         struct sensor_event_enable_data *data,
1715                                         uint16_t *bits,
1716                                         uint8_t *bitposition)
1717 {
1718   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1719   ipmi_config_err_t ret;
1720   char **event_strings = NULL;
1721   int found = 0;
1722   int i;
1723 
1724   assert (state_data);
1725   assert (section_name);
1726   assert (kv);
1727   assert (data);
1728   assert (bits);
1729   assert (bitposition);
1730 
1731   if ((ret = _get_sensor_event_enable (state_data,
1732                                        section_name,
1733                                        data)) != IPMI_CONFIG_ERR_SUCCESS)
1734     {
1735       rv = ret;
1736       goto cleanup;
1737     }
1738 
1739   if (stristr (kv->key->key_name, "Deassertion"))
1740     (*bits) = data->deassertion_bits;
1741   else
1742     (*bits) = data->assertion_bits;
1743 
1744   event_strings = _sensor_specific_event_enable_get_event_strings (state_data,
1745                                                                    sensor_type);
1746   if (!event_strings)
1747     {
1748       if (state_data->prog_data->args->verbose_count)
1749         pstdout_printf (state_data->pstate,
1750                         "## Unable to handle event flags for sensor type 0x%X\n",
1751                         sensor_type);
1752       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
1753       goto cleanup;
1754     }
1755 
1756   i = 0;
1757 
1758   /* special case - event state 4-7 are "reserved" and useless */
1759   if (sensor_type == IPMI_SENSOR_TYPE_WATCHDOG2)
1760     {
1761       while (sensor_specific_event_strings_watchdog2_indexes[i] >= 0)
1762         {
1763           if (stristr (kv->key->key_name,
1764                        event_strings[sensor_specific_event_strings_watchdog2_indexes[i]]))
1765             {
1766               (*bitposition) = sensor_specific_event_strings_watchdog2_indexes[i];
1767               found++;
1768               break;
1769             }
1770           i++;
1771         }
1772     }
1773   else
1774     {
1775       while (event_strings[i])
1776         {
1777           if (stristr (kv->key->key_name, event_strings[i]))
1778             {
1779               (*bitposition) = i;
1780               found++;
1781               break;
1782             }
1783           i++;
1784         }
1785     }
1786 
1787   if (!found)
1788     {
1789       if (state_data->prog_data->args->verbose_count)
1790         pstdout_printf (state_data->pstate,
1791                         "## Unrecognized section:key_name: %s:%s\n",
1792                         section_name,
1793                         kv->key->key_name);
1794       rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
1795       goto cleanup;
1796     }
1797 
1798   rv = IPMI_CONFIG_ERR_SUCCESS;
1799  cleanup:
1800   return (rv);
1801 }
1802 
1803 ipmi_config_err_t
sensor_specific_event_enable_checkout(ipmi_config_state_data_t * state_data,const char * section_name,struct ipmi_config_keyvalue * kv)1804 sensor_specific_event_enable_checkout (ipmi_config_state_data_t *state_data,
1805                                        const char *section_name,
1806                                        struct ipmi_config_keyvalue *kv)
1807 {
1808   struct sensor_event_enable_data data;
1809   uint16_t bits = 0;
1810   uint8_t bitposition = 0;
1811   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1812   ipmi_config_err_t ret;
1813   uint8_t sensor_type;
1814 
1815   assert (state_data);
1816   assert (section_name);
1817   assert (kv);
1818 
1819   if ((ret = _sensor_specific_event_enable_verify (state_data,
1820                                                    section_name,
1821                                                    &sensor_type)) != IPMI_CONFIG_ERR_SUCCESS)
1822     {
1823       rv = ret;
1824       goto cleanup;
1825     }
1826 
1827   if ((ret = _sensor_specific_event_enable_get_data (state_data,
1828                                                      section_name,
1829                                                      kv,
1830                                                      sensor_type,
1831                                                      &data,
1832                                                      &bits,
1833                                                      &bitposition)) != IPMI_CONFIG_ERR_SUCCESS)
1834     {
1835       rv = ret;
1836       goto cleanup;
1837     }
1838 
1839   if (ipmi_config_section_update_keyvalue_output (state_data,
1840                                                   kv,
1841                                                   ((bits >> bitposition) & 0x1) ? "Yes" : "No") < 0)
1842     goto cleanup;
1843 
1844   rv = IPMI_CONFIG_ERR_SUCCESS;
1845  cleanup:
1846   return (rv);
1847 }
1848 
1849 ipmi_config_err_t
sensor_specific_event_enable_commit(ipmi_config_state_data_t * state_data,const char * section_name,const struct ipmi_config_keyvalue * kv)1850 sensor_specific_event_enable_commit (ipmi_config_state_data_t *state_data,
1851                                      const char *section_name,
1852                                      const struct ipmi_config_keyvalue *kv)
1853 {
1854   struct sensor_event_enable_data data;
1855   uint16_t bits = 0;
1856   uint8_t bitposition = 0;
1857   ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
1858   ipmi_config_err_t ret;
1859   uint8_t sensor_type;
1860   uint8_t event_message_action;
1861 
1862   assert (state_data);
1863   assert (section_name);
1864   assert (kv);
1865 
1866   if ((ret = _sensor_specific_event_enable_verify (state_data,
1867                                                    section_name,
1868                                                    &sensor_type)) != IPMI_CONFIG_ERR_SUCCESS)
1869     {
1870       rv = ret;
1871       goto cleanup;
1872     }
1873 
1874   if ((ret = _sensor_specific_event_enable_get_data (state_data,
1875                                                      section_name,
1876                                                      kv,
1877                                                      sensor_type,
1878                                                      &data,
1879                                                      &bits,
1880                                                      &bitposition)) != IPMI_CONFIG_ERR_SUCCESS)
1881     {
1882       rv = ret;
1883       goto cleanup;
1884     }
1885 
1886   /* due to set sensor event enable mechanics, we need to clear the bits */
1887   data.assertion_bits = 0;
1888   data.deassertion_bits = 0;
1889 
1890   if (stristr (kv->key->key_name, "Deassertion"))
1891     data.deassertion_bits = (0x1 << bitposition);
1892   else
1893     data.assertion_bits = (0x1 << bitposition);
1894 
1895   if (same (kv->value_input, "yes"))
1896     event_message_action = IPMI_SENSOR_EVENT_MESSAGE_ACTION_ENABLE_SELECTED_EVENT_MESSAGES;
1897   else
1898     event_message_action = IPMI_SENSOR_EVENT_MESSAGE_ACTION_DISABLE_SELECTED_EVENT_MESSAGES;
1899 
1900   if ((ret = _set_sensor_event_enable (state_data,
1901                                        section_name,
1902                                        &data,
1903                                        event_message_action)) != IPMI_CONFIG_ERR_SUCCESS)
1904     {
1905       rv = ret;
1906       goto cleanup;
1907     }
1908 
1909   rv = IPMI_CONFIG_ERR_SUCCESS;
1910  cleanup:
1911   return (rv);
1912 }
1913 
1914 static int
_setup_sensor_specific_event_enable_wrapper(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section,const char * type_str,Sdr_event_flags_func sdr_call)1915 _setup_sensor_specific_event_enable_wrapper (ipmi_config_state_data_t *state_data,
1916                                              struct ipmi_config_section *section,
1917                                              const char *type_str,
1918                                              Sdr_event_flags_func sdr_call)
1919 {
1920   char key_name[KEY_NAME_MAX_LEN];
1921   char **event_strings = NULL;
1922   uint16_t bitmask = 0;
1923   uint8_t sensor_type;
1924   int rv = -1;
1925   int i;
1926 
1927   assert (state_data);
1928   assert (section);
1929   assert (type_str);
1930   assert (sdr_call);
1931 
1932   if (_get_event_state_bitmask (state_data,
1933                                 sdr_call,
1934                                 &bitmask) < 0)
1935     goto cleanup;
1936 
1937   if (ipmi_sdr_parse_sensor_type (state_data->sdr_ctx,
1938                                   NULL,
1939                                   0,
1940                                   &sensor_type) < 0)
1941     {
1942       pstdout_fprintf (state_data->pstate,
1943                        stderr,
1944                        "ipmi_sdr_parse_sensor_type: %s\n",
1945                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1946       goto cleanup;
1947     }
1948 
1949   event_strings = _sensor_specific_event_enable_get_event_strings (state_data,
1950                                                                    sensor_type);
1951   if (!event_strings)
1952     {
1953       if (state_data->prog_data->args->verbose_count)
1954         pstdout_printf (state_data->pstate,
1955                         "## Unable to handle event flags for sensor type 0x%X\n",
1956                         sensor_type);
1957       rv = 0;
1958       goto cleanup;
1959     }
1960 
1961   i = 0;
1962 
1963   /* special case - event state 4-7 are "reserved" and useless */
1964   if (sensor_type == IPMI_SENSOR_TYPE_WATCHDOG2)
1965     {
1966       while (sensor_specific_event_strings_watchdog2_indexes[i] >= 0)
1967         {
1968           snprintf (key_name,
1969                     KEY_NAME_MAX_LEN,
1970                     "Enable_%s_Event_%s",
1971                     type_str,
1972                     event_strings[sensor_specific_event_strings_watchdog2_indexes[i]]);
1973 
1974           if (_setup_event_enable_key (state_data,
1975                                        section,
1976                                        key_name,
1977                                        ((bitmask >> sensor_specific_event_strings_watchdog2_indexes[i]) & 0x1),
1978                                        sensor_specific_event_enable_checkout,
1979                                        sensor_specific_event_enable_commit) < 0)
1980             goto cleanup;
1981 
1982           i++;
1983         }
1984     }
1985   else
1986     {
1987       i = 0;
1988       while (event_strings[i])
1989         {
1990           snprintf (key_name,
1991                     KEY_NAME_MAX_LEN,
1992                     "Enable_%s_Event_%s",
1993                     type_str,
1994                     event_strings[i]);
1995 
1996           if (_setup_event_enable_key (state_data,
1997                                        section,
1998                                        key_name,
1999                                        ((bitmask >> i) & 0x1),
2000                                        sensor_specific_event_enable_checkout,
2001                                        sensor_specific_event_enable_commit) < 0)
2002             goto cleanup;
2003 
2004           i++;
2005         }
2006     }
2007 
2008   rv = 0;
2009  cleanup:
2010   return (rv);
2011 }
2012 
2013 int
_setup_sensor_specific_event_enable(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section,uint8_t event_reading_type_code)2014 _setup_sensor_specific_event_enable (ipmi_config_state_data_t *state_data,
2015                                      struct ipmi_config_section *section,
2016                                      uint8_t event_reading_type_code)
2017 {
2018   int rv = -1;
2019 
2020   assert (state_data);
2021   assert (section);
2022 
2023   if (_setup_sensor_specific_event_enable_wrapper (state_data,
2024                                                    section,
2025                                                    "Assertion",
2026                                                    &ipmi_sdr_parse_assertion_supported) < 0)
2027     goto cleanup;
2028 
2029   if (_setup_sensor_specific_event_enable_wrapper (state_data,
2030                                                    section,
2031                                                    "Deassertion",
2032                                                    &ipmi_sdr_parse_deassertion_supported) < 0)
2033     goto cleanup;
2034 
2035   rv = 0;
2036  cleanup:
2037   return (rv);
2038 }
2039 
2040 int
setup_sensor_event_enable_fields(ipmi_config_state_data_t * state_data,struct ipmi_config_section * section)2041 setup_sensor_event_enable_fields (ipmi_config_state_data_t *state_data,
2042                                   struct ipmi_config_section *section)
2043 {
2044   uint8_t event_message_control_support = 0;
2045   int rv = -1;
2046 
2047   assert (state_data);
2048   assert (section);
2049 
2050   if (ipmi_sdr_parse_sensor_capabilities (state_data->sdr_ctx,
2051                                           NULL,
2052                                           0,
2053                                           &event_message_control_support,
2054                                           NULL,
2055                                           NULL,
2056                                           NULL,
2057                                           NULL) < 0)
2058     {
2059       pstdout_fprintf (state_data->pstate,
2060                        stderr,
2061                        "ipmi_sdr_parse_sensor_capabilities: %s\n",
2062                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
2063       goto cleanup;
2064     }
2065 
2066   /* achu: I'm not quite sure what IPMI_SDR_GLOBAL_DISABLE_ONLY means.
2067    * Does it mean all sensors on the motherboard can be disabled
2068    * together? But one alone cannot?  I'm going to assume that's what
2069    * it means. I'll have to come back to this if that's not the case.
2070    */
2071   if (event_message_control_support == IPMI_SDR_PER_EVENT_ENABLE_DISABLE_SUPPORT
2072       || event_message_control_support == IPMI_SDR_ENTIRE_SENSOR_ONLY)
2073     {
2074       if (ipmi_config_section_add_key (state_data,
2075                                        section,
2076                                        "Enable_All_Event_Messages",
2077                                        "Possible values: Yes/No",
2078                                        0,
2079                                        sensor_event_enable_enable_all_event_messages_checkout,
2080                                        sensor_event_enable_enable_all_event_messages_commit,
2081                                        yes_no_validate) < 0)
2082         goto cleanup;
2083 
2084       if (ipmi_config_section_add_key (state_data,
2085                                        section,
2086                                        "Enable_Scanning_On_This_Sensor",
2087                                        "Possible values: Yes/No",
2088                                        0,
2089                                        sensor_event_enable_enable_scanning_on_this_sensor_checkout,
2090                                        sensor_event_enable_enable_scanning_on_this_sensor_commit,
2091                                        yes_no_validate) < 0)
2092         goto cleanup;
2093     }
2094 
2095   if (event_message_control_support == IPMI_SDR_PER_EVENT_ENABLE_DISABLE_SUPPORT)
2096     {
2097       uint8_t event_reading_type_code;
2098       int event_reading_type_code_class;
2099 
2100       if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
2101                                                   NULL,
2102                                                   0,
2103                                                   &event_reading_type_code) < 0)
2104         {
2105           pstdout_fprintf (state_data->pstate,
2106                            stderr,
2107                            "ipmi_sdr_parse_event_reading_type_code: %s\n",
2108                            ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
2109           goto cleanup;
2110         }
2111 
2112       event_reading_type_code_class = ipmi_event_reading_type_code_class (event_reading_type_code);
2113 
2114       if (event_reading_type_code_class == IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD)
2115         {
2116           if (_setup_threshold_event_enable (state_data,
2117                                              section) < 0)
2118             goto cleanup;
2119         }
2120       else if (event_reading_type_code_class == IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE)
2121         {
2122           if (_setup_generic_event_enable (state_data,
2123                                            section,
2124                                            event_reading_type_code) < 0)
2125             goto cleanup;
2126         }
2127       else if (event_reading_type_code_class == IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE)
2128         {
2129           if (_setup_sensor_specific_event_enable (state_data,
2130                                                    section,
2131                                                    event_reading_type_code) < 0)
2132             goto cleanup;
2133         }
2134     }
2135 
2136   rv = 0;
2137  cleanup:
2138   return (rv);
2139 }
2140