C2A_Core
command_analyze.c
[詳解]
1 #pragma section REPRO
6 #include "command_analyze.h"
9 #include "../Library/print.h"
10  #include "../System/EventManager/event_logger.h"
11 #include <string.h>
12 
18 typedef enum
19 {
23 
31 static CA_PARAM_SIZE_TYPE CA_get_param_size_type_(CMD_CODE cmd_code, uint8_t n);
32 
35 
36 
37 void CA_initialize(void)
38 {
39  int i;
40 
42  {
43  Printf("CA: init error!!!\n");
44  return;
45  }
46 
47  memset(&command_analyze_, 0x00, sizeof(CommandAnalyze));
48  for (i = 0; i < CA_MAX_CMDS; ++i)
49  {
51  }
52 
54 }
55 
57 {
58  CMD_CODE cmd_code = CCP_get_id(packet);
59  CCP_CmdRet (*cmd_func)(const CommonCmdPacket*) = NULL;
60 
61  if (cmd_code >= CA_MAX_CMDS)
62  {
66  (uint32_t)cmd_code);
68  }
69 
70  cmd_func = command_analyze->cmd_table[cmd_code].cmd_func;
71 
72  if (cmd_func != NULL)
73  {
74  // ここで最低限のパラメタ長チェックをするが, bct_id_t など,内部定義を使っているものは各コマンド内部でもアサーションすること
75  uint16_t param_len = CCP_get_param_len(packet);
76  if (CA_ckeck_cmd_param_len(cmd_code, param_len) != CA_ACK_OK)
77  {
78  return CCP_make_cmd_ret(CCP_EXEC_ILLEGAL_LENGTH, (uint32_t)cmd_code);
79  }
80 
81  return cmd_func(packet);
82  }
83  else
84  {
88  (uint32_t)cmd_code);
89  return CCP_make_cmd_ret(CCP_EXEC_CMD_NOT_DEFINED, (uint32_t)cmd_code);
90  }
91 }
92 
93 uint8_t CA_get_cmd_param_num(CMD_CODE cmd_code)
94 {
95  uint8_t num;
96  if (cmd_code >= CA_MAX_CMDS) return 0;
97 
98  for (num = 0; num < CA_MAX_CMD_PARAM_NUM; ++num)
99  {
100  if (CA_get_param_size_type_(cmd_code, num) == CA_PARAM_SIZE_TYPE_NONE)
101  {
102  return num;
103  }
104  }
105  return CA_MAX_CMD_PARAM_NUM;
106 }
107 
108 uint8_t CA_get_cmd_param_size(CMD_CODE cmd_code, uint8_t n)
109 {
110  switch (CA_get_param_size_type_(cmd_code, n))
111  {
114  return 0;
116  return 1;
117  break;
119  return 2;
120  break;
122  return 4;
123  break;
125  return 8;
126  break;
127  default:
128  return 0; // 不正
129  }
130 }
131 
133 {
134  uint8_t i;
135  uint16_t min_len = 0;
136 
137  for (i = 0; i < CA_MAX_CMD_PARAM_NUM; ++i)
138  {
139  uint8_t param_size = CA_get_cmd_param_size(cmd_code, i);
140  if (param_size == 0) return min_len;
141  min_len += param_size;
142  }
143  return min_len;
144 }
145 
146 CA_ACK CA_ckeck_cmd_param_len(CMD_CODE cmd_code, uint16_t param_len)
147 {
148  if (cmd_code >= CA_MAX_CMDS) return CA_ACK_ERR;
149 
150  if (CA_has_raw_param(cmd_code))
151  {
152  if (param_len < CA_get_cmd_param_min_len(cmd_code) || param_len > CCP_get_max_param_len())
153  {
154  return CA_ACK_ERR;
155  }
156  return CA_ACK_OK;
157  }
158  else
159  {
160  return (CA_get_cmd_param_min_len(cmd_code) == param_len) ? CA_ACK_OK : CA_ACK_ERR;
161  }
162 }
163 
165 {
166  uint8_t param_num = CA_get_cmd_param_num(cmd_code);
167  if (param_num == 0) return 0;
168 
169  return (CA_get_param_size_type_(cmd_code, (uint8_t)(param_num - 1)) == CA_PARAM_SIZE_TYPE_RAW) ? 1 : 0;
170 }
171 
173 {
175  if (cmd_code >= CA_MAX_CMDS) return CA_PARAM_SIZE_TYPE_NONE;
176  if (n % 2)
177  {
179  }
180  else
181  {
183  }
184 }
185 
187 {
188  (void)packet;
189  CA_initialize();
191 }
192 
194 {
195  uint8_t param_size_infos[(CA_MAX_CMD_PARAM_NUM + 1) / 2];
196  CMD_CODE cmd_code = (CMD_CODE)CCP_get_param_from_packet(packet, 0, uint16_t);
197  uint32_t cmd_func = CCP_get_param_from_packet(packet, 1, uint32_t);
198  uint16_t ret;
199  uint8_t i;
200 
201  // raw パラメタなので,引数長チェック
202  if (CCP_get_param_len(packet) != 6 + sizeof(param_size_infos)) return CCP_make_cmd_ret_without_err_code(CCP_EXEC_ILLEGAL_LENGTH);
203 
204  ret = CCP_get_raw_param_from_packet(packet, param_size_infos, sizeof(param_size_infos));
205  if (ret != sizeof(param_size_infos)) return CCP_make_cmd_ret_without_err_code(CCP_EXEC_ILLEGAL_LENGTH);
206 
207  if (cmd_code >= CA_MAX_CMDS)
208  {
209  // 登録指定位置がコマンド数上限を超えている場合は異常判定
211  }
212 
213  // ローレベルコマンドなので,アサーションしない
214  command_analyze_.cmd_table[cmd_code].cmd_func = (CCP_CmdRet (*)(const CommonCmdPacket*))cmd_func;
215  for (i = 0; i < sizeof(param_size_infos); ++i)
216  {
217  command_analyze_.cmd_table[cmd_code].param_size_infos[i].packed_info.bit.first = ( param_size_infos[i] & 0xf0 ) >> 4;
218  command_analyze_.cmd_table[cmd_code].param_size_infos[i].packed_info.bit.second = param_size_infos[i] & 0x0f;
219  }
220 
222 }
223 
225 {
226  uint8_t page = CCP_get_param_from_packet(packet, 0, uint8_t);
227 
228  if (page >= CA_TLM_PAGE_MAX)
229  {
230  // ページ番号がコマンドテーブル範囲外
232  }
233 
236 }
237 
238 #pragma section
static CommandAnalyze command_analyze_
uint8_t CA_get_cmd_param_num(CMD_CODE cmd_code)
コマンドパラメタ数を取得する
CA_EL_LOCAL_ID
@ CA_EL_LOCAL_ID_ILLEGAL_CMD_CODE
不正な CMD_CODE を指定された場合
@ CA_EL_LOCAL_ID_NULL_CMD_CODE
未登録な CMD_CODE を指定された場合
CCP_CmdRet Cmd_CA_SET_PAGE_FOR_TLM(const CommonCmdPacket *packet)
uint8_t CA_get_cmd_param_size(CMD_CODE cmd_code, uint8_t n)
コマンドパラメタサイズを取得する
CCP_CmdRet Cmd_CA_INIT(const CommonCmdPacket *packet)
int CA_has_raw_param(CMD_CODE cmd_code)
RAW パラメタを持っているか?
const CommandAnalyze *const command_analyze
static CA_PARAM_SIZE_TYPE CA_get_param_size_type_(CMD_CODE cmd_code, uint8_t n)
コマンドパラメタのサイズ情報を取得
CCP_CmdRet Cmd_CA_REGISTER_CMD(const CommonCmdPacket *packet)
uint16_t CA_get_cmd_param_min_len(CMD_CODE cmd_code)
最小コマンドパラメタ長を取得する
CCP_CmdRet CA_execute_cmd(const CommonCmdPacket *packet)
コマンド実行の本体
void CA_initialize(void)
CA の初期化
CA_ACK CA_ckeck_cmd_param_len(CMD_CODE cmd_code, uint16_t param_len)
コマンドパラメタ長をチェックする
コマンドの実行・登録,コマンド関連処理
#define CA_MAX_CMD_PARAM_NUM
コマンドパラメタ(引数)の最大数.現時点ではユーザー側で可変にすることを想定してはない
#define CA_TLM_PAGE_MAX
コマンドテーブルページ数(ページネーション用)
CA_PARAM_SIZE_TYPE
コマンドパラメタサイズ
@ CA_PARAM_SIZE_TYPE_8BYTE
8 byte
@ CA_PARAM_SIZE_TYPE_RAW
RAW パラメタ
@ CA_PARAM_SIZE_TYPE_2BYTE
2 byte
@ CA_PARAM_SIZE_TYPE_NONE
パラメタなし
@ CA_PARAM_SIZE_TYPE_1BYTE
1 byte
@ CA_PARAM_SIZE_TYPE_4BYTE
4 byte
#define CA_MAX_CMDS
コマンドテーブルサイズ.すなわち登録できる最大コマンド数
void CA_load_cmd_table(CA_CmdInfo cmd_table[CA_MAX_CMDS])
Cmd Tableのロード
CA_ACK
@ CA_ACK_ERR
エラー
@ CA_ACK_OK
正常終了
コマンド定義
@ Cmd_CODE_MAX
uint16_t CCP_get_max_param_len(void)
CMD パラメタ長の最大値を取得
@ CCP_EXEC_SUCCESS
@ CCP_EXEC_ILLEGAL_LENGTH
コマンド実行時のコマンド引数長エラー
@ CCP_EXEC_ILLEGAL_PARAMETER
コマンド実行時のパラメタエラー
@ CCP_EXEC_CMD_NOT_DEFINED
CA_execute_cmd で用いる
CMD_CODE CCP_get_id(const CommonCmdPacket *packet)
CMD ID を取得
uint16_t CCP_get_param_len(const CommonCmdPacket *packet)
CMD パラメタ長を取得
CCP_CmdRet CCP_make_cmd_ret(CCP_EXEC_STS exec_sts, uint32_t err_code)
コマンド返り値である CCP_CmdRet を作成
CCP_CmdRet CCP_make_cmd_ret_without_err_code(CCP_EXEC_STS exec_sts)
コマンド返り値である CCP_CmdRet を作成(エラーコード不使用版)
uint16_t CCP_get_raw_param_from_packet(const CommonCmdPacket *packet, void *dest, uint16_t max_copy_len)
CCP packet から,RAW コマンド引数を取得する
CCP の汎用 Utility
#define CCP_get_param_from_packet(packet, n, type)
CCP packet から,n番目のコマンド引数を取得する
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
@ EL_CORE_GROUP_COMMAND_ANALYZE
Definition: event_logger.h:217
@ EL_ERROR_LEVEL_LOW
Definition: event_logger.h:266
EL_GROUP
event_logger の Event Group の user 定義部分
void Printf(const char *format,...)
Definition: print.c:9
CCP_CmdRet(* cmd_func)(const CommonCmdPacket *)
コマンドとなる関数
CA_PackedParamSizeInfo param_size_infos[(CA_MAX_CMD_PARAM_NUM+1)/2]
パラメタサイズ情報
union CA_PackedParamSizeInfo::@19 packed_info
struct CA_PackedParamSizeInfo::@19::@20 bit
コマンド返り値
Space Packet (コマンド用)
CommandAnalyze の Info 構造体
uint8_t tlm_page_no
テレメで使うページ数
CA_CmdInfo cmd_table[CA_MAX_CMDS]
コマンドテーブル