Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter

- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,295 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#ifndef SCOPED_LOCK_TIMEOUT
#define SCOPED_LOCK_TIMEOUT
#include "everest/exceptions.hpp"
#include "everest/logging.hpp"
#include <mutex>
#include <signal.h>
#include "backtrace.hpp"
/*
Simple helper class for scoped lock with timeout
*/
namespace Everest {
enum class MutexDescription {
Undefined,
Charger_signal_loop,
Charger_signal_error,
Charger_signal_error_cleared,
Charger_mainloop,
Charger_process_event,
Charger_waiting_for_power,
Charger_cancel_transaction,
Charger_setup,
Charger_get_current_state,
Charger_get_authorized_pnc,
Charger_get_authorized_eim,
Charger_get_authorized_pnc_ready_for_hlc,
Charger_get_authorized_eim_ready_for_hlc,
Charger_authorize,
Charger_deauthorize,
Charger_disable,
Charger_enable,
Charger_set_faulted,
Charger_get_max_current,
Charger_set_current_drawn_by_vehicle,
Charger_request_error_sequence,
Charger_set_matching_started,
Charger_notify_currentdemand_started,
Charger_inform_new_evse_max_hlc_limits,
Charger_get_evse_max_hlc_limits,
Charger_inform_new_evse_min_hlc_limits,
Charger_get_evse_min_hlc_limits,
Charger_dlink_pause,
Charger_dlink_terminate,
Charger_dlink_error,
Charger_set_hlc_charging_active,
Charger_set_hlc_allow_close_contactor,
Charger_errors_prevent_charging,
Charger_set_max_current,
Charger_switch_three_phases_while_charging,
Charger_get_last_stop_transaction,
Charger_set_hlc_d20_active,
IEC_process_bsp_event,
IEC_state_machine,
IEC_set_pwm,
IEC_set_cp_state_X1,
IEC_set_cp_state_F,
IEC_allow_power_on,
IEC_force_unlock,
EVSE_charger_ready,
EVSE_set_ev_info,
EVSE_publish_ev_info,
EVSE_subscribe_dc_ev_maximum_limits,
EVSE_subscribe_departure_time,
EVSE_subscribe_ac_eamount,
EVSE_subscribe_ac_ev_max_voltage,
EVSE_subscribe_ac_ev_max_current,
EVSE_subscribe_ac_ev_min_current,
EVSE_subscribe_ac_ev_power_limits,
EVSE_subscribe_ac_ev_present_powers,
EVSE_subscribe_ac_ev_dynamic_control_mode,
EVSE_subscribe_dc_ev_energy_capacity,
EVSE_subscribe_dc_ev_energy_request,
EVSE_subscribe_dc_full_soc,
EVSE_subscribe_dc_bulk_soc,
EVSE_subscribe_dc_ev_remaining_time,
EVSE_subscribe_dc_ev_status,
EVSE_subscribe_evcc_id,
EVSE_subscribe_powermeter,
EVSE_get_latest_powermeter_data_billing,
EVSE_get_reservation_id,
EVSE_reserve,
EVSE_cancel_reservation,
EVSE_is_reserved,
EVSE_get_ev_info
};
static std::string to_string(MutexDescription d) {
switch (d) {
case MutexDescription::Undefined:
return "Undefined";
case MutexDescription::Charger_signal_loop:
return "Charger.cpp: error_handling->signal_loop";
case MutexDescription::Charger_signal_error:
return "Charger.cpp: error_handling->signal_error";
case MutexDescription::Charger_signal_error_cleared:
return "Charger.cpp: error_handling->signal_all_errors_cleared";
case MutexDescription::Charger_mainloop:
return "Charger.cpp: mainloop";
case MutexDescription::Charger_process_event:
return "Charger.cpp: process_event";
case MutexDescription::Charger_waiting_for_power:
return "Charger.cpp: pause_charging_wait_for_power";
case MutexDescription::Charger_cancel_transaction:
return "Charger.cpp: cancel_transaction";
case MutexDescription::Charger_setup:
return "Charger.cpp: setup";
case MutexDescription::Charger_get_current_state:
return "Charger.cpp: get_current_state";
case MutexDescription::Charger_get_authorized_pnc:
return "Charger.cpp: get_authorized_pnc";
case MutexDescription::Charger_get_authorized_eim:
return "Charger.cpp: get_authorized_eim";
case MutexDescription::Charger_get_authorized_pnc_ready_for_hlc:
return "Charger.cpp: get_authorized_pnc_ready_for_hlc";
case MutexDescription::Charger_get_authorized_eim_ready_for_hlc:
return "Charger.cpp: get_authorized_eim_ready_for_hlc";
case MutexDescription::Charger_authorize:
return "Charger.cpp: authorize";
case MutexDescription::Charger_deauthorize:
return "Charger.cpp: deauthorize";
case MutexDescription::Charger_disable:
return "Charger.cpp: disable";
case MutexDescription::Charger_enable:
return "Charger.cpp: enable";
case MutexDescription::Charger_set_faulted:
return "Charger.cpp: set_faulted";
case MutexDescription::Charger_get_max_current:
return "Charger.cpp: get_max_current";
case MutexDescription::Charger_set_current_drawn_by_vehicle:
return "Charger.cpp: set_current_drawn_by_vehicle";
case MutexDescription::Charger_request_error_sequence:
return "Charger.cpp: request_error_sequence";
case MutexDescription::Charger_set_matching_started:
return "Charger.cpp: set_matching_started";
case MutexDescription::Charger_notify_currentdemand_started:
return "Charger.cpp: notify_currentdemand_started";
case MutexDescription::Charger_inform_new_evse_max_hlc_limits:
return "Charger.cpp: inform_new_evse_max_hlc_limits";
case MutexDescription::Charger_get_evse_max_hlc_limits:
return "Charger.cpp: get_evse_max_hlc_limits";
case MutexDescription::Charger_inform_new_evse_min_hlc_limits:
return "Charger.cpp: inform_new_evse_min_hlc_limits";
case MutexDescription::Charger_get_evse_min_hlc_limits:
return "Charger.cpp: get_evse_min_hlc_limits";
case MutexDescription::Charger_dlink_pause:
return "Charger.cpp: dlink_pause";
case MutexDescription::Charger_dlink_terminate:
return "Charger.cpp: dlink_dlink_terminate";
case MutexDescription::Charger_dlink_error:
return "Charger.cpp: dlink_error";
case MutexDescription::Charger_set_hlc_charging_active:
return "Charger.cpp: set_hlc_charging_active";
case MutexDescription::Charger_set_hlc_allow_close_contactor:
return "Charger.cpp: set_hlc_allow_close_contactor";
case MutexDescription::Charger_errors_prevent_charging:
return "Charger.cpp: errors_prevent_charging";
case MutexDescription::Charger_set_max_current:
return "Charger.cpp: set max current";
case MutexDescription::Charger_switch_three_phases_while_charging:
return "Charger.cpp switch_three_phases_while_charging";
case MutexDescription::Charger_get_last_stop_transaction:
return "Charger.cpp get_last_stop_transaction";
case MutexDescription::Charger_set_hlc_d20_active:
return "Charger.cpp set_hlc_d20_active";
case MutexDescription::IEC_process_bsp_event:
return "IECStateMachine::process_bsp_event";
case MutexDescription::IEC_state_machine:
return "IECStateMachine::state_machine";
case MutexDescription::IEC_set_pwm:
return "IECStateMachine::set_pwm";
case MutexDescription::IEC_set_cp_state_X1:
return "IECStateMachine::set_cp_state_X1";
case MutexDescription::IEC_set_cp_state_F:
return "IECStateMachine::set_cp_state_F";
case MutexDescription::IEC_allow_power_on:
return "IECStateMachine::allow_power_on";
case MutexDescription::IEC_force_unlock:
return "IECStateMachine::force_unlock";
case MutexDescription::EVSE_charger_ready:
return "EvseManager.cpp: charger_ready";
case MutexDescription::EVSE_set_ev_info:
return "EvseManager.cpp: set ev_info present_voltage/current";
case MutexDescription::EVSE_publish_ev_info:
return "EvseManager.cpp: publish_ev_info";
case MutexDescription::EVSE_subscribe_dc_ev_maximum_limits:
return "EvseManager.cpp: subscribe_dc_ev_maximum_limits";
case MutexDescription::EVSE_subscribe_departure_time:
return "EvseManager.cpp: subscribe_departure_time";
case MutexDescription::EVSE_subscribe_ac_eamount:
return "EvseManager.cpp: subscribe_ac_eamount";
case MutexDescription::EVSE_subscribe_ac_ev_max_voltage:
return "EvseManager.cpp: subscribe_ac_ev_max_voltage";
case MutexDescription::EVSE_subscribe_ac_ev_max_current:
return "EvseManager.cpp: subscribe_ac_ev_max_current";
case MutexDescription::EVSE_subscribe_ac_ev_min_current:
return "EvseManager.cpp: subscribe_ac_ev_min_current";
case MutexDescription::EVSE_subscribe_ac_ev_power_limits:
return "EvseManager.cpp: subscribe_ac_ev_power_limits";
case MutexDescription::EVSE_subscribe_ac_ev_present_powers:
return "EvseManager.cpp: subscribe_ac_ev_present_powers";
case MutexDescription::EVSE_subscribe_ac_ev_dynamic_control_mode:
return "EvseManager.cpp: subscribe_ac_ev_dynamic_control_mode";
case MutexDescription::EVSE_subscribe_dc_ev_energy_capacity:
return "EvseManager.cpp: subscribe_dc_ev_energy_capacity";
case MutexDescription::EVSE_subscribe_dc_ev_energy_request:
return "EvseManager.cpp: subscribe_dc_ev_energy_request";
case MutexDescription::EVSE_subscribe_dc_full_soc:
return "EvseManager.cpp: subscribe_dc_full_soc";
case MutexDescription::EVSE_subscribe_dc_bulk_soc:
return "EvseManager.cpp: subscribe_dc_bulk_soc";
case MutexDescription::EVSE_subscribe_dc_ev_remaining_time:
return "EvseManager.cpp: subscribe_dc_ev_remaining_time";
case MutexDescription::EVSE_subscribe_dc_ev_status:
return "EvseManager.cpp subscribe_dc_ev_status";
case MutexDescription::EVSE_subscribe_evcc_id:
return "EvseManager.cpp: subscribe_evcc_id";
case MutexDescription::EVSE_subscribe_powermeter:
return "EvseManager.cpp: subscribe_powermeter";
case MutexDescription::EVSE_get_latest_powermeter_data_billing:
return "EvseManager.cpp: get_latest_powermeter_data_billing";
case MutexDescription::EVSE_get_reservation_id:
return "EvseManager.cpp: get_reservation_id";
case MutexDescription::EVSE_reserve:
return "EvseManager.cpp: reserve";
case MutexDescription::EVSE_cancel_reservation:
return "EvseManager.cpp: cancel_reservation";
case MutexDescription::EVSE_is_reserved:
return "EvseManager.cpp: is_reserved";
case MutexDescription::EVSE_get_ev_info:
return "EvseManager.cpp: get_ev_info";
}
return "Undefined";
}
class timed_mutex_traceable : public std::timed_mutex {
#ifdef EVEREST_USE_BACKTRACES
public:
MutexDescription description;
pthread_t p_id;
#endif
};
template <typename mutex_type> class scoped_lock_timeout {
public:
explicit scoped_lock_timeout(mutex_type& __m, MutexDescription description) : mutex(__m) {
if (not mutex.try_lock_for(deadlock_timeout)) {
#ifdef EVEREST_USE_BACKTRACES
request_backtrace(pthread_self());
request_backtrace(mutex.p_id);
// Give some time for other timeouts to report their state and backtraces
std::this_thread::sleep_for(std::chrono::seconds(10));
std::string different_thread;
if (mutex.p_id not_eq pthread_self()) {
different_thread = " from a different thread.";
} else {
different_thread = " from the same thread";
}
EVLOG_AND_THROW(EverestTimeoutError("Mutex deadlock detected: Failed to lock " + to_string(description) +
", mutex held by " + to_string(mutex.description) + different_thread));
#endif
} else {
locked = true;
#ifdef EVEREST_USE_BACKTRACES
mutex.description = description;
mutex.p_id = pthread_self();
#endif
}
}
~scoped_lock_timeout() {
if (locked) {
mutex.unlock();
}
}
scoped_lock_timeout(const scoped_lock_timeout&) = delete;
scoped_lock_timeout& operator=(const scoped_lock_timeout&) = delete;
private:
bool locked{false};
mutex_type& mutex;
// This should be lower then command timeouts from framework (by default 300s)
static constexpr auto deadlock_timeout = std::chrono::seconds(120);
};
} // namespace Everest
#endif