C2A_Core
event_handler.c
[詳解]
1 #pragma section REPRO
7 #include "event_handler.h"
8 #include <string.h>
9 #include <stdlib.h>
10 #include "../../TlmCmd/common_cmd_packet_util.h"
11 #include "../../Applications/timeline_command_dispatcher_id_define.h"
12 #include "../TimeManager/time_manager.h"
13 
14 #ifdef EL_IS_ENABLE_TLOG
15 
21 typedef enum
22 {
32 
38 typedef enum
39 {
43 
49 typedef enum
50 {
58 
64 typedef enum
65 {
69 
70 
76 static void EH_clear_rules_(void);
77 
83 static void EH_clear_log_(void);
84 
92 
99 static const EL_Event* EH_get_event_to_check_rule_(void);
100 
107 static uint8_t EH_check_event_and_respond_(const EL_Event* event);
108 
119 static uint8_t EH_check_rule_and_respond_(EH_RULE_ID rule_id, const EL_Event* event);
120 
129 
137 static EH_CKECK_RULE_ACK EH_check_rule_(EH_RULE_ID rule_id, const EL_Event* event);
138 
147 static EH_CKECK_RULE_ACK EH_check_single_rule_(EH_RULE_ID rule_id, const EL_Event* event);
148 
157 static EH_CKECK_RULE_ACK EH_check_continuous_rule_(EH_RULE_ID rule_id, const EL_Event* event);
158 
167 static EH_CKECK_RULE_ACK EH_check_cumulative_rule_(EH_RULE_ID rule_id, const EL_Event* event);
168 
176 static void EH_respond_(EH_RULE_ID rule_id);
177 
185 static void EH_record_responded_log_(EH_RULE_ID rule_id, CCP_EXEC_STS deploy_cmd_ack);
186 
194 
207  uint32_t local,
209  uint16_t found_sorted_idxes[EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES],
210  uint8_t* found_id_num);
211 
221 static int EH_compare_sorted_index_for_bsearch_(const void* key, const void* elem);
222 
234  uint16_t* least_found_sorted_idx,
235  uint16_t* found_sorted_idx_num);
236 
247 static int EH_compare_sorted_index_by_event_group_for_bsearch_(const void* key, const void* elem);
248 
262 
271 
278 
285 static void EH_exec_func_by_event_group_(EL_GROUP group,
286  EH_CHECK_RULE_ACK (*func)(EH_RULE_ID));
287 
288 
291 
292 
293 void EH_initialize(void)
294 {
295  memset(&event_handler_, 0x00, sizeof(EventHandler));
296 
297  EH_clear_rules_();
298  EH_clear_log_();
299 
305 
307 }
308 
309 
310 static void EH_clear_rules_(void)
311 {
312  int i;
313  memset(&event_handler_.rule_table, 0x00, sizeof(EH_RuleTable));
314  // 現時点で EL_CORE_GROUP_NULL == 0 であるため,以下は不要.
315  // for (i = 0; i < (int)EH_RULE_MAX; ++i)
316  // {
317  // event_handler_.rule_table.rules[i].settings.event.group = (EL_GROUP)EL_CORE_GROUP_NULL;
318  // }
319 
320  // EH_RuleSortedIndex もクリア
322  for (i = 0; i < (int)EH_RULE_MAX; ++i)
323  {
324  // 現時点で EL_CORE_GROUP_NULL == 0 であるため,以下は不要.
325  // event_handler_.sorted_idxes[i].group = (EL_GROUP)EL_CORE_GROUP_NULL;
327  }
328 }
329 
330 
331 static void EH_clear_log_(void)
332 {
333  int i;
334  memset(&event_handler_.log_table, 0x00, sizeof(EH_LogTable));
335 
336  for (i = 0; i < EH_LOG_MAX; ++i)
337  {
339  }
340 }
341 
342 
343 void EH_execute(void)
344 {
345  uint8_t responded_count = 0;
346  EH_ACK ack;
347  uint16_t i;
348 
350  if (ack != EH_ACK_OK) return;
351 
352  for (i = 0; i < event_handler_.exec_settings.max_check_event_num; ++i)
353  {
354  const EL_Event* event = EH_get_event_to_check_rule_();
355  if (event == NULL)
356  {
357  // もうチェックすべきイベントはなし
358  break;
359  }
360 
362  responded_count += EH_check_event_and_respond_(event);
363  if (responded_count >= event_handler_.exec_settings.max_response_num) break;
364  }
365 }
366 
367 
369 {
371  int32_t delta_counters[EL_ERROR_LEVEL_MAX];
372  uint8_t err_level;
373  int32_t subtotal = 0;
374 
375  // カウンタ不整合を調べる.
376  // エラー等は定期的にリセットされているはずなので,オーバーフローは考慮していない
377  if (delta_counter < 0)
378  {
379  // 不整合
383  (uint32_t)(-delta_counter));
384  // 仕方がないので強制的に合わせる
386  return EH_ACK_ERR;
387  }
388 
389  for (err_level = 0; err_level < EL_ERROR_LEVEL_MAX; ++err_level)
390  {
391  delta_counters[err_level] = event_logger->statistics.record_counters[err_level] - event_handler_.el_event_counter.counters[err_level];
392  if (delta_counters[err_level] < 0)
393  {
394  // 不整合
398  (uint32_t)(err_level));
399  // 仕方がないので強制的に合わせる
401  return EH_ACK_ERR;
402  }
403 
404  subtotal += delta_counters[err_level];
405  }
406 
407  if (delta_counter != (int32_t)subtotal)
408  {
409  // 不整合
413  EL_ERROR_LEVEL_MAX); // ここの note は少し考える?
414  // 仕方がないので強制的に合わせる
416  return EH_ACK_ERR;
417  }
418 
419  return EH_ACK_OK;
420 }
421 
422 
424 {
426  if (event == NULL) return NULL;
427 
428  // 処理する EL_Event が見つかったので,カウントアップ
430  event_handler_.el_event_counter.counters[event->err_level]++;
431 
432  return event;
433 }
434 
435 static uint8_t EH_check_event_and_respond_(const EL_Event* event)
436 {
437  EH_RULE_SORTED_INDEX_ACK search_ack;
439  uint16_t found_sorted_idxes[EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES];
440  uint8_t found_id_num;
441  uint8_t i;
442  uint8_t responded_num = 0;
443 
444  search_ack = EH_search_rule_table_index_(event->group,
445  event->local,
446  found_ids,
447  found_sorted_idxes,
448  &found_id_num);
449 
450  if (search_ack == EH_RULE_SORTED_INDEX_ACK_NOT_FOUND)
451  {
452  // 対応する EH_Rule なし
453  return 0;
454  }
455  if (search_ack != EH_RULE_SORTED_INDEX_ACK_OK)
456  {
460  (uint32_t)search_ack);
461  return 0;
462  }
463 
464  // ルールチェック & 対応
465  for (i = 0; i < found_id_num; ++i)
466  {
467  responded_num += EH_check_rule_and_respond_(found_ids[i], event);
468  }
469 
470  return responded_num;
471 }
472 
473 
474 static uint8_t EH_check_rule_and_respond_(EH_RULE_ID rule_id, const EL_Event* event)
475 {
476  EH_RuleSettings* rule_settings = &event_handler_.rule_table.rules[rule_id].settings;
477  uint8_t responded_num = 0;
478 
479  if (rule_settings->event.group != event->group || rule_settings->event.local != event->local)
480  {
481  // 何かがおかしい(ありえないが,安全のため入れている.問題なさそうなら消してよし)
485  (uint32_t)rule_id);
486  return 0;
487  }
488 
489  if (EH_check_rule_(rule_id, event) != EH_CKECK_RULE_ACK_MATCH)
490  {
491  return 0;
492  }
493 
494  // ここまで来たら引数に取った EH_RULE_ID は EH_Rule にマッチした
496  (uint32_t)rule_id,
498  (uint32_t)event->err_level);
499 
500  // 上位の EH_Rule にマッチしないか問い合わせ
501  responded_num = EH_check_higher_level_rule_and_respond_(rule_id);
502 
503  if (responded_num > 0)
504  {
505  // 上位で対応された
507  (uint32_t)rule_id,
509  (uint32_t)responded_num);
510  return responded_num;
511  }
512 
513  // このルールで対応する
514  EH_respond_(rule_id);
515  return 1;
516 }
517 
518 
520 {
521  const EL_Event* higher_level_trigger_event = EL_get_the_nth_tlog_from_the_latest(EL_ERROR_LEVEL_EH, 0);
522  int32_t delta_counter = event_logger->statistics.record_counters[EL_ERROR_LEVEL_EH] -
524 
526 
528  {
529  // これ以上の再帰回数は認められない
533  0);
534  return 0;
535  }
536 
537  if (delta_counter < 1)
538  {
539  // 何かがおかしい(ありえないが,安全のため入れている.問題なさそうなら消してよし)
543  0);
544  return 0;
545  }
546  if (higher_level_trigger_event->group != (EL_GROUP)EL_CORE_GROUP_EH_MATCH_RULE || higher_level_trigger_event->local != rule_id)
547  {
548  // 何かがおかしい(ありえないが,安全のため入れている.問題なさそうなら消してよし)
552  0);
553  return 0;
554  }
555 
556  // EL_Event を処理したのでカウントアップ
559 
560  // 上位の EH_Rule があるか検索して対応(再帰)
561  return EH_check_event_and_respond_(higher_level_trigger_event);
562 }
563 
564 
566 {
567  EH_RuleSettings* rule_settings = &event_handler_.rule_table.rules[rule_id].settings;
568 
569  if (!(rule_settings->is_active))
570  {
572  }
573  if (rule_settings->should_match_err_level)
574  {
575  if (rule_settings->event.err_level != event->err_level)
576  {
578  }
579  }
580 
581  switch (rule_settings->condition.type)
582  {
584  return EH_check_single_rule_(rule_id, event);
586  return EH_check_continuous_rule_(rule_id, event);
588  return EH_check_cumulative_rule_(rule_id, event);
589  default:
590  // 何かがおかしい(ありえないが,安全のため入れている.問題なさそうなら消してよし)
594  (uint32_t)rule_id);
596  }
597 }
598 
599 
601 {
602  EH_Rule* rule = &event_handler_.rule_table.rules[rule_id];
603  rule->last_event_time = event->time;
605 }
606 
607 
609 {
610  EH_Rule* rule = &event_handler_.rule_table.rules[rule_id];
611  uint32_t delta_time_ms = OBCT_diff_in_msec(&rule->last_event_time, &event->time);
612  rule->last_event_time = event->time;
613 
614  if (delta_time_ms > rule->settings.condition.time_threshold_ms)
615  {
616  // 連続ではなくなった
617  EH_clear_rule_counter(rule_id);
618  }
619 
620  rule->counter++;
621 
622  if (rule->counter < rule->settings.condition.count_threshold)
623  {
625  }
626 
627  EH_clear_rule_counter(rule_id);
629 }
630 
631 
633 {
634  EH_Rule* rule = &event_handler_.rule_table.rules[rule_id];
635  rule->last_event_time = event->time;
636  rule->counter++;
637 
638  if (rule->counter < rule->settings.condition.count_threshold)
639  {
641  }
642 
643  EH_clear_rule_counter(rule_id);
645 }
646 
647 
648 static void EH_respond_(EH_RULE_ID rule_id)
649 {
650  EH_Rule* rule = &event_handler_.rule_table.rules[rule_id];
651  CCP_CmdRet cmd_ret;
652 
654  if (cmd_ret.exec_sts != CCP_EXEC_SUCCESS)
655  {
656  uint32_t note = ((0x0000ffff & cmd_ret.exec_sts) << 16) | (0x0000ffff & cmd_ret.err_code);
657  if ((PL_ACK)cmd_ret.err_code == PL_BC_TIME_ADJUSTED)
658  {
662  note);
663  }
664  else
665  {
669  note);
670  }
671  }
672 
674 
675  EH_record_responded_log_(rule_id, cmd_ret.exec_sts);
676 }
677 
678 
679 // FIXME: CCP_EXEC_STS -> CCP_CmdRet にしてもいいかも?
680 static void EH_record_responded_log_(EH_RULE_ID rule_id, CCP_EXEC_STS deploy_cmd_ack)
681 {
682  EH_LogTable* log_table = &event_handler_.log_table;
683 
684  log_table->respond_counter++;
685 
686  log_table->logs[log_table->log_wp].rule_id = rule_id;
688  log_table->logs[log_table->log_wp].deploy_cmd_ack = deploy_cmd_ack;
689 
690  log_table->log_wp++;
691  if (log_table->log_wp >= EH_LOG_MAX)
692  {
693  log_table->log_wp = 0;
697  0);
698  }
699 }
700 
701 
703 {
704  uint8_t err_level; // for で回すので u8 で
705  ObcTime oldest_time = OBCT_get_max();
706  const EL_Event* oldest_event = NULL;
707 
708  for (err_level = 0; err_level < EL_ERROR_LEVEL_MAX; ++err_level)
709  {
710  // EH 実行中にも EL のイベント登録は発生するため,ここで最新の情報を元に処理する
711  int32_t delta_counter = event_logger->statistics.record_counters[err_level] - event_handler_.el_event_counter.counters[err_level];
712  const uint16_t tlog_capacity = event_logger->tlogs[err_level].log_capacity;
713  const EL_Event* event;
714 
715  if (err_level == EL_ERROR_LEVEL_EH) continue;
716  if (delta_counter <= 0) continue;
717 
718  // キャパを溢れていたら,諦めて情報を修正する
719  if (delta_counter > tlog_capacity)
720  {
721  const uint16_t keep_tlogs_num = (uint16_t)(tlog_capacity / 2);
722  uint32_t drop_tlog_num;
723 
724  // イベントが発生しすぎて,TLogが失われている
728  (uint32_t)(err_level));
729 
730  // 溢れかえっているということなので,またすぐ溢れることを考慮し
731  // tlog_capacity の半分ぐらいまでのこし,後は諦める
732  drop_tlog_num = (uint32_t)(delta_counter - keep_tlogs_num);
733 
735  event_handler_.el_event_counter.counters[err_level] += drop_tlog_num;
736 
737  // カウンタを変えたので,更新
738  delta_counter = event_logger->statistics.record_counters[err_level] - event_handler_.el_event_counter.counters[err_level];
739  }
740 
741  event = EL_get_the_nth_tlog_from_the_latest((EL_ERROR_LEVEL)err_level, (uint16_t)(delta_counter - 1));
742  if (OBCT_compare(&event->time, &oldest_time) == 1)
743  {
744  oldest_event = event;
745  oldest_time = event->time;
746  }
747  }
748 
749  return oldest_event;
750 }
751 
752 
754  uint32_t local,
756  uint16_t found_sorted_idxes[EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES],
757  uint8_t* found_id_num)
758 {
759  // idx: 0 ~ rule_table.registered_rule_num の間で二分探索する
760  // 重複もあり得ることを考慮する (duplicate_id は異なる)
761 
762  uint16_t found_idx = EH_RULE_MAX;
763  const EH_RuleSortedIndex* p_searched_sorted_idx = NULL;
764  EH_RuleSortedIndex target_sorted_idx;
765  uint16_t i;
766  uint16_t possible_num_of_id_duplicates;
767 
769  {
771  }
772 
773  memset(&target_sorted_idx, 0x00, sizeof(EH_RuleSortedIndex));
774  target_sorted_idx.group = group;
775  target_sorted_idx.local = local;
776  p_searched_sorted_idx = (EH_RuleSortedIndex*)bsearch(&target_sorted_idx,
779  sizeof(EH_RuleSortedIndex),
781  if (p_searched_sorted_idx == NULL) return EH_RULE_SORTED_INDEX_ACK_NOT_FOUND;
782  found_idx = (uint16_t)(p_searched_sorted_idx - (&event_handler_.sorted_idxes[0]));
783 
784  // 見つかった.後は,いくつあるか?
785  *found_id_num = 0;
786  possible_num_of_id_duplicates = EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES;
787  if (possible_num_of_id_duplicates > event_handler_.rule_table.registered_rule_num - found_idx)
788  {
789  possible_num_of_id_duplicates = event_handler_.rule_table.registered_rule_num - found_idx;
790  }
791  for (i = 0; i < possible_num_of_id_duplicates; ++i)
792  {
793  EH_RuleSortedIndex* p_idx = &event_handler_.sorted_idxes[found_idx + i];
794  if ( !(p_idx->group == group && p_idx->local == local) )
795  {
796  break;
797  }
798  found_sorted_idxes[i] = (uint16_t)(found_idx + i);
799  found_ids[i] = p_idx->rule_id;
800  (*found_id_num)++;
801  }
802 
804 }
805 
806 
807 static int EH_compare_sorted_index_for_bsearch_(const void* key, const void* elem)
808 {
809  const EH_RuleSortedIndex* p_key = (const EH_RuleSortedIndex*)key;
810  const EH_RuleSortedIndex* p_elem = (const EH_RuleSortedIndex*)elem;
811 
812  if (p_elem->group == p_key->group)
813  {
814  if (p_elem->local == p_key->local)
815  {
816  if (p_elem->duplicate_id == 0)
817  {
818  // 探してたもの
819  return 0;
820  }
821  else
822  {
823  // もっと手前にあるはず
824  return -1;
825  }
826  }
827  else if (p_elem->local < p_key->local)
828  {
829  return 1;
830  }
831  else
832  {
833  return -1;
834  }
835  }
836  else if (p_elem->group < p_key->group)
837  {
838  return 1;
839  }
840  else
841  {
842  return -1;
843  }
844 }
845 
846 
848  uint16_t* least_found_sorted_idx,
849  uint16_t* found_sorted_idx_num)
850 {
851  // idx: 0 ~ rule_table.registered_rule_num の間で二分探索する
852  // 重複もあり得ることを考慮する (duplicate_id は異なる)
853 
854  uint16_t found_idx = EH_RULE_MAX;
855  uint16_t last_found_sorted_idx = 0;
856  const EH_RuleSortedIndex* p_searched_sorted_idx = NULL;
857  EH_RuleSortedIndex target_sorted_idx;
858  uint16_t i;
859 
861  {
863  }
864 
865  memset(&target_sorted_idx, 0x00, sizeof(EH_RuleSortedIndex));
866  target_sorted_idx.group = group;
867  p_searched_sorted_idx = (EH_RuleSortedIndex*)bsearch(&target_sorted_idx,
870  sizeof(EH_RuleSortedIndex),
872  if (p_searched_sorted_idx == NULL) return EH_RULE_SORTED_INDEX_ACK_NOT_FOUND;
873  found_idx = (uint16_t)(p_searched_sorted_idx - (&event_handler_.sorted_idxes[0]));
874  *least_found_sorted_idx = found_idx;
875 
876  // ひとまず見つかったので,最も若いものを探す
877  for (i = found_idx; i >= 0; --i)
878  {
879  if (event_handler_.sorted_idxes[i].group == group)
880  {
881  *least_found_sorted_idx = i;
882  }
883  else
884  {
885  break;
886  }
887  }
888 
889  // 最も後ろのものを探す
890  for (i = found_idx; i < event_handler_.rule_table.registered_rule_num; ++i)
891  {
892  if (event_handler_.sorted_idxes[i].group == group)
893  {
894  last_found_sorted_idx = i;
895  }
896  else
897  {
898  break;
899  }
900  }
901 
902  *found_sorted_idx_num = (uint16_t)(last_found_sorted_idx - *least_found_sorted_idx + 1);
904 }
905 
906 
907 static int EH_compare_sorted_index_by_event_group_for_bsearch_(const void* key, const void* elem)
908 {
909  const EH_RuleSortedIndex* p_key = (const EH_RuleSortedIndex*)key;
910  const EH_RuleSortedIndex* p_elem = (const EH_RuleSortedIndex*)elem;
911 
912  if (p_elem->group == p_key->group)
913  {
914  return 0; // 注意: 同じ group のものが複数あった時,どれを bsearch が返すかは未規定
915  }
916  else if (p_elem->group < p_key->group)
917  {
918  return 1;
919  }
920  else
921  {
922  return -1;
923  }
924 }
925 
926 
928 {
929  // insert は,めんどくさい & 頻繁には起きないので,二分探索せずにやっていく
930  EH_RuleTable* p_rule_table = &event_handler_.rule_table;
932  const EL_GROUP insert_group = rule->settings.event.group;
933  const uint32_t insert_local = rule->settings.event.local;
934  uint16_t i;
935  uint8_t j;
936  uint16_t insert_idx;
937  uint8_t duplicate_id;
938 
939  EH_CHECK_RULE_ACK check_ack = EH_check_rule_id_(id);
942 
943  if (p_rule_table->registered_rule_num >= EH_RULE_MAX)
944  {
946  }
947 
948  insert_idx = p_rule_table->registered_rule_num;
949  duplicate_id = 0;
950  for (i = 0; i < p_rule_table->registered_rule_num; ++i)
951  {
952  EH_RuleSortedIndex* p_sorted_idx = &p_sorted_idxes[i];
953  uint8_t break_flag = 0;
954 
955  if (p_sorted_idx->group < insert_group) continue;
956 
957  if (p_sorted_idx->group > insert_group)
958  {
959  // 挿入する場所はここ
960  insert_idx = i;
961  break;
962  }
963 
964  // ここまできたら p_sorted_idx->group == insert_group
965  if (p_sorted_idx->local < insert_local) continue;
966 
967  if (p_sorted_idx->local > insert_local)
968  {
969  // 挿入する場所はここ
970  insert_idx = i;
971  break;
972  }
973 
974  // ここまできたら
975  // - p_sorted_idx->group == insert_group
976  // - p_sorted_idx->local == insert_local
977 
978  // 重複してる or する
979  for (j = 1; j < EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES; ++j)
980  {
981  uint16_t idx = (uint16_t)(i + j);
982  EH_RuleSortedIndex* p_sorted_idx = &p_sorted_idxes[idx];
983 
984  if (idx >= p_rule_table->registered_rule_num)
985  {
986  // 末端まできたので,ここが挿入する場所
987  insert_idx = idx;
988  duplicate_id = j;
989  break_flag = 1;
990  break;
991  }
992 
993  if (p_sorted_idx->group == insert_group && p_sorted_idx->local == insert_local)
994  {
995  // まだ重複している
996  continue;
997  }
998 
999  // 重複しなくなったので,ここが挿入する場所
1000  insert_idx = idx;
1001  duplicate_id = j;
1002  break_flag = 1;
1003  break;
1004  }
1005  if (break_flag) break;
1006 
1007  // 重複上限まで重複してしまっている
1009  }
1010 
1011  // ここまで来たら,挿入できる
1012  // insert_idx, duplicate_id が出揃っているはず
1013  memmove(&p_sorted_idxes[insert_idx + 1],
1014  &p_sorted_idxes[insert_idx],
1015  sizeof(EH_RuleSortedIndex) * (EH_RULE_MAX - insert_idx - 1));
1016  p_sorted_idxes[insert_idx].group = insert_group;
1017  p_sorted_idxes[insert_idx].local = insert_local;
1018  p_sorted_idxes[insert_idx].duplicate_id = duplicate_id;
1019  p_sorted_idxes[insert_idx].rule_id = id;
1020 
1021  p_rule_table->rules[id] = *rule;
1022  p_rule_table->registered_rule_num++;
1023 
1025 }
1026 
1027 
1029 {
1030  // delete は,めんどくさい & 頻繁には起きないので,二分探索せずにやっていく
1031  EH_RuleTable* p_rule_table = &event_handler_.rule_table;
1033  EL_GROUP delete_group;
1034  uint32_t delete_local;
1035  uint16_t i;
1036  uint8_t j;
1037  uint16_t delete_idx;
1038 
1039  EH_CHECK_RULE_ACK check_ack = EH_check_rule_id_(id);
1042 
1043  // この2個,const にしたい...
1044  delete_group = p_rule_table->rules[id].settings.event.group;
1045  delete_local = p_rule_table->rules[id].settings.event.local;
1046 
1047  delete_idx = EH_RULE_MAX;
1048  for (i = 0; i < p_rule_table->registered_rule_num; ++i)
1049  {
1050  if (id == p_sorted_idxes[i].rule_id)
1051  {
1052  // 見つかった
1053  delete_idx = i;
1054  break;
1055  }
1056  }
1057 
1058  if (delete_idx == EH_RULE_MAX)
1059  {
1060  // 本当はこれはありえないはず
1061  // (ありえないが,安全のため入れている.問題なさそうなら消してよし)
1065  0xffffffff);
1067  }
1068 
1069  // ここまで来たら削除できる
1070  memmove(&p_sorted_idxes[delete_idx],
1071  &p_sorted_idxes[delete_idx + 1],
1072  sizeof(EH_RuleSortedIndex) * (EH_RULE_MAX - delete_idx - 1));
1073  memset(&p_sorted_idxes[EH_RULE_MAX - 1], 0x00, sizeof(EH_RuleSortedIndex));
1074  p_sorted_idxes[EH_RULE_MAX - 1].group = (EL_GROUP)EL_CORE_GROUP_NULL;
1075  p_sorted_idxes[EH_RULE_MAX - 1].rule_id = EH_RULE_MAX;
1076 
1077  // 重複IDの処理
1078  for (j = 0; j < (EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES - 1); ++j)
1079  {
1080  uint16_t idx = (uint16_t)(delete_idx + j);
1081  EH_RuleSortedIndex* p_sorted_idx = &p_sorted_idxes[idx];
1082 
1083  if (p_sorted_idx->group == delete_group && p_sorted_idx->local == delete_local)
1084  {
1085  p_sorted_idx->duplicate_id--;
1086  }
1087  else
1088  {
1089  break;
1090  }
1091  }
1092 
1093  memset(&p_rule_table->rules[id], 0x00, sizeof(EH_Rule));
1094  p_rule_table->rules[id].settings.event.group = (EL_GROUP)EL_CORE_GROUP_NULL;
1095  p_rule_table->registered_rule_num--;
1096 
1098 }
1099 
1100 
1102 {
1104  EH_Rule rule;
1105 
1106  if (settings->event.group >= EL_GROUP_MAX) return EH_REGISTER_ACK_ILLEGAL_GROUP;
1108  if (settings->event.err_level < 0) return EH_REGISTER_ACK_ILLEGAL_ERROR_LEVEL;
1110  if (settings->should_match_err_level != 0 && settings->should_match_err_level != 1)
1111  {
1113  }
1115  if (settings->condition.type != EH_RESPONSE_CONDITION_SINGLE)
1116  {
1118  }
1120  if (settings->is_active != 0 && settings->is_active != 1)
1121  {
1123  }
1124  if (settings->event.err_level == EL_ERROR_LEVEL_EH)
1125  {
1126  // 多段対応以外で EL_ERROR_LEVEL_EH の設定は不可
1128  }
1129  if (settings->event.group == (EL_GROUP)EL_CORE_GROUP_EH_MATCH_RULE)
1130  {
1131  // 多段の時は EL_ERROR_LEVEL_EH が必須
1134  }
1135  if (settings->event.group == (EL_GROUP)EL_CORE_GROUP_EH_MATCH_RULE)
1136  {
1137  // 多段設定の最大値を超えてないかチェック
1138  uint8_t multi_level_num;
1139  EH_RULE_ID lower_level_rule = (EH_RULE_ID)(settings->event.local);
1140 
1141  // 1段以下なら,そもそも多段が組めない
1143 
1144  // 無限ループ回避のために EH_RULE_MAX で抑える
1145  for (multi_level_num = 0; multi_level_num < EH_RULE_MAX; ++multi_level_num)
1146  {
1147  EH_RuleSettings* rule_settings;
1148  EH_CHECK_RULE_ACK ack;
1149 
1150  ack = EH_check_rule_id_(lower_level_rule);
1152  if (ack == EH_CHECK_RULE_ACK_UNREGISTERED) break;
1153 
1154  rule_settings = &event_handler_.rule_table.rules[lower_level_rule].settings;
1155 
1156  if (rule_settings->event.group != (EL_GROUP)EL_CORE_GROUP_EH_MATCH_RULE) break;
1157 
1158  // 更に多段になっている
1159  lower_level_rule = (EH_RULE_ID)rule_settings->event.local;
1160 
1162  }
1163  }
1164 
1165  rule.settings = *settings;
1166  rule.counter = 0;
1167  OBCT_clear(&rule.last_event_time);
1168 
1169  ack = EH_insert_rule_table_(id, &rule);
1170 
1171  switch (ack)
1172  {
1174  return EH_REGISTER_ACK_OK;
1178  return EH_REGISTER_ACK_ERR_FULL;
1183  default:
1185  }
1186 }
1187 
1188 
1190 {
1191  if (id < 0) return EH_CHECK_RULE_ACK_INVALID_RULE_ID;
1194  {
1196  }
1197  return EH_CHECK_RULE_ACK_OK;
1198 }
1199 
1200 
1202  EH_CHECK_RULE_ACK (*func)(EH_RULE_ID))
1203 {
1204  uint16_t least_found_sorted_idx = 0;
1205  uint16_t found_sorted_idx_num = 0;
1206  EH_RULE_SORTED_INDEX_ACK search_ack;
1207  uint16_t i;
1208 
1209  search_ack = EH_search_rule_table_index_by_event_group_(group,
1210  &least_found_sorted_idx,
1211  &found_sorted_idx_num);
1212  if (search_ack == EH_RULE_SORTED_INDEX_ACK_NOT_FOUND)
1213  {
1214  // 操作すべき EH_Rule はなし
1215  return;
1216  }
1217  if (search_ack != EH_RULE_SORTED_INDEX_ACK_OK || found_sorted_idx_num == 0)
1218  {
1219  // 何かがおかしい(ありえないが,安全のため入れている.問題なさそうなら消してよし)
1223  (uint32_t)group);
1224  return;
1225  }
1226 
1227  for (i = 0; i < found_sorted_idx_num; ++i)
1228  {
1229  func(event_handler_.sorted_idxes[least_found_sorted_idx + i].rule_id);
1230  }
1231 }
1232 
1233 
1235 {
1237  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1238 
1239  EH_activate_rule(id);
1241  return EH_CHECK_RULE_ACK_OK;
1242 }
1243 
1244 
1246 {
1247  int i;
1248  EH_RULE_ID next_rule_id = id;
1250  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1251 
1252  // 無限ループ回避のため for で
1253  for (i = 0; i < (int)EH_RULE_MAX; ++i)
1254  {
1255  if (EH_activate_rule(next_rule_id) != EH_CHECK_RULE_ACK_OK) break;
1256  EH_clear_rule_counter(next_rule_id);
1258  {
1259  break;
1260  }
1261  next_rule_id = (EH_RULE_ID)event_handler_.rule_table.rules[next_rule_id].settings.event.local;
1262  }
1263 
1264  return EH_CHECK_RULE_ACK_OK;
1265 }
1266 
1267 
1269 {
1271 }
1272 
1273 
1275 {
1277 }
1278 
1279 
1281 {
1283  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1284 
1286  return EH_CHECK_RULE_ACK_OK;
1287 }
1288 
1289 
1291 {
1293  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1294 
1296  return EH_CHECK_RULE_ACK_OK;
1297 }
1298 
1299 
1301 {
1302  int i;
1303  EH_RULE_ID next_rule_id = id;
1305  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1306 
1307  // 無限ループ回避のため for
1308  for (i = 0; i < (int)EH_RULE_MAX; ++i)
1309  {
1310  if (EH_activate_rule(next_rule_id) != EH_CHECK_RULE_ACK_OK) break;
1312  {
1313  break;
1314  }
1315  next_rule_id = (EH_RULE_ID)event_handler_.rule_table.rules[next_rule_id].settings.event.local;
1316  }
1317 
1318  return EH_CHECK_RULE_ACK_OK;
1319 }
1320 
1321 
1323 {
1324  int i;
1325  EH_RULE_ID next_rule_id = id;
1327  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1328 
1329  // 無限ループ回避のため for
1330  for (i = 0; i < (int)EH_RULE_MAX; ++i)
1331  {
1332  if (EH_inactivate_rule(next_rule_id) != EH_CHECK_RULE_ACK_OK) break;
1334  {
1335  break;
1336  }
1337  next_rule_id = (EH_RULE_ID)event_handler_.rule_table.rules[next_rule_id].settings.event.local;
1338  }
1339 
1340  return EH_CHECK_RULE_ACK_OK;
1341 }
1342 
1343 
1345 {
1347 }
1348 
1349 
1351 {
1353 }
1354 
1355 
1357 {
1359 }
1360 
1361 
1363 {
1365 }
1366 
1367 
1369 {
1371  if (ack != EH_CHECK_RULE_ACK_OK) return 0;
1372 
1374 }
1375 
1377 {
1379  if (ack != EH_CHECK_RULE_ACK_OK) return ack;
1380 
1381  event_handler_.rule_table.rules[id].counter = counter;
1382  return EH_CHECK_RULE_ACK_OK;
1383 }
1384 
1385 
1387 {
1388  return EH_set_rule_counter(id, 0);
1389 }
1390 
1391 
1392 void EH_clear_rule_counter_by_event(EL_GROUP group, uint32_t local, EL_ERROR_LEVEL err_level)
1393 {
1394  EH_RULE_SORTED_INDEX_ACK search_ack;
1396  uint16_t found_sorted_idxes[EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES];
1397  uint8_t found_id_num;
1398  uint8_t i;
1399 
1400  search_ack = EH_search_rule_table_index_(group,
1401  local,
1402  found_ids,
1403  found_sorted_idxes,
1404  &found_id_num);
1405 
1406  if (search_ack == EH_RULE_SORTED_INDEX_ACK_NOT_FOUND)
1407  {
1408  // 対応する EH_Rule なし
1409  return;
1410  }
1411  if (search_ack != EH_RULE_SORTED_INDEX_ACK_OK)
1412  {
1416  (uint32_t)search_ack);
1417  return;
1418  }
1419 
1420  // 見つかったルールに対して処理
1421  for (i = 0; i < found_id_num; ++i)
1422  {
1423  EH_RULE_ID id = found_ids[i];
1424  EH_RuleSettings* rule_settings = &event_handler_.rule_table.rules[id].settings;
1425 
1426  if (rule_settings->should_match_err_level)
1427  {
1428  if (rule_settings->event.err_level != err_level) continue;
1429  }
1431  }
1432 }
1433 
1434 
1436 {
1437  uint8_t err_level;
1439  for (err_level = 0; err_level < EL_ERROR_LEVEL_MAX; ++err_level)
1440  {
1442  }
1443 }
1444 
1445 
1447 {
1448  uint16_t idx;
1449 
1450  if (n >= EH_LOG_MAX)
1451  {
1452  // 仕方がないので,最新のものを
1453  idx = 0;
1454  }
1455  else
1456  {
1457  idx = (uint16_t)((event_handler->log_table.log_wp - 1 - n + EH_LOG_MAX) % EH_LOG_MAX);
1458  }
1459 
1460  return &event_handler->log_table.logs[idx];
1461 }
1462 
1463 
1465 {
1466  (void)packet;
1467  EH_initialize();
1469 }
1470 
1471 
1473 {
1474  (void)packet;
1475  EH_clear_rules_();
1477 }
1478 
1479 
1481 {
1482  (void)packet;
1485 }
1486 
1487 
1489 {
1490  // 登録する瞬間にしかわからないので,ここでは値のアサーションはせず,
1491  // Cmd_EH_REGISTER_RULE でアサーションする
1498 
1500 }
1501 
1502 
1504 {
1505  // 登録する瞬間にしかわからないので,ここでは値のアサーションはせず,
1506  // Cmd_EH_REGISTER_RULE でアサーションする
1511 
1513 }
1514 
1515 
1517 {
1518  (void)packet;
1521 
1523  {
1524  case EH_REGISTER_ACK_OK:
1535  return CCP_make_cmd_ret_without_err_code(CCP_EXEC_ILLEGAL_PARAMETER); // 正確にはこのコマンドのパラメタではないが...
1541  default:
1543  }
1544 }
1545 
1546 
1548 {
1549  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1551 
1552  switch (ack)
1553  {
1560  default:
1562  }
1563 }
1564 
1565 
1567 {
1568  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1569  EH_CHECK_RULE_ACK ack = EH_init_rule(rule_id);
1570 
1571  switch (ack)
1572  {
1573  case EH_CHECK_RULE_ACK_OK:
1579  default:
1581  }
1582 }
1583 
1584 
1586 {
1587  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1589 
1590  switch (ack)
1591  {
1592  case EH_CHECK_RULE_ACK_OK:
1598  default:
1600  }
1601 }
1602 
1603 
1605 {
1606  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1607  EH_CHECK_RULE_ACK ack = EH_activate_rule(rule_id);
1608 
1609  switch (ack)
1610  {
1611  case EH_CHECK_RULE_ACK_OK:
1617  default:
1619  }
1620 }
1621 
1622 
1624 {
1625  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1626  EH_CHECK_RULE_ACK ack = EH_inactivate_rule(rule_id);
1627 
1628  switch (ack)
1629  {
1630  case EH_CHECK_RULE_ACK_OK:
1636  default:
1638  }
1639 }
1640 
1641 
1643 {
1644  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1646 
1647  switch (ack)
1648  {
1649  case EH_CHECK_RULE_ACK_OK:
1655  default:
1657  }
1658 }
1659 
1660 
1662 {
1663  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1665 
1666  switch (ack)
1667  {
1668  case EH_CHECK_RULE_ACK_OK:
1674  default:
1676  }
1677 }
1678 
1679 
1681 {
1682  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1683  uint16_t counter = CCP_get_param_from_packet(packet, 1, uint16_t);
1684  EH_CHECK_RULE_ACK ack = EH_set_rule_counter(rule_id, counter);
1685 
1686  switch (ack)
1687  {
1688  case EH_CHECK_RULE_ACK_OK:
1694  default:
1696  }
1697 }
1698 
1699 
1701 {
1702  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1704 
1705  switch (ack)
1706  {
1707  case EH_CHECK_RULE_ACK_OK:
1713  default:
1715  }
1716 }
1717 
1718 
1720 {
1721  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1722  uint32_t local = (EL_GROUP)CCP_get_param_from_packet(packet, 1, uint32_t);
1723  EL_ERROR_LEVEL err_level = (EL_ERROR_LEVEL)CCP_get_param_from_packet(packet, 2, uint8_t);
1724 
1725  EH_clear_rule_counter_by_event(group, local, err_level);
1727 }
1728 
1729 
1731 {
1732  (void)packet;
1733  EH_clear_log_();
1735 }
1736 
1737 
1739 {
1742 }
1743 
1744 
1746 {
1749 }
1750 
1751 
1753 {
1756 }
1757 
1758 
1760 {
1761  uint8_t page = CCP_get_param_from_packet(packet, 0, uint8_t);
1765 }
1766 
1767 
1769 {
1770  uint8_t page = CCP_get_param_from_packet(packet, 0, uint8_t);
1774 }
1775 
1776 
1778 {
1779  uint8_t page = CCP_get_param_from_packet(packet, 0, uint8_t);
1783 }
1784 
1785 
1787 {
1788  EH_RULE_ID rule_id = (EH_RULE_ID)CCP_get_param_from_packet(packet, 0, uint16_t);
1789 
1791  {
1793  }
1794 
1797 }
1798 
1799 
1801 {
1802  (void)packet;
1805 }
1806 
1807 
1809 {
1810  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1813 }
1814 
1815 
1817 {
1818  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1821 }
1822 
1823 
1825 {
1826  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1829 }
1830 
1831 
1833 {
1834  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1837 }
1838 
1839 
1841 {
1842  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1845 }
1846 
1847 
1849 {
1850  EL_GROUP group = (EL_GROUP)CCP_get_param_from_packet(packet, 0, uint32_t);
1853 }
1854 
1855 #endif // EL_IS_ENABLE_TLOG
1856 
1857 #pragma section
#define BCT_MAX_BLOCKS
BCのIDの最大数
uint16_t bct_id_t
void * bsearch(const void *key, const void *base, size_t nmemb, size_t size, compr_func compr)
Definition: bsearch.c:16
CCP_EXEC_STS
コマンド実行結果コード
@ CCP_EXEC_SUCCESS
@ CCP_EXEC_ILLEGAL_PARAMETER
コマンド実行時のパラメタエラー
@ CCP_EXEC_ILLEGAL_CONTEXT
コマンド実行時のその他のエラー
CCP_CmdRet CCP_form_and_exec_block_deploy_cmd(TLCD_ID tl_no, bct_id_t block_no)
BC展開 command を生成し,即時実行する
CCP_CmdRet CCP_make_cmd_ret_without_err_code(CCP_EXEC_STS exec_sts)
コマンド返り値である CCP_CmdRet を作成(エラーコード不使用版)
#define CCP_get_param_from_packet(packet, n, type)
CCP packet から,n番目のコマンド引数を取得する
EH_REGISTER_ACK EH_register_rule(EH_RULE_ID id, const EH_RuleSettings *settings)
ルールの登録
static EH_RULE_SORTED_INDEX_ACK EH_insert_rule_table_(EH_RULE_ID id, const EH_Rule *rule)
EH_Rule を EH_RuleTable と EH_RuleSortedIndex に挿入する
const EventHandler *const event_handler
static EventHandler event_handler_
static int EH_compare_sorted_index_for_bsearch_(const void *key, const void *elem)
EH_search_rule_table_index_ での bsearch 用の EH_RuleSortedIndex 比較関数
static void EH_exec_func_by_event_group_(EL_GROUP group, EH_CHECK_RULE_ACK(*func)(EH_RULE_ID))
by_event_group 関数を実行する主体
CCP_CmdRet Cmd_EH_SET_REGISTER_RULE_EVENT_PARAM(const CommonCmdPacket *packet)
static uint8_t EH_check_event_and_respond_(const EL_Event *event)
EL_Event に対応する EH_Rule が存在するかチェックし,対応する
EH_CHECK_RULE_ACK EH_init_rule_for_multi_level(EH_RULE_ID id)
ルールの初期化 (multi-level)
const EH_Log * EH_get_the_nth_log_from_the_latest(uint16_t n)
EH_LogTable の最新からn番目の対応ログを取得
CCP_CmdRet Cmd_EH_SET_RULE_COUNTER(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_INIT_RULE_BY_EVENT_GROUP_FOR_MULTI_LEVEL(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_CLEAR_LOG(const CommonCmdPacket *packet)
static EH_CKECK_RULE_ACK EH_check_rule_(EH_RULE_ID rule_id, const EL_Event *event)
EH の対応条件をチェックする
void EH_activate_rule_by_event_group(EL_GROUP group)
EH_RuleSettings.event.group 指定による一括でのルールの有効化
CCP_CmdRet Cmd_EH_SET_REGISTER_RULE_CONDITION_PARAM(const CommonCmdPacket *packet)
void EH_init_rule_by_event_group(EL_GROUP group)
EH_RuleSettings.event.group 指定による一括でのルールの初期化
EH_CHECK_RULE_ACK EH_init_rule(EH_RULE_ID id)
ルールの初期化
CCP_CmdRet Cmd_EH_SET_MAX_MULTI_LEVEL_NUM(const CommonCmdPacket *packet)
void EH_initialize(void)
event_handler の初期化
static EH_RULE_SORTED_INDEX_ACK EH_search_rule_table_index_(EL_GROUP group, uint32_t local, EH_RULE_ID found_ids[EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES], uint16_t found_sorted_idxes[EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES], uint8_t *found_id_num)
EH_RuleSortedIndex から,目的の EL_Event の idx を検索する
void EH_clear_rule_counter_by_event(EL_GROUP group, uint32_t local, EL_ERROR_LEVEL err_level)
EH_Rule の counter を EL_Event 指定で 0 クリア
CCP_CmdRet Cmd_EH_INIT_RULE(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_LOAD_DEFAULT_RULE(const CommonCmdPacket *packet)
static EH_CHECK_RULE_ACK EH_check_rule_id_(EH_RULE_ID id)
EH_RULE_ID のルール登録状況を調べる
CCP_CmdRet Cmd_EH_MATCH_EVENT_COUNTER_TO_EL(const CommonCmdPacket *packet)
新しい EL_Event 発生を検出するためのカウンタを強制的に EL のカウンタに合わせる
CCP_CmdRet Cmd_EH_INIT_RULE_BY_EVENT_GROUP(const CommonCmdPacket *packet)
void EH_match_event_counter_to_el(void)
イベントカウンタを EL のそれに合わせる
static int EH_compare_sorted_index_by_event_group_for_bsearch_(const void *key, const void *elem)
EH_search_rule_table_index_by_event_group_ での bsearch 用の EH_RuleSortedIndex 比較関数
CCP_CmdRet Cmd_EH_INACTIVATE_RULE_FOR_MULTI_LEVEL(const CommonCmdPacket *packet)
static const EL_Event * EH_get_event_to_check_rule_(void)
EH_Rule が存在するかチェックするための次の EL_Event (EL_ERROR_LEVEL_EH を除く) を返す
void EH_execute(void)
event_handler の実行
static EH_RULE_SORTED_INDEX_ACK EH_delete_rule_table_(EH_RULE_ID id)
EH_Rule を EH_RuleTable と EH_RuleSortedIndex から削除する
void EH_activate_rule_by_event_group_for_multi_level(EL_GROUP group)
EH_RuleSettings.event.group 指定による一括でのルールの有効化 (multi-level)
CCP_CmdRet Cmd_EH_ACTIVATE_RULE_BY_EVENT_GROUP_FOR_MULTI_LEVEL(const CommonCmdPacket *packet)
EH_CHECK_RULE_ACK EH_clear_rule_counter(EH_RULE_ID id)
EH_Rule の counter を 0 クリア
CCP_CmdRet Cmd_EH_CLEAR_RULE_COUNTER(const CommonCmdPacket *packet)
EH_CHECK_RULE_ACK EH_set_rule_counter(EH_RULE_ID id, uint16_t counter)
EH_Rule の counter をセット
CCP_CmdRet Cmd_EH_SET_PAGE_OF_RULE_SORTED_IDX_FOR_TLM(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_INACTIVATE_RULE_BY_EVENT_GROUP(const CommonCmdPacket *packet)
uint8_t EH_get_rule_is_active(EH_RULE_ID id)
ルールが有効かどうか取得する
static void EH_respond_(EH_RULE_ID rule_id)
EH 対応を実施
CCP_CmdRet Cmd_EH_INIT_RULE_FOR_MULTI_LEVEL(const CommonCmdPacket *packet)
EH_CHECK_RULE_ACK EH_activate_rule(EH_RULE_ID id)
ルールの有効化
void EH_inactivate_rule_by_event_group_for_multi_level(EL_GROUP group)
EH_RuleSettings.event.group 指定による一括でのルールの無効化 (multi-level)
static const EL_Event * EH_get_oldest_event_excluding_eh_error_level_(void)
まだ処理していない最も古い EL_Event (EL_ERROR_LEVEL_EH を除く) を返す
CCP_CmdRet Cmd_EH_SET_MAX_CHECK_EVENT_NUM(const CommonCmdPacket *packet)
void EH_init_rule_by_event_group_for_multi_level(EL_GROUP group)
EH_RuleSettings.event.group 指定による一括でのルールの初期化 (multi-level)
static void EH_clear_rules_(void)
EH_RuleTable を全消去
EH_RULE_SORTED_INDEX_ACK
EH_RuleSortedIndex を操作するときの返り値
Definition: event_handler.c:50
@ EH_RULE_SORTED_INDEX_ACK_RULE_OVERWRITE
ルールの上書きになってしまう(すでに同じ ID にルールが登録されているため棄却)
Definition: event_handler.c:55
@ EH_RULE_SORTED_INDEX_ACK_ILLEGAL_RULE_ID
不正な EH_RULE_ID
Definition: event_handler.c:52
@ EH_RULE_SORTED_INDEX_ACK_NOT_FOUND
見つからず
Definition: event_handler.c:53
@ EH_RULE_SORTED_INDEX_ACK_DUPLICATE_FULL
重複上限まで重複してしまっている
Definition: event_handler.c:56
@ EH_RULE_SORTED_INDEX_ACK_OK
正常終了
Definition: event_handler.c:51
@ EH_RULE_SORTED_INDEX_ACK_FULL
これ以上登録できない
Definition: event_handler.c:54
static EH_ACK EH_check_el_event_counter_(void)
EL 側の EL_Event のカウンタをチェックし,整合性を確認する
CCP_CmdRet Cmd_EH_SET_MAX_RESPONSE_NUM(const CommonCmdPacket *packet)
static EH_CKECK_RULE_ACK EH_check_continuous_rule_(EH_RULE_ID rule_id, const EL_Event *event)
EH の対応条件をチェックする (EH_RESPONSE_CONDITION_CONTINUOUS)
static EH_CKECK_RULE_ACK EH_check_single_rule_(EH_RULE_ID rule_id, const EL_Event *event)
EH の対応条件をチェックする (EH_RESPONSE_CONDITION_SINGLE)
EH_EL_LOCAL_ID
EL_CORE_GROUP_EVENT_HANDLER イベントの local id
Definition: event_handler.c:22
@ EH_EL_LOCAL_ID_TOO_MANY_EVENT
イベントが発生しすぎて,TLogが失われている
Definition: event_handler.c:25
@ EH_EL_LOCAL_ID_FAIL_TO_RESPOND
EH 対応時に BC 展開に失敗
Definition: event_handler.c:26
@ EH_EL_LOCAL_ID_UNKNOWN_ERR
不明なエラー
Definition: event_handler.c:30
@ EH_EL_LOCAL_ID_EL_COUNTER_ERR
ELとEHのカウンタの不整合エラー (counters)
Definition: event_handler.c:24
@ EH_EL_LOCAL_ID_RECURSION_ERR
多段対応時に再帰呼び出し回数が設定値を超えた
Definition: event_handler.c:29
@ EH_EL_LOCAL_ID_EL_TOTAL_COUNTER_ERR
ELとEHのカウンタの不整合エラー (counter_total)
Definition: event_handler.c:23
@ EH_EL_LOCAL_ID_LOG_TABLE_FULL
EH_LogTable が満杯になり, wp が 0 に戻った
Definition: event_handler.c:27
@ EH_EL_LOCAL_ID_SEARCH_ERR
EH_search_rule_table_index_ の返り値不正
Definition: event_handler.c:28
EH_CKECK_RULE_ACK
EH_check_rule 系関数の返り値
Definition: event_handler.c:65
@ EH_CKECK_RULE_ACK_MATCH
該当 EH_Rule にマッチした
Definition: event_handler.c:66
@ EH_CKECK_RULE_ACK_NOT_MATCH
該当 EH_Rule にマッチしなかった
Definition: event_handler.c:67
CCP_CmdRet Cmd_EH_CLEAR_RULE_COUNTER_BY_EVENT(const CommonCmdPacket *packet)
static EH_RULE_SORTED_INDEX_ACK EH_search_rule_table_index_by_event_group_(EL_GROUP group, uint16_t *least_found_sorted_idx, uint16_t *found_sorted_idx_num)
EH_RuleSortedIndex から,指定した EL_GROUP の EH_Rule を指す最も若い EH_RuleSortedIndex を取得する
CCP_CmdRet Cmd_EH_DELETE_RULE(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_INACTIVATE_RULE_BY_EVENT_GROUP_FOR_MULTI_LEVEL(const CommonCmdPacket *packet)
EH_ACK
EH の内部関数返り値
Definition: event_handler.c:39
@ EH_ACK_OK
Definition: event_handler.c:40
@ EH_ACK_ERR
Definition: event_handler.c:41
EH_CHECK_RULE_ACK EH_activate_rule_for_multi_level(EH_RULE_ID id)
ルールの有効化 (multi-level)
CCP_CmdRet Cmd_EH_ACTIVATE_RULE_FOR_MULTI_LEVEL(const CommonCmdPacket *packet)
void EH_inactivate_rule_by_event_group(EL_GROUP group)
EH_RuleSettings.event.group 指定による一括でのルールの無効化
static uint8_t EH_check_rule_and_respond_(EH_RULE_ID rule_id, const EL_Event *event)
EH の対応条件をチェックし, EL_Event に対応する
CCP_CmdRet Cmd_EH_INACTIVATE_RULE(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_ACTIVATE_RULE_BY_EVENT_GROUP(const CommonCmdPacket *packet)
EH_CHECK_RULE_ACK EH_inactivate_rule(EH_RULE_ID id)
ルールの無効化
CCP_CmdRet Cmd_EH_REGISTER_RULE(const CommonCmdPacket *packet)
static void EH_clear_log_(void)
EH 対応ログを全消去
static void EH_record_responded_log_(EH_RULE_ID rule_id, CCP_EXEC_STS deploy_cmd_ack)
EH 対応のログを残す
CCP_CmdRet Cmd_EH_ACTIVATE_RULE(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_INIT(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_SET_PAGE_OF_LOG_TABLE_FOR_TLM(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_SET_TARGET_ID_OF_RULE_TABLE_FOR_TLM(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_SET_PAGE_OF_RULE_TABLE_FOR_TLM(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_EH_CLEAR_ALL_RULE(const CommonCmdPacket *packet)
static EH_CKECK_RULE_ACK EH_check_cumulative_rule_(EH_RULE_ID rule_id, const EL_Event *event)
EH の対応条件をチェックする (EH_RESPONSE_CONDITION_CUMULATIVE)
static uint8_t EH_check_higher_level_rule_and_respond_(EH_RULE_ID rule_id)
上位の EH の対応条件をチェックし,対応する
EH_CHECK_RULE_ACK EH_inactivate_rule_for_multi_level(EH_RULE_ID id)
ルールの無効化 (multi-level)
イベント発火型処理を行う
#define EH_LOG_MAX
最大何個の EH 対応ログを保持できるか
EH_CHECK_RULE_ACK
EH_Rule 登録状況確認用
@ EH_CHECK_RULE_ACK_INVALID_RULE_ID
EH_RULE_ID が不正
@ EH_CHECK_RULE_ACK_OK
正常 or ルール登録済み
@ EH_CHECK_RULE_ACK_UNREGISTERED
ルールが未登録
#define EH_MAX_RULE_NUM_OF_EL_ID_DUPLICATES
EL_Event の ID が重複した EH_Rule を最大何個まで重複させてよいか (uint8_t を想定)
EH_REGISTER_ACK
EH_register_rule の返り値
@ EH_REGISTER_ACK_ILLEGAL_MULTI_LEVEL
多段 EH 対応での不正な設定
@ EH_REGISTER_ACK_ILLEGAL_RULE_ID
不正な EH_RULE_ID
@ EH_REGISTER_ACK_ILLEGAL_MATCH_FLAG
不正な should_match_err_level
@ EH_REGISTER_ACK_ILLEGAL_GROUP
不正な EL_Event.group
@ EH_REGISTER_ACK_ERR_RULE_OVERWRITE
すでに同じ ID にルールが登録されているため棄却
@ EH_REGISTER_ACK_ILLEGAL_ERROR_LEVEL
不正な EL_Event.err_level
@ EH_REGISTER_ACK_UNKNOWN_ERR
不明なエラー
@ EH_REGISTER_ACK_ERR_FULL
これ以上登録できない
@ EH_REGISTER_ACK_ERR_DUPLICATE_FULL
これ以上, EL_Event の重複した EH_Rule を登録できない
@ EH_REGISTER_ACK_ILLEGAL_CONDITION_TYPE
不正な EH_RESPONSE_CONDITION_TYPE
@ EH_REGISTER_ACK_OK
正常に登録完了
@ EH_REGISTER_ACK_ILLEGAL_BCT_ID
不正な deploy_bct_id
@ EH_REGISTER_ACK_ILLEGAL_COUNT_THRESHOLD
不正な condition.count_threshold
@ EH_REGISTER_ACK_ILLEGAL_ACTIVE_FLAG
不正な is_active
#define EH_RULE_TLM_PAGE_MAX
event_handler のルールテーブルのページ数(ページネーション用)
#define EH_MAX_MULTI_LEVEL_NUM_DEFAULT
多段の EH 対応の設定可能な最大段数(初期値) (uint8_t を想定)
#define EH_LOG_TLM_PAGE_MAX
EH対応のログテーブルのページ数(ページネーション用)
#define EH_MAX_CHECK_EVENT_NUM_DEFAULT
#define EH_RULE_MAX
EH_RESPONSE_CONDITION_TYPE
EL_Event 登録に対して,どのように EH 対応させるかの種類
@ EH_RESPONSE_CONDITION_CONTINUOUS
Event 登録後 N 秒以内に再び同じ Event 登録が発生することが M 回連続で発生した場合に EH 対応
@ EH_RESPONSE_CONDITION_TYPE_MAX
@ EH_RESPONSE_CONDITION_CUMULATIVE
Event が M 回登録した場合に EH 対応
@ EH_RESPONSE_CONDITION_SINGLE
Event 登録に対して即座に EH 対応
#define EH_MAX_RESPONSE_NUM_DEFAULT
一度の実行で対応する最大数(初期値) (uint8_t を想定)
void EH_load_default_rules(void)
event_handler のデフォルトルールを読み込む
EH_RULE_ID
EH_Rule の ID
EL_ACK EL_record_event(EL_GROUP group, uint32_t local, EL_ERROR_LEVEL err_level, uint32_t note)
イベント (EL_Event) を記録
Definition: event_logger.c:269
const EL_Event * EL_get_the_nth_tlog_from_the_latest(EL_ERROR_LEVEL err_level, uint16_t n)
TLog のイベントテーブルの最新からn番目のイベントを取得
Definition: event_logger.c:721
const EventLogger *const event_logger
Definition: event_logger.c:155
@ EL_CORE_GROUP_EH_RESPOND_WITH_HIGHER_LEVEL_RULE
EH_Rule でマッチしたが,そのルールで対応せずに,上位のルールで対応させた(詳細は event_handler.h 参照)
Definition: event_logger.h:216
@ EL_CORE_GROUP_EH_MATCH_RULE
EH_Rule でマッチした(詳細は event_handler.h 参照)
Definition: event_logger.h:215
@ EL_CORE_GROUP_NULL
初期値 or NULL.これは 0 であることを要求 (clear で memset 0x00 をするなら)
Definition: event_logger.h:206
@ EL_CORE_GROUP_EVENT_HANDLER
EH (詳細は event_handler.h 参照)
Definition: event_logger.h:214
EL_ERROR_LEVEL
event_logger の エラーレベル
Definition: event_logger.h:261
@ EL_ERROR_LEVEL_MAX
Definition: event_logger.h:272
@ EL_ERROR_LEVEL_EH
Definition: event_logger.h:270
@ EL_ERROR_LEVEL_HIGH
Definition: event_logger.h:262
@ EL_ERROR_LEVEL_LOW
Definition: event_logger.h:266
EL_GROUP
event_logger の Event Group の user 定義部分
@ EL_GROUP_MAX
uint32_t OBCT_diff_in_msec(const ObcTime *before, const ObcTime *after)
ObcTime の引き算をミリ秒単位で行う
Definition: obc_time.c:153
ObcTime OBCT_get_max(void)
ObcTime が取りうる最大値を返す
Definition: obc_time.c:54
int OBCT_compare(const ObcTime *t1, const ObcTime *t2)
ObcTime の比較
Definition: obc_time.c:181
void OBCT_clear(ObcTime *time)
ObcTime をクリアし全てゼロにする
Definition: obc_time.c:23
PL_ACK
PacketList 関連操作のエラーコード
Definition: packet_list.h:39
@ PL_BC_TIME_ADJUSTED
同時刻に Node があったため調整せれた
Definition: packet_list.h:50
コマンド返り値
uint32_t err_code
各 Cmd ユニークなエラーコード.各 App で定義する enum などを入れることを想定.
CCP_EXEC_STS exec_sts
CCP_EXEC_STS.Cmd の統一的なエラーコード
Space Packet (コマンド用)
uint32_t counter_total
前回 EH_execute 実行時の EL でのイベント記録数
uint32_t counters[EL_ERROR_LEVEL_MAX]
エラーレベルごとの記録数
uint8_t current_multi_level
現在処理してる多段 EH 対応レベル
uint8_t max_multi_level_num
uint8_t max_response_num
uint16_t max_check_event_num
EH 対応のログ
CCP_EXEC_STS deploy_cmd_ack
cycle_t respond_time_in_master_cycle
EH_RULE_ID rule_id
EH 対応のログテーブル
uint16_t log_wp
uint32_t respond_counter
EH_Log logs[EH_LOG_MAX]
EH_RuleSettings settings
登録する EH_RuleSettings
EH_REGISTER_ACK register_ack
EH_register_rule の返り値
EH_RULE_ID rule_id
登録先 EH_RULE_ID
EL_Event に対して対応する EH_Rule
EH_RuleSettings settings
設定値
ObcTime last_event_time
最後に発生した EL_Event の時刻
uint16_t counter
EH 対応までのカウンタ
EH_register_rule の引数.Rule登録に必要な情報
struct EH_RuleSettings::@8 event
EH に対応する EL_Event
EL_GROUP group
引っ掛ける EL_Event.group
uint32_t time_threshold_ms
uint8_t should_match_err_level
EL_Event の一致に,エラーレベル一致を含めるか?
uint8_t is_active
対応が有効か? 対応後,自動的に無効になる
struct EH_RuleSettings::@9 condition
EH 対応条件
EH_RESPONSE_CONDITION_TYPE type
EH 対応の条件種類
bct_id_t deploy_bct_id
EH 対応に展開する BCT id
uint16_t count_threshold
uint32_t local
引っ掛ける EL_Event.local
EL_ERROR_LEVEL err_level
EL_GROUP group
EH_Rule.event.group
uint8_t duplicate_id
同じ {group. local} の rule がある場合の,重複ID
uint32_t local
EH_Rule.event.local
EH_RULE_ID rule_id
EventHandler.rules の idx
EH_Rule のテーブル
uint16_t registered_rule_num
登録済み rule 数
EH_Rule rules[EH_RULE_MAX]
idx は EH_RULE_ID
struct EH_TlmInfo::@11 rule_sorted_index
struct EH_TlmInfo::@10 rule
struct EH_TlmInfo::@12 log
uint8_t page_no
EH_RULE_ID target_rule_id
イベント
Definition: event_logger.h:297
EL_GROUP group
イベントを特定する group id
Definition: event_logger.h:298
uint32_t local
Definition: event_logger.h:299
ObcTime time
発生時刻
Definition: event_logger.h:303
EL_ERROR_LEVEL err_level
エラーレベル
Definition: event_logger.h:302
uint32_t record_counters[EL_ERROR_LEVEL_MAX]
エラーレベルごとの記録数
Definition: event_logger.h:319
uint32_t record_counter_total
イベント記録数
Definition: event_logger.h:318
uint16_t log_capacity
イベントテーブルのキャパシティ(サイズ)
Definition: event_logger.h:331
EventHandler のInfo構造体
EH_ExecSettings exec_settings
実行時設定
EH_ElEventCounter el_event_counter
EH_ElEventCounter
EH_RegisterFromCmd reg_from_cmd
コマンド経由で EH_Rule を登録するときに使う内部状態変数
EH_RuleTable rule_table
EH_Rule のテーブル
EH_LogTable log_table
EH 対応ログテーブル
EH_RuleSortedIndex sorted_idxes[EH_RULE_MAX]
rules の二分探索用 idx
EH_ExecInfo exec_info
実行時情報
EH_TlmInfo tlm_info
tlmのための情報
EL_EventStatistics statistics
統計情報
Definition: event_logger.h:394
EL_TimeSeriesLog tlogs[EL_ERROR_LEVEL_MAX]
Definition: event_logger.h:388
OBCの時刻情報を保持する構造体
Definition: obc_time.h:18
cycle_t TMGR_get_master_total_cycle(void)
現在の total_cycle を返す
Definition: time_manager.c:97