From 0b2dcba3768bbb3e61cab01bac7452a8a49537a1 Mon Sep 17 00:00:00 2001 From: mdlewisfb Date: Mon, 22 Oct 2018 20:35:59 -0700 Subject: [PATCH 1/3] Copying host software from OCWare repo. --- firmware/host/Makefile | 44 + firmware/host/bin/occli | Bin 0 -> 92248 bytes firmware/host/bin/occmd | 1 + firmware/host/bin/ocmw_eth | Bin 0 -> 160296 bytes firmware/host/bin/ocmw_eth_stub | Bin 0 -> 160376 bytes firmware/host/bin/ocmw_uart | Bin 0 -> 160168 bytes firmware/host/bin/ocmw_usb | Bin 0 -> 160168 bytes firmware/host/bin/ocware_stub | Bin 0 -> 87632 bytes firmware/host/include/logger.h | 59 + firmware/host/include/occli_common.h | 191 +++ firmware/host/include/ocmw_core.h | 68 + firmware/host/include/ocmw_eth_comm.h | 55 + firmware/host/include/ocmw_helper.h | 183 +++ firmware/host/include/ocmw_msgproc.h | 17 + firmware/host/include/ocmw_occli_comm.h | 128 ++ firmware/host/include/ocmw_schema.h | 52 + firmware/host/include/ocmw_socket_comm.h | 42 + firmware/host/include/ocmw_uart_comm.h | 59 + firmware/host/include/ocware_stub_eth_comm.h | 16 + .../host/include/ocware_stub_main_module.h | 266 ++++ firmware/host/include/ocwdg_daemon.h | 30 + firmware/host/include/postframe.h | 23 + firmware/host/include/util.h | 19 + firmware/host/log.txt | 67 + firmware/host/occli/occli_helpMenu.c | 460 +++++++ firmware/host/occli/occli_main.c | 860 ++++++++++++ firmware/host/occli/occli_ocmw_comm.c | 192 +++ firmware/host/ocmw/ocmw_clicmd.c | 1216 +++++++++++++++++ firmware/host/ocmw/ocmw_core.c | 818 +++++++++++ firmware/host/ocmw/ocmw_eth_comm.c | 236 ++++ firmware/host/ocmw/ocmw_helper.c | 156 +++ firmware/host/ocmw/ocmw_main.c | 94 ++ firmware/host/ocmw/ocmw_msgproc.c | 43 + firmware/host/ocmw/ocmw_occli_comm.c | 185 +++ firmware/host/ocmw/ocmw_schema.c | 1104 +++++++++++++++ firmware/host/ocmw/ocmw_uart_comm.c | 312 +++++ firmware/host/ocwarestub/get_params_stub.sh | 390 ++++++ .../host/ocwarestub/ocware_stub_database.c | 1117 +++++++++++++++ .../host/ocwarestub/ocware_stub_eth_comm.c | 135 ++ .../host/ocwarestub/ocware_stub_main_module.c | 204 +++ .../ocwarestub/ocware_stub_parse_message.c | 124 ++ firmware/host/ocwarestub/test_all_stub.sh | 73 + firmware/host/ocwdg/ocwdg_daemon.c | 121 ++ firmware/host/ocwdg/ocwdg_daemon.conf | 20 + .../scripts/autoTest/oc_pmic_i2c0_read.sh | 29 + .../scripts/autoTest/oc_pmic_tsensor_read.sh | 18 + .../host/scripts/autoTest/oc_smb_ddr3_read.sh | 27 + .../scripts/autoTest/oc_smb_tsensor_read.sh | 25 + firmware/host/scripts/get_params.sh | 849 ++++++++++++ firmware/host/scripts/set_config_params.sh | 198 +++ firmware/host/scripts/test_all.sh | 85 ++ firmware/host/util/logger.c | 35 + firmware/host/util/util.c | 29 + 53 files changed, 10475 insertions(+) create mode 100644 firmware/host/Makefile create mode 100755 firmware/host/bin/occli create mode 120000 firmware/host/bin/occmd create mode 100755 firmware/host/bin/ocmw_eth create mode 100755 firmware/host/bin/ocmw_eth_stub create mode 100755 firmware/host/bin/ocmw_uart create mode 100755 firmware/host/bin/ocmw_usb create mode 100755 firmware/host/bin/ocware_stub create mode 100644 firmware/host/include/logger.h create mode 100644 firmware/host/include/occli_common.h create mode 100644 firmware/host/include/ocmw_core.h create mode 100644 firmware/host/include/ocmw_eth_comm.h create mode 100644 firmware/host/include/ocmw_helper.h create mode 100755 firmware/host/include/ocmw_msgproc.h create mode 100644 firmware/host/include/ocmw_occli_comm.h create mode 100644 firmware/host/include/ocmw_schema.h create mode 100644 firmware/host/include/ocmw_socket_comm.h create mode 100644 firmware/host/include/ocmw_uart_comm.h create mode 100755 firmware/host/include/ocware_stub_eth_comm.h create mode 100755 firmware/host/include/ocware_stub_main_module.h create mode 100644 firmware/host/include/ocwdg_daemon.h create mode 100644 firmware/host/include/postframe.h create mode 100644 firmware/host/include/util.h create mode 100644 firmware/host/log.txt create mode 100644 firmware/host/occli/occli_helpMenu.c create mode 100644 firmware/host/occli/occli_main.c create mode 100644 firmware/host/occli/occli_ocmw_comm.c create mode 100644 firmware/host/ocmw/ocmw_clicmd.c create mode 100644 firmware/host/ocmw/ocmw_core.c create mode 100644 firmware/host/ocmw/ocmw_eth_comm.c create mode 100644 firmware/host/ocmw/ocmw_helper.c create mode 100644 firmware/host/ocmw/ocmw_main.c create mode 100755 firmware/host/ocmw/ocmw_msgproc.c create mode 100644 firmware/host/ocmw/ocmw_occli_comm.c create mode 100644 firmware/host/ocmw/ocmw_schema.c create mode 100644 firmware/host/ocmw/ocmw_uart_comm.c create mode 100755 firmware/host/ocwarestub/get_params_stub.sh create mode 100755 firmware/host/ocwarestub/ocware_stub_database.c create mode 100755 firmware/host/ocwarestub/ocware_stub_eth_comm.c create mode 100755 firmware/host/ocwarestub/ocware_stub_main_module.c create mode 100755 firmware/host/ocwarestub/ocware_stub_parse_message.c create mode 100755 firmware/host/ocwarestub/test_all_stub.sh create mode 100644 firmware/host/ocwdg/ocwdg_daemon.c create mode 100644 firmware/host/ocwdg/ocwdg_daemon.conf create mode 100755 firmware/host/scripts/autoTest/oc_pmic_i2c0_read.sh create mode 100755 firmware/host/scripts/autoTest/oc_pmic_tsensor_read.sh create mode 100755 firmware/host/scripts/autoTest/oc_smb_ddr3_read.sh create mode 100755 firmware/host/scripts/autoTest/oc_smb_tsensor_read.sh create mode 100755 firmware/host/scripts/get_params.sh create mode 100755 firmware/host/scripts/set_config_params.sh create mode 100755 firmware/host/scripts/test_all.sh create mode 100644 firmware/host/util/logger.c create mode 100644 firmware/host/util/util.c diff --git a/firmware/host/Makefile b/firmware/host/Makefile new file mode 100644 index 0000000000..556fdc9f91 --- /dev/null +++ b/firmware/host/Makefile @@ -0,0 +1,44 @@ + +#Makefile for ocmw and cli + +CC=gcc +CFLAGS= -I./ocwdg -I./include -I./../ec -I./../ec/common -I./../ec/platform/oc-sdr/schema -I./../ec/common/inc/global -Wall -Werror -g -fshort-enums +LIBS = -lpthread -ledit -lm -lrt +src_ocmw = $(wildcard ocmw/*.c) $(wildcard ocwdg/*.c) $(wildcard util/*.c) $(wildcard ../ec/platform/oc-sdr/schema/*.c) +src_occli = $(wildcard occli/*.c) $(wildcard util/*.c) $(wildcard ../ec/platform/oc-sdr/schema/*.c) +src_ocware_stub = $(wildcard ocwarestub/*.c) $(wildcard ../ec/platform/oc-sdr/schema/*.c) +output_dir = bin + +# --- Build binary and executable files + +default: + @mkdir -p $(output_dir) + make all + +all: ocmw_uart ocmw_usb ocmw_eth occli ocmw_eth_stub ocware_stub + +.PHONY: occli + +ocmw_uart: $(OBJECTS) + $(CC) $(src_ocmw) -o $(output_dir)/ocmw_uart $(LIBS) $(CFLAGS) -DOCWARE_HOST + +ocmw_usb: $(OBJECTS) + $(CC) $(src_ocmw) -o $(output_dir)/ocmw_usb $(LIBS) $(CFLAGS) -DINTERFACE_USB -DOCWARE_HOST + +ocmw_eth: $(OBJECTS) + $(CC) $(src_ocmw) -o $(output_dir)/ocmw_eth $(LIBS) $(CFLAGS) -DINTERFACE_ETHERNET -DOCWARE_HOST + +ocmw_eth_stub: $(OBJECTS) + $(CC) $(src_ocmw) -o $(output_dir)/ocmw_eth_stub $(LIBS) $(CFLAGS) -DINTERFACE_STUB_EC -DOCWARE_HOST + +ocware_stub: $(OBJECTS) + $(CC) $(src_ocware_stub) -o $(output_dir)/ocware_stub $(LIBS) $(CFLAGS) -DOCWARE_HOST + +occli: $(OBJECTS) + $(CC) $(src_occli) -o $(output_dir)/occli $(LIBS) $(CFLAGS) -DOCWARE_HOST + ln -sf occli $(output_dir)/occmd + + +# --- remove binary and executable files +clean: + rm -fr $(output_dir)/ocmw_eth_stub $(output_dir)/ocmw_eth $(output_dir)/ocmw_usb $(output_dir)/ocmw_uart $(output_dir)/occli $(output_dir)/ocware_stub diff --git a/firmware/host/bin/occli b/firmware/host/bin/occli new file mode 100755 index 0000000000000000000000000000000000000000..d3e6b012265a4a3c6d6a0d628c54392609b4e8f2 GIT binary patch literal 92248 zcmeFa31C#!**AV?CX=}tLNe?L2#oA5?1;GGutWxBNm&%vBqWm%&1N#gqJqH~HAa-! zYEe;8t5UaO-4JRLQ3+bLw6%)wXWP8KE|X%FYHMk$=KuRW=iJH6kO73WZ~x!dQSN!3 z=RD`x&U4N^=giHWYqRE@W4GB1>ti>j8pNu5`GlmdhOr^1gU4q~F;WblG1M4hB!epn z|13VAhOF{{Zf2Dxc=>VQAKOi_6JzOP5h;%o%rLCd($3PU>r~;>m?~EW6>61+;S~bg z(bn*4K~d%kV3nKaDY~yxl~y~N$9BdVO<$9%0A23ahFPWMAARG$McThbb{{a}J{HDI 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.a4Ib*WPh5&aEN(FX(hHrDZ1R{x8chHY)o3{5 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 literal 0 HcmV?d00001 diff --git a/firmware/host/bin/occmd b/firmware/host/bin/occmd new file mode 120000 index 0000000000..4aeebb9d64 --- /dev/null +++ b/firmware/host/bin/occmd @@ -0,0 +1 @@ +occli \ No newline at end of file diff --git a/firmware/host/bin/ocmw_eth b/firmware/host/bin/ocmw_eth new file mode 100755 index 0000000000000000000000000000000000000000..0f4cbc8d5727d4ed2ab98d2b190a5bff9a38badf GIT binary patch literal 160296 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%0DrL~OGTdM8a{zlUE)~b9TwlYLt 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�_BzlCHr2`Lb2gt%LyokGjxp$!KzP7 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

<4P-H>Ipp}Z5fI2^t46yC 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 literal 0 HcmV?d00001 diff --git a/firmware/host/include/logger.h b/firmware/host/include/logger.h new file mode 100644 index 0000000000..9a1142b163 --- /dev/null +++ b/firmware/host/include/logger.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef __LOGGER_H__ +#define __LOGGER_H__ + +#include +#include + +#define __filename__ (basename(__FILE__)) +#ifdef CONSOLE_LOG +#define logit(facility, fmt, ...) \ +{ \ + if(facility != LOG_DEBUG) \ + printf(fmt "\n", ##__VA_ARGS__); \ + else \ + printf ("[%s:%d, %s()]:" fmt "\n", __filename__, \ + __LINE__, __func__, ##__VA_ARGS__); \ +} + +#else /* syslog */ + +#define logit(facility, fmt, ...) \ +{ \ + if(facility != LOG_DEBUG) \ + syslog(facility, fmt "\n", ##__VA_ARGS__); \ + else \ + syslog(facility, " [%s:%d, %s()]: " fmt "\n", \ + __filename__, __LINE__, __func__, ##__VA_ARGS__); \ +} + +#endif + +#define logemerg(fmt, ...) logit(LOG_EMERG, " " fmt, ##__VA_ARGS__) +#define logalert(fmt, ...) logit(LOG_ALERT, " " fmt, ##__VA_ARGS__) +#define logcrit(fmt, ...) logit(LOG_CRIT, " " fmt, ##__VA_ARGS__) +#define logerr(fmt, ...) logit(LOG_ERR, " " fmt, ##__VA_ARGS__) +#define logwarn(fmt, ...) logit(LOG_WARNING, " " fmt, ##__VA_ARGS__) +#define lognotice(fmt, ...) logit(LOG_NOTICE, " " fmt, ##__VA_ARGS__) +#define loginfo(fmt, ...) logit(LOG_INFO, " " fmt, ##__VA_ARGS__) +#define logdebug(fmt, ...) logit(LOG_DEBUG, fmt, ##__VA_ARGS__) + +/* + * @param ident an input value (by pointer) + * + */ +void initlog(const char* ident); +/* + * deinitialize the logging routine + * + */ +void deinitlog(void); + +#endif /* __LOGGER_H__ */ diff --git a/firmware/host/include/occli_common.h b/firmware/host/include/occli_common.h new file mode 100644 index 0000000000..e6532403d6 --- /dev/null +++ b/firmware/host/include/occli_common.h @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCCLI_COMM_H_ +#define _OCCLI_COMM_H_ + +/* OC Inlucdes */ +#include +#include +#include + +#define HIT_FILE_BUFF_SIZE 50 +#define OCCLI_STRING_SIZE 128 +#define RES_STR_BUFF_SIZE 10000 +#define OCMP_MAX_SIZE 10 +#define OCCLI_CHAR_ARRAY_SIZE 30 +#define OCMW_MAX_SUBSYSTEM 11 +/* This timeout must be more than OCMW timeout */ +#define OCCLI_TIMEOUT_PERIOD 12 +#define FAILED -1 +#define SUCCESS 0 +#define OCCLI_SNPRINTF_MAX_LEN 200 +#define OCCLI_HELP_MAX_SIZE 400 + +typedef struct { + char option; + int sizeNum; + int totalStr; +}OCCLI_ARRAY_PARAM; + +typedef struct { + char subsystem[OCCLI_CHAR_ARRAY_SIZE]; + char component[OCCLI_CHAR_ARRAY_SIZE]; + char subcomponent[OCCLI_CHAR_ARRAY_SIZE]; + char msgtype[OCCLI_CHAR_ARRAY_SIZE]; + char parameter[OCCLI_CHAR_ARRAY_SIZE]; +}strMsgFrame; + +typedef struct { + int8_t subsystem; + int8_t component; + int8_t msgtype; + int16_t parameter; +}sMsgParam; + +typedef struct{ + char *subsystem; + char *component; + char *msgtype; + char *subcomponent; + char *parameter; +} OCCLI_STRING_MSG; + + +typedef struct { + int32_t totalNum; + struct name { + int32_t number; + char name[OCCLI_CHAR_ARRAY_SIZE]; + } Info[OCCLI_CHAR_ARRAY_SIZE]; +}subSystemInfo; + +//Help Menu structure +typedef struct { + char subSystem[OCMW_MAX_SUBSYSTEM_SIZE]; + char component[OCMW_HELP_FRAME_SIZE]; + char subComponent[OCMW_HELP_FRAME_SIZE]; + char msgType[OCMW_MAX_MSGTYPE_SIZE]; + char actionType[OCMW_MAX_ACTION_SIZE]; + char arguments[OCMW_HELP_FRAME_SIZE]; + char parameter[OCMW_HELP_FRAME_SIZE]; +}helpMenu; + +typedef struct { + char subsystem[OCCLI_CHAR_ARRAY_SIZE]; + char component[OCCLI_CHAR_ARRAY_SIZE]; + char subComponent[OCCLI_CHAR_ARRAY_SIZE]; +}commandFrame; +/* + + * Initialize the ocmw communication + */ +int32_t occli_init_comm(void); +/* + * Deinitialize the ocmw communication + */ +int8_t occli_deinit_comm(void); +/* + * @param cmd an input string (by pointer) + * @param cmdlen an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t occli_send_cmd_to_ocmw(const char *cmd, int32_t cmdlen); +/* + * @param resp an output value (by pointer) + * @param resplen an output value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t occli_recv_cmd_resp_from_ocmw(char *resp, int32_t resplen); +/* + * @param resp an output value (by pointer) + * @param resplen an output value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t occli_recv_alertmsg_from_ocmw(char *resp, int32_t resplen); +/* + * @param root an input value (by pointer) + * @param msgFrame an input value (by pointer) + * @param ecSendBuf an input value (by pointer) + * @param actiontype an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_parse_msgframe(const Component *root, strMsgFrame *msgFrame, + uint8_t actiontype,ocmwSchemaSendBuf *ecSendBuf); +/* + * @param root an output value (by pointer) + * @param dMsgFrameParam an output value (by pointer) + * @param ecReceivedMsg an output value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +void ocmw_deserialization_msgframe(const Component *root, + sMsgParam *dMsgFrameParam, + OCMPMessageFrame *ecReceivedMsg); +/* + * @param compBase an output value (by pointer) + * @param msgFrame an output value (by pointer) + * @param ecSendBuf an output value (by pointer) + * @param actiontype an output value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_parse_command_msgframe(const Component *compBase, + strMsgFrame *msgFrame, uint8_t actiontype, + ocmwSchemaSendBuf *ecSendBuf); +/* + * @param compBase an output value (by pointer) + * @param msgFrame an output value (by pointer) + * @param ecSendBuf an output value (by pointer) + * @param actiontype an output value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_parse_post_msgframe(const Component *compBase, + strMsgFrame *msgFrame, uint8_t actiontype, + ocmwSchemaSendBuf *ecSendBuf); +/* + * @param root an output value (by pointer) + * @param systemInfo an output value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_frame_subsystem_from_schema(const Component *root, + subSystemInfo *systemInfo); + +/* + * @param root an output value (by pointer) + * @param systemInfo an output value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_frame_postTable_from_schema(const Component *root); + +/* + * @param pointer to global memory + * + * @return NONE + */ +inline void ocmw_free_global_pointer(void **ptr); + +/* + * @param root an output value (by pointer) + * @param systemInfo an output value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int8_t occli_printHelpMenu(const Component *root,char *cmd); + +/*Display CLI window*/ +void occli_print_opencelluar(); + +#endif /* _OCCLI_COMM_H_ */ diff --git a/firmware/host/include/ocmw_core.h b/firmware/host/include/ocmw_core.h new file mode 100644 index 0000000000..e752fc559a --- /dev/null +++ b/firmware/host/include/ocmw_core.h @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCMW_CORE_H_ +#define _OCMW_CORE_H_ + +/* OC includes */ +#include + +sem_t semecMsgParser; +sem_t semCliReturn; +sem_t semCommandPost; + +/* This timeout must be less than CLI timeout */ +#define OCMW_SEM_WAIT_TIME 10 +#define OCMW_BUSY_WAIT_INDEX 0 +#define OCMW_TIMED_WAIT_INDEX 1 +#define PARAM_STR_MAX_BUFF_SIZE 100 + +int32_t ocmw_init(); +/* + * @param actionType an input enum value (by value) + * @param msgType an input enum value (by value) + * @param paramStr an input string (by pointer) + * @param interface an input enum value (by value) + * @param paramVal an input value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_msg_packetize_and_send(char * argv[], uint8_t actionType, + uint8_t msgType, const int8_t * paramStr, uint8_t interface, + void* paramVal); +/* + * Message parser module + * + */ +void ocmw_ec_msgparser(void); +/* + * Thread to parse the data coming from EC to AP through uart + * @param pthreadData an input value (by pointer) + */ +void * ocmw_thread_uartmsgparser(void *pthreadData); + +/* + * Thread to parse the data coming from EC to AP through ethernet + * @param pthreadData an input value (by pointer) + */ +void * ocmw_thread_ethmsgparser(void *pthreadData); +/* + * @param ecMsgFrame an input structure (by value) + * @param interface an input enum value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_send_msg(OCMPMessageFrame ecMsgFrame, uint8_t interface); +/* + * @param semId an input value (by pointer) + * @param semWaitType an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_sem_wait(sem_t *semId, int32_t semWaitType); +#endif /* _OCMW_CORE_H_ */ diff --git a/firmware/host/include/ocmw_eth_comm.h b/firmware/host/include/ocmw_eth_comm.h new file mode 100644 index 0000000000..815b2e9692 --- /dev/null +++ b/firmware/host/include/ocmw_eth_comm.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCCLI_IPC_COMM_H_ +#define _OCCLI_IPC_COMM_H_ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OCMW_EC_DEV 1 +#define OCMW_EC_STUB_DEV 2 + +/* + * Initialize the ocmw ethernet communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_init_eth_comm(int32_t sentDev); +/* + * Deinitialize the ocmw ethernet communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_deinit_eth_comm(int32_t sentDev); +/* + * @param cmd an input string (by pointer) + * @param cmdlen an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_send_eth_msgto_ec(const int8_t *cmd, int32_t cmdlen,int32_t sentDev); +/* + * @param resp an input value (by pointer) + * @param resplen an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_recv_eth_msgfrom_ec(int8_t *resp, int32_t resplen, int32_t sentDev); + +#endif /* _OCCLI_IPC_COMM_H_ */ diff --git a/firmware/host/include/ocmw_helper.h b/firmware/host/include/ocmw_helper.h new file mode 100644 index 0000000000..f9aad134ce --- /dev/null +++ b/firmware/host/include/ocmw_helper.h @@ -0,0 +1,183 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCMW_HELPER_H_ +#define _OCMW_HELPER_H_ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* OC includes */ +#include +#include + +#define Buf_PARAM_STRUCT_MAX_SIZE 16 +#define MAX_PARM_COUNT (OCMP_MSG_SIZE - (sizeof(OCMPMessage)\ + - sizeof(void *) + sizeof (OCMPHeader))) + +#define DEBUG_SUBSYSTEM_NBR 11 +#define DEBUG_I2C 3 +#define DEBUG_MDIO 8 + +#define PARAM_STR_BUFF_SIZE 100 +#define PARAM_TYPE_BUFF_SIZE 32 + +#define OCMW_MAX_SUBSYSTEM_SIZE 16 +#define OCMW_MAX_ACTION_SIZE 16 +#define OCMW_MAX_MSGTYPE_SIZE 16 +#define OCMW_COMMAND_BUFF_SIZE 20 +#define OCMW_POST_DESC_SIZE 24 +#define OCMW_HELP_FRAME_SIZE 40 +#define OCMW_POST_DEVICE_SIZE 40 +#define EEPROM_STATUS_MAX_SIZE 21 +#define EEPROM_SDR_STATUS_SIZE 19 +#define EEPROM_CONFIG_MAX_SIZE 14 +#define EEPROM_CONFIG_SIZE 18 +#define OCMW_MAX_POST_CODE_SIZE 100 +#define TEMP_STR_BUFF_SIZE 100 + + +typedef enum { + VOID = 0, + CHAR = 1, + UCHAR = 1, + SHORT = 2, + USHORT = 2, + INT = 4, + UINT = 4, + FLOAT = 4 +} DATA_TYPE; + +typedef enum { + FAILED = -1, + SUCCESS, + INVALID_POINTER, +} ocmw_db_ret; + +typedef struct { + int32_t paramindex; + int32_t paramval; +} bufParam; + +typedef struct { + int8_t msgType; + int8_t componentId; + int8_t subsystem; + int8_t actionType; + int16_t paramInfo; + int32_t numOfele; + int8_t pbuf[MAX_PARM_COUNT]; + int32_t paramSizebuf[MAX_PARM_COUNT]; +} ocmwSendRecvBuf; + +typedef struct { + int8_t subsystem; + int8_t componentId; + int8_t msgType; + int8_t actionType; + int16_t paramId; + int8_t paramPos; + int8_t paramSize; + char commandType[OCMW_COMMAND_BUFF_SIZE]; +} ocmwSchemaSendBuf; + +typedef struct __attribute__((packed, aligned(1))){ + uint8_t devsn; /* device serial Number */ + uint8_t subsystem; + char subsysName[OCMW_MAX_SUBSYSTEM_SIZE]; /* Subsystem Name */ + char deviceName[OCMW_POST_DEVICE_SIZE]; /* Device Name */ + uint8_t status; /* device status */ +}ocwarePostResultData; + +typedef struct { + unsigned int count; /* Device Status count */ + ocwarePostResultData results[OCMW_MAX_POST_CODE_SIZE]; /* Post result structure */ +} ocwarePostResults; + +typedef struct { + uint8_t msgtype; /* Post Message tyep */ + uint8_t replycode; /* Reply type */ + char desc[OCMW_POST_DESC_SIZE]; /* Device description */ +} ocwarePostReplyCode; + +/* + * @param sem an input value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_sem_wait_nointr(sem_t *sem); +/* + * @param sem an input value (by pointer) + * @param timeout an input value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_sem_timedwait_nointr(sem_t *sem, const struct timespec *timeout); +/* + * @param paramindex an input value (by value) + * @param paramSizebuf an input value (by pointer) + * @param dataSize an output value (by pointer) + * @param pos an output value (by pointer) + * + */ +void ocmw_dataparsing_from_db(int32_t paramIndex, int32_t *paramSizebuf, + int32_t *dataSize, int32_t *pos); +/* + * @param input an input buffer (by pointer) + * @param bufParamStruct an output buffer (by pointer) + * + */ +void ocmw_dataparsing_from_ec(ocmwSendRecvBuf *input, + bufParam * bufParamStruct); +/* + * @param uartInputBuf an input buffer (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_fill_inputstruct(ocmwSendRecvBuf *uartInputBuf); +/* + * @param ecInputData an input data (by value) + * + * @return true if function succeeds, false otherwise + */ +int8_t ocmw_parse_eepromdata_from_ec (ocmwSendRecvBuf ecInputData); +/* + * @param ecInputData an input data (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_parse_obc_from_ec(ocmwSendRecvBuf ecInputData); +/* + * @param ecInputData an input data (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_parse_testingmodule_from_ec(ocmwSendRecvBuf ecInputData); +/* + * @param msgaction an input value (by value) + * @param msgtype an input value (by value) + * @param paramstr an input string (by pointer) + * @param paramvalue an input value (by pointer) + * + */ +//int ocmw_msgproc_send_msg(int8_t msgaction, int8_t msgtype, + // const int8_t* paramstr, void* paramvalue); + +#endif /* _OCMW_HELPER_H_ */ diff --git a/firmware/host/include/ocmw_msgproc.h b/firmware/host/include/ocmw_msgproc.h new file mode 100755 index 0000000000..0bda2bb72d --- /dev/null +++ b/firmware/host/include/ocmw_msgproc.h @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCMW_MSGPROC_H_ +#define _OCMW_MSGPROC_H_ + +#include "ocmp_frame.h" + +int ocmw_msgproc_send_msg(char * argv[], uint8_t action, int8_t msgtype, + const int8_t* paramstr, void* paramvalue); + +#endif /* _OCMW_MSGPROC_H_ */ diff --git a/firmware/host/include/ocmw_occli_comm.h b/firmware/host/include/ocmw_occli_comm.h new file mode 100644 index 0000000000..5d5d2f0a21 --- /dev/null +++ b/firmware/host/include/ocmw_occli_comm.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCMW_IPC_COMM_H_ +#define _OCMW_IPC_COMM_H_ + +#include + +#define PARAMSTR_NUMBER_LEN 12 +#define TESTMOD_MAX_LEN 16 +#define RES_STR_BUFF_SIZE 10000 +#define TEMP_STR_BUFF_SIZE 100 +#define ALERT_STR_BUFF_SIZE 128 +#define CMD_STR_BUFF_SIZE 100 +#define OCMW_MAX_IMEI_SIZE 15 +#define OCMW_MAX_MSG_SIZE 20 + +typedef struct { + int8_t pin; + int8_t value; +}debugGPIOData; + +typedef struct { + uint16_t regAddress; + uint16_t regValue; +}debugMDIOData; + +typedef struct __attribute__((packed, aligned(1))){ + uint8_t slaveAddress; + uint8_t numOfBytes; + uint8_t regAddress; + uint16_t regValue; +}debugI2CData; + +typedef enum { + SET_STR, + GET_STR, + RESET_STR, + ENABLE_STR, + DISABLE_STR, + ACTIVE_STR, + ECHO_STR, + DISCONNECT_STR, + CONNECT_STR, + SEND_STR, + DIAL_STR, + ANSWER_STR, + HANGUP_STR, + ELOOPBK_STR, + DLOOPBK_STR, + EPKTGEN_STR, + DPKTGEN_STR, + MAX_STR +} ocmw_token_t; + +typedef enum { + HCI_STR, + DEBUG_STR, + RESULT_STR, + ENABLE_SET_STR, + GETSETMAX +} ocmw_setGet; + +/* + * Initialize the ocmw cli communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_init_occli_comm(void); + +/* + * Deinitialize the ocmw cli communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_deinit_occli_comm(void); +/* + * @param cmd an input string (by pointer) + * @param cmdlen an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_recv_clicmd_from_occli(char* cmdstr, int32_t cmdlen); +/* + * @param resp an input value (by pointer) + * @param resplen an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_send_clicmd_resp_to_occli(const char* resp, int32_t resplen); +/* + * @param cmdstr an input value (by pointer) + * @param response an output value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int ocmw_clicmd_handler(const char *cmdstr, char *response); +/* + * Initialize the ocmw alert communication + * + * @return true if function succeeds, false otherwise + */ +int32_t init_occli_alert_comm(); +/* + * Deinitialize the ocmw alert communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_deinit_occli_alert_comm(void); +/* + * @param buf an input value (by pointer) + * @param buflen an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_send_alert_to_occli(const char* buf, int32_t buflen); + +char ocmw_retrieve_post_results_count(ocwarePostResults *psData); + +char ocmw_retrieve_post_results(ocwarePostResults *psData); + +char ocmw_retrieve_reply_code_desc(ocwarePostReplyCode *replyCode); +#endif /* _OCMW_IPC_COMM_H_ */ diff --git a/firmware/host/include/ocmw_schema.h b/firmware/host/include/ocmw_schema.h new file mode 100644 index 0000000000..e9fe807a48 --- /dev/null +++ b/firmware/host/include/ocmw_schema.h @@ -0,0 +1,52 @@ +/* OC Includes */ +#include + +#ifndef _OCMW_SCHEMA_H_ +#define _OCMW_SCHEMA_H_ + +#define OCMW_VALUE_TYPE_UINT8 1 +#define OCMW_VALUE_TYPE_INT8 2 +#define OCMW_VALUE_TYPE_UINT16 3 +#define OCMW_VALUE_TYPE_INT16 6 +#define OCMW_VALUE_TYPE_UINT32 11 +#define OCMW_VALUE_TYPE_ENUM 9 +#define OCMW_VALUE_TYPE_MFG 10 +#define OCMW_VALUE_TYPE_MODEL 4 +#define OCMW_VALUE_TYPE_GETMODEL 5 +#define OCMW_VALUE_TYPE_STRUCT 7 +#define OCMW_VALUE_TYPE_NWOP_STRUCT 12 +#define IRIDIUM_LASTERR_ERROR_CODE_OFFSET 2 +#define TWO_G_SIM_NET_OPTR_STATUS_OFFSET 2 +#define BUF_SIZE 50 +#define ENUM_BUF_SIZE 30 +#define OCMW_VALUE_TYPE_COMPLEX 3 + +static const char *DATA_TYPE_MAP[] = { + [TYPE_NULL] = "NULL", + [TYPE_INT8] = "int8", + [TYPE_UINT8] = "uint8", + [TYPE_INT16] = "int16", + [TYPE_UINT16] = "uint16", + [TYPE_INT32] = "int32", + [TYPE_UINT32] = "uint32", + [TYPE_INT64] = "int64", + [TYPE_UINT64] = "uint64", + [TYPE_STR] = "string", + [TYPE_BOOL] = "bool", + [TYPE_ENUM] = "enum", +}; + +typedef enum ErrorSource { + ERR_RC_INTERNAL = 0, + ERR_SRC_CMS = 1, + ERR_SRC_CME = 2 +}Source; + +typedef enum OperatorStat { + TWOG_SIM_STAT_UNKNOWN = 0x00, + TWOG_SIM_STAT_AVAILABLE = 0x01, + TWOG_SIM_STAT_CURRENT = 0x02, + TWOG_SIM_STAT_FORBIDDEN = 0x03, +}eOperatorStat; +#endif /* _OCMW_SCHEMA_H_ */ + diff --git a/firmware/host/include/ocmw_socket_comm.h b/firmware/host/include/ocmw_socket_comm.h new file mode 100644 index 0000000000..9d9ae003dc --- /dev/null +++ b/firmware/host/include/ocmw_socket_comm.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCMW_SOCK_COMM_H_ +#define _OCMW_SOCK_COMM_H_ + +#define OCMW_SOCK_SERVER_IP ("127.0.0.1") +#define OCMW_SOCK_SERVER_PORT (5000) +#define OCMW_SOCK_SERVER_ALERT_PORT (6000) + +#define OCMW_SOCK_SERVER_CONN_COUNT (1) +#define OCMW_SOCK_SERVER_ALERT_CONN_COUNT (2) + +#define OCMW_SOCK_DOMAIN (AF_INET) +#define OCMW_SOCK_TYPE (SOCK_DGRAM) +#define OCMW_SOCK_PROTOCOL (IPPROTO_UDP) + +#define OCMW_SOCK_ALERT_SERVER_IP ("127.0.0.1") +#define OCMW_SOCK_ALERT_SERVER_PORT (6000) +#define OCMW_SOCK_ALERT_DOMAIN (AF_INET) +#define OCMW_SOCK_ALERT_TYPE (SOCK_DGRAM) +#define OCMW_SOCK_ALERT_PROTOCOL (IPPROTO_UDP) + +#define OCMW_ETH_SOCK_SERVER_IP ("192.168.1.2") +#define OCMW_ETH_SOCK_SERVER_PORT (1000) +#define OCMW_ETH_SOCK_DOMAIN (AF_INET) +#define OCMW_ETH_SOCK_TYPE (SOCK_STREAM) +#define OCMW_ETH_SOCK_PROTOCOL (IPPROTO_TCP) +#define OCMW_SOCKET_ERROR_SIZE 256 + + +#define OCMW_SOCK_STUB_SERVER_IP ("127.0.0.1") +#define OCMW_SOCK_STUB_SERVER_PORT (2000) +#define OCMW_SOCK_STUB_DOMAIN (AF_INET) +#define OCMW_SOCK_STUB_TYPE (SOCK_DGRAM) +#define OCMW_SOCK_STUB_PROTOCOL (IPPROTO_UDP) +#endif /* _OCMW_SOCK_COMM_H_ */ diff --git a/firmware/host/include/ocmw_uart_comm.h b/firmware/host/include/ocmw_uart_comm.h new file mode 100644 index 0000000000..135c9156d9 --- /dev/null +++ b/firmware/host/include/ocmw_uart_comm.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCMW_UART_COMM_H_ +#define _OCMW_UART_COMM_H_ + +#ifdef INTERFACE_USB +#define ECTTY "sudo find /dev/ -iname \"ttyACM*\" | tr -cd [:digit:]" +#else +#define ECTTY "/dev/ttyS4" +#endif +#define OCMP_MSG_SIZE (64) + +/* + * @param msgstr an input value (by pointer) + * @param msgsize an input value (by value) + * + * @return the function handler + */ +typedef void + (*handle_msg_from_ec_t)(const unsigned char* msgstr, int32_t msgsize); +/* + * @param msgstr an input value (by pointer) + * @param msgsize an input value (by value) + * + */ +void ocmw_ec_uart_msg_hndlr(const unsigned char* msgstr, int32_t msgsize); +/* + * Initialize the ocmw ec communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_init_ec_comm(handle_msg_from_ec_t msghndlr); +/* + * Deinitialize the ocmw ec communication + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_deinit_ec_comm(void); +/* + * @param msgstr an input value (by pointer) + * @param size an input value (by value) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_send_uart_msg_to_ec(const uint8_t* msgstr, int32_t size); +/* + * @param pathName an input value (by pointer) + * + * @return true if function succeeds, false otherwise + */ +int32_t ocmw_find_ttyacm_port(char *pathName); + +#endif /* _OCMW_UART_COMM_H_ */ diff --git a/firmware/host/include/ocware_stub_eth_comm.h b/firmware/host/include/ocware_stub_eth_comm.h new file mode 100755 index 0000000000..9b80152d5a --- /dev/null +++ b/firmware/host/include/ocware_stub_eth_comm.h @@ -0,0 +1,16 @@ +#ifndef _STUB_ETH_COMM_H_ +#define _STUB_ETH_COMM_H_ + +#include +#include +#include +#include + +#define OCMW_STUB_ETH_SOCK_DOMAIN (AF_INET) +#define OCMW_STUB_ETH_SOCK_TYPE (SOCK_DGRAM) +#define OCMW_STUB_ETH_SOCK_PROTOCOL (IPPROTO_UDP) +#define OCMW_STUB_ETH_SOCK_SERVER_PORT (2000) +#define OCMW_STUB_ETH_SOCK_SERVER_IP ("127.0.0.1") +#define OCWARE_STUB_ERR_STR_LEN (80) + +#endif /* _STUB_ETH_COMM_H_ */ diff --git a/firmware/host/include/ocware_stub_main_module.h b/firmware/host/include/ocware_stub_main_module.h new file mode 100755 index 0000000000..64e6254828 --- /dev/null +++ b/firmware/host/include/ocware_stub_main_module.h @@ -0,0 +1,266 @@ +#ifndef _OCMW_STUB_H_ +#define _OCMW_STUB_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define OC_EC_MSG_SIZE (64) +#define MAX_PAYLOAD_COUNT (OC_EC_MSG_SIZE - sizeof (OCMPHeader)) + +/* Max parameters to be stored in database */ +#define MAX_NUMBER_PARAM 400 +#define MAX_POST_DEVICE 400 +#define MAX_I2C_COMP_NBR 1 +#define MAX_GPIO_COMP_NBR 1 +#define MAX_MDIO_COMP_NBR 1 + +/* Default values in the database */ +#define DEFAULT_INT8 0x11 +#define DEFAULT_INT16 0x2222 +#define DEFAULT_INT32 0x33333333 +#define DEFAULT_INT64 0x4444444444444444 +#define DEFAULT_ENUM 0x05 +#define DEFAULT_STRING "stub" + +/* default values in the debug subsystem */ +#define I2C_SLAVE_ADDRESS 1 +#define I2C_NUM_BYTES 1 +#define I2C_REG_ADDRESS 1 +#define I2C_REG_VALUE 1 +#define GPIO_PIN_NBR 1 +#define GPIO_VALUE 1 + +/* size of strings and enum dataypes in schema */ +#define SIZE_OF_TYPE_REGISTRATION 1 +#define SIZE_OF_NWOP_STRUCT 3 +#define SIZE_OF_LAST_ERROR 3 +#define SIZE_OF_TYPE_MFG 10 +#define SIZE_OF_TYPE_GETMODEL 5 +#define SIZE_OF_TYPE_MODEL 4 +#define SIZE_OF_NWOP_STRUCT 3 +#define SIZE_OF_LAST_ERROR 3 +#define SIZE_OF_TYPE_OCSERIAL_INFO 18 +#define SIZE_OF_TYPE_GBCBOARD_INFO 18 +#define SIZE_OF_TYPE_MACADDR 13 + +/* Masking related defines */ +#define MASK_MSB 0xFF00 +#define MASK_LSB 0xFF +#define SHIFT_NIBBLE 8 + +typedef struct { + uint8_t subsystemId; + uint8_t componentId; + uint8_t msgtype; + uint16_t paramId; + uint8_t paramSize; + uint8_t paramPos; + uint8_t datatype; + void *data; +}OCWareStubDatabase; + +typedef struct{ + uint8_t SubsystemId; + uint8_t DeviceNumber; + ePostCode Status; +}OCWareStubPostData; + +typedef enum { + OCSTUB_VALUE_ZERO, + OCSTUB_VALUE_TYPE_MFG, + OCSTUB_VALUE_TYPE_GETMODEL, + OCSTUB_VALUE_TYPE_MODEL, + OCSTUB_VALUE_TYPE_REGISTRATION, + OCSTUB_VALUE_TYPE_NWOP_STRUCT, + OCSTUB_VALUE_TYPE_LAST_ERROR, + OCSTUB_VALUE_TYPE_OCSERIAL_INFO, + OCSTUB_VALUE_TYPE_GBCBOARD_INFO, + OCSTUB_VALUE_TYPE_I2C_DEBUG, + OCSTUB_VALUE_TYPE_GPIO_DEBUG, + OCSTUB_VALUE_TYPE_MDIO_DEBUG, +}OCWareStubsizeflag; + +typedef struct { + uint8_t slaveAddress; + uint8_t numOfBytes; + uint8_t regAddress; + uint16_t regValue; +}OCWareDebugI2Cinfo; + +typedef struct { + uint16_t regAddress; + uint16_t regValue; +}OCWareDebugMDIOinfo; + +typedef struct { + uint8_t pin_nbr; + uint8_t value; +}OCWareDebugGPIOinfo; + +typedef enum ocware_ret{ + STUB_FAILED = -1, + STUB_SUCCESS = 0 +}ocware_stub_ret; + + +extern int8_t debugGetCommand; +extern int8_t debugSetCommand; +extern int8_t PostResult; +extern int8_t PostEnable; + +/****************************************************************************** + * Function Name : ocware_stub_parse_post_get_message + * Description : Parse post messages from MW + * + * @param buffer - output pointer to the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_parse_post_get_message(char *buffer); + +/****************************************************************************** + * Function Name : ocware_stub_parse_command_message + * Description : Parse command messages from MW + * + * @param buffer - output pointer to the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_parse_command_message(char *buffer); + +/****************************************************************************** + * Function Name : ocware_stub_get_set_params + * Description : Function to check if GET/SET operation is to be performed + * + * @param msgFrameData - Pointer to the message frame field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_set_params(OCMPMessage *msgFrameData); +/****************************************************************************** + * Function Name : ocware_stub_init_database + * Description : Parse the schema and add entries in the DB + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_init_database(void); +/****************************************************************************** + * Function Name : ocware_stub_send_msgframe_middleware + * Description : send message to the MW + * + * @param bufferlen - length of the message (by value) + * @param buffer - pointer to the message to be sent to MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_send_msgframe_middleware(char **buffer, int32_t bufferlen); +/****************************************************************************** + * Function Name : ocware_stub_init_ethernet_comm + * Description : initialise the socket IPC + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_init_ethernet_comm(void); +/****************************************************************************** + * Function Name : ocware_stub_deinit_ethernet_comm + * Description : close the IPC socket + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_deinit_ethernet_comm(); +/****************************************************************************** + * Function Name : ocware_stub_recv_msgfrom_middleware + * Description : Receive message from MW + * + * @param bufferlen - length of the message (by value) + * @param buffer - pointer to the location where the message from MW is to be + * stored for further processing (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_recv_msgfrom_middleware(char **buffer, int32_t bufferlen); +/****************************************************************************** + * Function Name : ocware_stub_get_database + * Description : Function to retrieve data from the DB + * + * @param msgFrameData - Pointer to the message frame field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_database(OCMPMessage *msgFrameData); +/****************************************************************************** + * Function Name : ocware_stub_set_database + * Description : Function to modify data in the DB + * + * @param msgFrameData - Pointer to the message frame field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_set_database(OCMPMessage *msgFrameData); +/****************************************************************************** + * Function Name : ocware_stub_get_post_result_paramvalue_from_table + * Description : Fill payload with the post information + * + * @param message - output pointer to the message from MW + * @param payload - output pointer to the payload field of the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_post_result_paramvalue_from_table( + OCMPMessage *msgFrameData, + int8_t *payload); +/****************************************************************************** + * Function Name : ocware_stub_parse_debug_actiontype + * Description : Convert debug actiontype into the SET/GET + * + * @param msgFrameData - output pointer to the OCMPheader field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_parse_debug_actiontype(OCMPMessage *msgFrameData); +/****************************************************************************** + * Function Name : ocware_stub_get_post_database + * Description : extract device number and status from the post database + * depending on the subsytem id + * + * @param msgFrameData - output pointer to the OCMPheader field of the message + * from MW (by reference) + * @param payload - output pointer to the payload field of the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_post_database(OCMPMessage *msgFrameData, + char *payload); + +#endif /* __OCMW_STUB_H__ */ diff --git a/firmware/host/include/ocwdg_daemon.h b/firmware/host/include/ocwdg_daemon.h new file mode 100644 index 0000000000..f096fcffb2 --- /dev/null +++ b/firmware/host/include/ocwdg_daemon.h @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _OCWGD_DAEMON_H_ +#define _OCWGD_DAEMON_H_ + +/* OC includes */ +#include +#include +#include + +sem_t semEcWdgMsg; +/* + * Initialize the watchdog daemon + * + * @return true if function succeeds, false otherwise + */ +int32_t ocwdg_init(void); +/* + * @param pthreadData an input value (by pointer) + * + */ +void * ocwdg_thread_comm_with_ec(void *pthreadData); + +#endif /* _OCWGD_DAEMON_H_ */ diff --git a/firmware/host/include/postframe.h b/firmware/host/include/postframe.h new file mode 100644 index 0000000000..c193a798ba --- /dev/null +++ b/firmware/host/include/postframe.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _POST_H_ +#define _POST_H_ + +/* stdlib includes */ +#include +#include +#include +#include + +#define POST_MAIN_PAYLOAD_SIZE 3 +#define POST_MAIN_PAYLOAD_SUBSYSTEM_OFFSET 0 +#define POST_MAIN_PAYLOAD_DEVSN_OFFSET 1 +#define POST_MAIN_PAYLOAD_STATUS_OFFSET 2 + +#endif /* _POST_H_ */ diff --git a/firmware/host/include/util.h b/firmware/host/include/util.h new file mode 100644 index 0000000000..ccca883213 --- /dev/null +++ b/firmware/host/include/util.h @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#ifndef _UTIL_H_ +#define _UTIL_H_ + +/* + * @param buf an input value (by pointer) + * @param buflen an input value (by value) + * + */ +void hexdisp(const unsigned char* buf, int buflen); + +#endif /* _UTIL_H_ */ diff --git a/firmware/host/log.txt b/firmware/host/log.txt new file mode 100644 index 0000000000..92ead9277f --- /dev/null +++ b/firmware/host/log.txt @@ -0,0 +1,67 @@ +In file included from ./include/ocmw_schema.h:2:0, + from ocmw/ocmw_schema.c:1: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: +ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] + ecMsgFrame.message = ecCoreMsg; + ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ +In file included from ./include/ocmw_schema.h:2:0, + from ocmw/ocmw_schema.c:1: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: +ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] + ecMsgFrame.message = ecCoreMsg; + ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ +In file included from ./include/ocmw_schema.h:2:0, + from ocmw/ocmw_schema.c:1: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: +ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] + ecMsgFrame.message = ecCoreMsg; + ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ +In file included from occli/occli_ocmw_comm.c:26:0: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +In file included from occli/occli_main.c:24:0: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +In file included from occli/occli_helpMenu.c:4:0: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +In file included from ./include/ocmw_schema.h:2:0, + from ocmw/ocmw_schema.c:1: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: +ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] + ecMsgFrame.message = ecCoreMsg; + ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ +In file included from ./include/ocware_stub_main_module.h:16:0, + from ocwarestub/ocware_stub_database.c:10: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +In file included from ocwarestub/ocware_stub_parse_message.c:10:0: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +In file included from ./include/ocware_stub_main_module.h:16:0, + from ocwarestub/ocware_stub_main_module.c:9: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ +In file included from ./include/ocware_stub_main_module.h:16:0, + from ocwarestub/ocware_stub_eth_comm.c:2: +./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined + extern inline void ocmw_free_global_pointer(void **ptr); + ^~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/firmware/host/occli/occli_helpMenu.c b/firmware/host/occli/occli_helpMenu.c new file mode 100644 index 0000000000..3e797670a7 --- /dev/null +++ b/firmware/host/occli/occli_helpMenu.c @@ -0,0 +1,460 @@ +#include +#include +#include +#include + +/************************************************************************** + * Function Name : occli_print_opencelluar + * Description : This Function print Opencelluar at prompt + * Input(s) : + * Output(s) : + ***************************************************************************/ +void occli_print_opencelluar() +{ + printf("\nHELP Usage:\n\t\"subsystem --help\"" + " OR \"subsystem.component --help\""); + printf("\nEXIT:\n\t\"quit\""); + + printf("\nDisplay:\n\t\"Press Double TAB\""); + printf("\nClear Screen:\n\t\"Press CTRL + L \"\n\n"); + return; +} + +/************************************************************************** + * Function Name : occli_fill_data_from_param + * Description : This Function fill array data based on msgType + * Input(s) : param, helpMsgType, index + * Output(s) : index, helpMenuArray + ***************************************************************************/ +int8_t occli_fill_data_from_param(const Parameter *param, + helpMenu *helpMenuArray[], int32_t *index, char *helpMsgType) +{ + int32_t helpIndex = *index; + + if ((helpMenuArray == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + if (param && param->name) { + strncpy(helpMenuArray[helpIndex]->msgType, + helpMsgType,strlen(helpMsgType)); + if (strcmp(helpMsgType, "config") == 0) { + strncpy(helpMenuArray[helpIndex]->actionType, + "get/set", strlen("get/set")); + } else { + strncpy(helpMenuArray[helpIndex]->actionType, "get", strlen("get")); + } + do { + strncpy(helpMenuArray[helpIndex]->parameter, + param->name, strlen(param->name)); + param += 1; + helpIndex++; + } while (param && param->name); + *index = helpIndex; + } + return SUCCESS; +} + +/************************************************************************** + * Function Name : occli_fill_data_from_command + * Description : This Function fill array data for command + * Input(s) : command, index + * Output(s) : index, helpMenuArray + ***************************************************************************/ +int8_t occli_fill_data_from_command(const Command *command, + helpMenu *helpMenuArray[], int32_t *index, + char *subSysComp) +{ + int32_t helpIndex = *index; + + if ((helpMenuArray == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + if (command && command->name) { + strncpy(helpMenuArray[helpIndex]->msgType, + "command", strlen("command")); + while (command && command->name) { + strncpy(helpMenuArray[helpIndex]->actionType, + command->name, strlen(command->name)); + + if (strncmp(subSysComp, "debug", strlen("debug")) == 0) { + if (strstr(subSysComp, "I2C")) { + if (strcmp(command->name, "get") == 0) { + strcpy(helpMenuArray[helpIndex++]->arguments, + "Slave Address(Decimal)"); + strcpy(helpMenuArray[helpIndex++]->arguments, + "Number of Bytes(1/2)"); + strcpy(helpMenuArray[helpIndex++]->arguments, + "Register Address(Decimal)"); + } else { + strcpy(helpMenuArray[helpIndex++]->arguments, + "Slave Address(Decimal)"); + strcpy(helpMenuArray[helpIndex++]->arguments, + "Number of Bytes(1/2)"); + strcpy(helpMenuArray[helpIndex++]->arguments, + "Register Address(Decimal)"); + strcpy(helpMenuArray[helpIndex]->arguments, + "Register Data(Decimal)"); + } + } else { + if (strcmp(command->name, "get") == 0) { + strcpy(helpMenuArray[helpIndex++]->arguments, + "Pin Number"); + } else { + strcpy(helpMenuArray[helpIndex++]->arguments, + "Pin Number"); + strcpy(helpMenuArray[helpIndex]->arguments, + "Value(0/1)"); + } + } + } else if ((strncmp(subSysComp, "hci", strlen("hci")) == 0) && + (strcmp(command->name, "set") == 0)) { + strcpy(helpMenuArray[helpIndex++]->arguments, "Off/Red/Green"); + } + if (strcmp(command->name, "send") == 0) { + strcpy(helpMenuArray[helpIndex++]->arguments, "MSISDN Number"); + strcpy(helpMenuArray[helpIndex]->arguments, "Message"); + } else if (strcmp(command->name, "dial") == 0) { + strcpy(helpMenuArray[helpIndex]->arguments, "MSISDN Number"); + } + command += 1; + helpIndex++; + } + *index = helpIndex; + } + + return SUCCESS; +} + +/************************************************************************** + * Function Name : occli_fill_data_from_post + * Description : This Function fill array data for command + * Input(s) : post, index + * Output(s) : index, helpMenuArray + ***************************************************************************/ +int8_t occli_fill_data_from_post(const Post *post, + helpMenu *helpMenuArray[], int32_t *index, + char *subSysComp) +{ + int32_t helpIndex = *index; + + if ((helpMenuArray == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + if (post && post->name) { + strncpy(helpMenuArray[helpIndex]->msgType, + "post", strlen("post")); + while (post && post->name) { + strncpy(helpMenuArray[helpIndex]->actionType, + post->name, strlen(post->name)); + post += 1; + helpIndex++; + } + *index = helpIndex; + } + + return SUCCESS; +} + +/************************************************************************** + * Function Name : occli_fill_data_from_driver + * Description : This Function will fill array data from driver + * Input(s) : devDriver + * Output(s) : helpMenuArray, index + ***************************************************************************/ +int8_t occli_fill_data_from_driver(const Driver *devDriver, + helpMenu *helpMenuArray[], int32_t *index, char *subSysComp) +{ + const Parameter *param = NULL; + const Command *command = NULL; + const Post *post = NULL; + int8_t ret = FAILED; + + if ((helpMenuArray == NULL) || (devDriver == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + param = devDriver->config; + ret = occli_fill_data_from_param(param, helpMenuArray, index, "config"); + + param = devDriver->status; + ret = occli_fill_data_from_param(param, helpMenuArray, index, "status"); + + command = devDriver->commands; + ret = occli_fill_data_from_command(command, helpMenuArray, + index, subSysComp); + post = devDriver->post; + ret = occli_fill_data_from_post (post, helpMenuArray, + index, subSysComp); + return ret; +} + +/************************************************************************** + * Function Name : occli_printHelpMenu_on_console + * Description : This Function will print CLI help Menu + * Input(s) : helpMenuArray, index, subSystem + * Output(s) : NA + ***************************************************************************/ +void occli_printHelpMenu_on_console(helpMenu *helpMenuArray[], + int32_t index, char *subSystem) +{ + int32_t printIndex = 0; + + if ((strcmp(subSystem, "testmodule") == 0) || + (strcmp(subSystem, "hci") == 0)) { + /*Printing for testmodule and hci subSystem */ + printf("\nExample :\n"); + if (strcmp(subSystem, "testmodule") == 0) { + printf("testmodule.2gsim send 9789799425 hi\n"); + printf("testmodule.2gsim dial 9789799425\n"); + printf("testmodule.2gsim connect_nw\n\n"); + } else { + printf("hci.led set 1\n\n"); + } + + printf("----------------------------------------------------------" + "-------------------------------------------\n"); + printf("%-12s%-12s%-15s%-10s%-15s%-20s%-15s\n", + "Subsystem", "Component", "SubComponent", "MsgType", + "ActionType", "Parameter", "Arguments"); + printf("----------------------------------------------------------" + "-------------------------------------------\n"); + for(printIndex = 0; printIndex < index; printIndex++) { + printf("%-12s%-12s%-15s%-10s%-15s%-20s%-15s\n", + helpMenuArray[printIndex]->subSystem, + helpMenuArray[printIndex]->component, + helpMenuArray[printIndex]->subComponent, + helpMenuArray[printIndex]->msgType, + helpMenuArray[printIndex]->actionType, + helpMenuArray[printIndex]->parameter, + helpMenuArray[printIndex]->arguments); + } + printf("----------------------------------------------------------" + "-------------------------------------------\n"); + } else if (strcmp(subSystem, "debug") == 0) { + /*Printing for debug subSystem */ + printf("\nGet Example :\n"); + printf("debug.I2C.bus0 get 104 2 58\n"); + printf("debug.gbc.ioexpanderx70 get 1\n\n"); + printf("Set Example :\n"); + printf("debug.I2C.bus0 set 104 2 58 1\n"); + printf("debug.gbc.ioexpanderx70 set 1 0\n"); + printf("\n-------------------------------------------------------" + "----------------------------------------" + "---------\n"); + printf("%-15s%-15s%-15s%-15s%-15s%-20s\n", + "Subsystem", "Component", "SubComponent", "MsgType", + "ActionType", "Arguments"); + printf("-------------------------------------------------------" + "----------------------------------------" + "---------\n"); + for(printIndex = 0; printIndex < index; printIndex++) { + printf("%-15s%-15s%-15s%-15s%-15s%-20s\n", + helpMenuArray[printIndex]->subSystem, + helpMenuArray[printIndex]->component, + helpMenuArray[printIndex]->subComponent, + helpMenuArray[printIndex]->msgType, + helpMenuArray[printIndex]->actionType, + helpMenuArray[printIndex]->arguments); + } + printf("-------------------------------------------------------" + "----------------------------------------" + "---------\n"); + } else { + /*Printing for all othere subSystem */ + /* Dispalay of parameter default value and unit in help menu + * will be take care with common schema factory config + */ + printf("\n------------------------------------------------------------" + "----------------------------------\n"); + printf("%-12s%-17s%-18s%-12s%-12s%-23s\n", + "Subsystem", "Component", "SubComponent", "MsgType", + "ActionType", "Parameter"); + printf("\n------------------------------------------------------------" + "----------------------------------\n"); + for(printIndex = 0; printIndex < index; printIndex++) { + printf("%-12s%-17s%-18s%-12s%-12s%-23s\n", + helpMenuArray[printIndex]->subSystem, + helpMenuArray[printIndex]->component, + helpMenuArray[printIndex]->subComponent, + helpMenuArray[printIndex]->msgType, + helpMenuArray[printIndex]->actionType, + helpMenuArray[printIndex]->parameter); + } + printf("\n------------------------------------------------------------" + "----------------------------------\n"); + } +} + +/************************************************************************** + * Function Name : occli_free_helpMenupointer + * Description : This is an inline function to free memory + * Input(s) : helpMenuArray + * Output(s) : helpMenuArray + ***************************************************************************/ +inline void occli_free_helpMenupointer(helpMenu *helpMenuArray[]) +{ + int32_t mallocIndex = 0; + + for (mallocIndex = 0; mallocIndex < OCCLI_HELP_MAX_SIZE; mallocIndex++) { + if(helpMenuArray[mallocIndex]) + free(helpMenuArray[mallocIndex]); + } + + return; +} + +/************************************************************************** + * Function Name : occli_printHelpMenu + * Description : This Function will print CLI help Menu + * Input(s) : root, cmd + * Output(s) : NA + ***************************************************************************/ +int8_t occli_printHelpMenu(const Component *root, char *cmd) +{ + int32_t index = 0; + int32_t mallocIndex = 0; + const Component *subSystem = root; + const Component *component = NULL; + const Component *subComponent = NULL; + const Driver *devDriver = NULL; + const Command *command = NULL; + char *token = NULL; + char *cliStr = NULL; + char *cmdBkp = NULL; + char componentStr[OCCLI_CHAR_ARRAY_SIZE] = {0}; + char subSys[OCCLI_CHAR_ARRAY_SIZE] = {0}; + char subSysComp[OCCLI_CHAR_ARRAY_SIZE] = {0}; + int8_t ret = FAILED; + int8_t count = 1; + int8_t subCount = 0; + int8_t compCount = 0; + helpMenu *helpMenuArray[OCCLI_HELP_MAX_SIZE]; + + if ((subSystem == NULL) || (cmd == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + cmdBkp = (char *)malloc (sizeof(cmd)); + if (cmdBkp == NULL) { + logerr("Invalid Memory \n"); + return FAILED; + } + strcpy(cmdBkp,cmd); + + /* Tokenizing string for subsystem and component */ + cliStr = strtok(cmd, " "); + if ((cliStr == NULL) || (strstr(cliStr, "help"))) { + printf("%s : Error : Incorrect request\n", cmdBkp); + printf ("Usage : subsystem --help or subsystem.component --help\n"); + free(cmdBkp); + return FAILED; + } else { + token = strtok(cliStr, " ."); + strcpy(subSys, token); + while (token) { + token = strtok(NULL, " ."); + if (token == NULL) + break; + count++; + if (count > 2) { + printf("%s : Error : Incorrect request\n", cmdBkp); + printf ("Usage : subsystem --help" + " OR subsystem.component --help\n"); + free(cmdBkp); + return FAILED; + } + strcpy(componentStr, token); + } + } + for (mallocIndex = 0; mallocIndex < OCCLI_HELP_MAX_SIZE; mallocIndex++) { + helpMenuArray[mallocIndex] = (helpMenu *)malloc(sizeof(helpMenu)); + if (helpMenuArray[mallocIndex] == NULL) { + logerr("Invalid Memory \n"); + free(cmdBkp); + return FAILED; + } else { + memset(helpMenuArray[mallocIndex], '\0', sizeof(helpMenu)); + } + } + /* Parsing schema */ + while (subSystem && subSystem->name) { + if (strcmp(subSys, subSystem->name) == 0) { + subCount++; + strncpy((helpMenuArray[index++]->subSystem), + subSystem->name, strlen(subSystem->name)); + component = subSystem->components; + while (component && component->name) { + if ((count == 2)) { + if (strcmp(component->name, componentStr)) { + component += 1; + continue; + } else { + compCount++; + } + } + strncpy((helpMenuArray[index]->component), + component->name, strlen(component->name)); + sprintf(subSysComp, "%s.%s", subSystem->name, component->name); + command = component->commands; + ret = occli_fill_data_from_command(command, + helpMenuArray, &index, subSysComp); + devDriver = component->driver; + if (devDriver != NULL) { + ret = occli_fill_data_from_driver(devDriver, + helpMenuArray, &index, subSysComp); + if (ret == FAILED) { + logerr("\noccli_fill_data_from_driver Error"); + occli_free_helpMenupointer(helpMenuArray); + return ret; + } + } + index++; + subComponent = component->components; + while (subComponent && subComponent->name) { + strncpy((helpMenuArray[index]->subComponent), + subComponent->name, strlen(subComponent->name)); + command = subComponent->commands; + ret = occli_fill_data_from_command(command, + helpMenuArray, &index, subSysComp); + devDriver = subComponent->driver; + if (devDriver != NULL) { + ret = occli_fill_data_from_driver(devDriver, + helpMenuArray, &index, subSysComp); + if (ret == FAILED) { + logerr("\noccli_fill_data_from_driver Error"); + occli_free_helpMenupointer(helpMenuArray); + return ret; + } + } + index++; + subComponent += 1; + } + component += 1; + } + if ((count == 2) && (compCount == 0)) { + printf("%s : Error : Invalid Component\n", cmdBkp); + occli_free_helpMenupointer(helpMenuArray); + free(cmdBkp); + return FAILED; + } + } + subSystem += 1; + } + if (subCount == 0) { + printf("%s : Error : Invalid Subsystem\n", cmdBkp); + occli_free_helpMenupointer(helpMenuArray); + free(cmdBkp); + return FAILED; + } + occli_printHelpMenu_on_console(helpMenuArray, index, subSys); + occli_free_helpMenupointer(helpMenuArray); + free(cmdBkp); + return SUCCESS; +} diff --git a/firmware/host/occli/occli_main.c b/firmware/host/occli/occli_main.c new file mode 100644 index 0000000000..91b79087a9 --- /dev/null +++ b/firmware/host/occli/occli_main.c @@ -0,0 +1,860 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* sudo apt-get install libedit-dev : Install editline */ +#include + +/* OC includes */ +#include + +#define HISTORY ".occli_history" /* Saved under ${HOME} direcotory */ + +#define SWAP(s, e) do { \ + int32_t t; t = s; s = e; e = t; \ + } while (0) + +/* MAX_CLIENTRY represents the maximum entries which autofill can take */ +#define OCCLI_MAX_CLISTRING 1000 +#define OCCLI_MAX_SUBSTRING 75 +#define OCCLI_STRING_MAX_LEN 100 +#define OCCLI_CALC_SCHEMA_SIZE 1 +#define OCCLI_PARSE_SCHEMA 2 +#define MAX_ETHERNET_PORT 4 +#define OPENCELLULAR "opencellular# " + +extern char *rl_line_buffer; +static char *s_allParams[OCCLI_MAX_CLISTRING]; +static char *s_subSetParams[OCCLI_MAX_SUBSTRING]; +static char *s_strCli = NULL; +extern const Component sys_schema[]; + +/************************************************************************** + * Function Name : occli_trim_extra_spaces + * Description : This Function used to remove extra space inbetween + * words and trailing spaces from the string + * Input(s) : string + * Output(s) : string + ***************************************************************************/ +int8_t occli_trim_extra_spaces(char *string) +{ + int8_t length = 0; + char *end = NULL; + + if (string == NULL) { + logerr("Invalid memory location \n"); + return FAILED; + } + + /* Logic to remove trailing spaces */ + length = strlen(string); + end = string + length - 1; + + while(end >= string && isblank(*end)) { + end--; + } + + *(end + 1) = '\0'; + return SUCCESS; +} +/************************************************************************** + * Function Name : occli_copy_text + * Description : This Function Return a copy of the string entered + by the user in cli + * Input(s) : + * Output(s) : s_strCli + ***************************************************************************/ +static int8_t occli_copy_text () +{ + int8_t ret = FAILED; + int16_t length; + + if (isblank(rl_line_buffer[0])) { + printf("\nBlank Space is not allowed as the first character\n"); + printf("Please press ctrl+L to clear screen\n"); + return ret; + } + + length = rl_point; + s_strCli = (char*)realloc(s_strCli, length + 1); + + if (s_strCli == NULL) { + printf("\n ERROR: realloc"); + } else { + ret = SUCCESS; + strncpy (s_strCli, rl_line_buffer, length); + s_strCli[length] = '\0'; + } + + if (ret == SUCCESS) { + ret = occli_trim_extra_spaces(s_strCli); + } + + return ret; +} +/************************************************************************** + * Function Name : occli_init_subSetParams + * Description : This Function is used to allocate memory for + * subSetParams + * Input(s) : text + * Output(s) : + ***************************************************************************/ +static int8_t occli_init_subSetParams(const char *text) +{ + char *paramStr = NULL; + int32_t len = 0; + int16_t listIdx = 0; + int16_t subsetIdx = 0; + + if (text == NULL) { + logerr("Invalid memory location \n"); + return FAILED; + } + + if (s_subSetParams != NULL) { + for (listIdx = 0; (s_subSetParams[listIdx] != NULL && + listIdx < OCCLI_MAX_SUBSTRING) ; listIdx++) { + free(s_subSetParams[listIdx]); + s_subSetParams[listIdx] = NULL; + } + } + + len = strlen(text); + listIdx = 0; + while ((paramStr = s_allParams[listIdx])) { + if (strncmp(text, paramStr, len) == 0) { + subsetIdx++; + if(subsetIdx >= OCCLI_MAX_SUBSTRING) { + break; + } + } + listIdx++; + } + + for (listIdx= 0; listIdx < subsetIdx; listIdx++) { + s_subSetParams[listIdx] = (char *)calloc(1, OCCLI_STRING_MAX_LEN); + if ((s_subSetParams[listIdx]) == NULL) { + logerr("calloc error"); + return -ENOMEM; + } + } + + return SUCCESS; +} +/************************************************************************** + * Function Name : occli_all_param_generator + * Description : This Function used to generate the all param + * list + * Input(s) : text, state + * Output(s) : + ***************************************************************************/ +static char* occli_all_param_generator(const char* text, int32_t state) +{ + char *paramstr = NULL; + char *token = NULL; + char subStr[OCCLI_STRING_MAX_LEN] = {0}; + char tempStr[OCCLI_STRING_MAX_LEN] = {0}; + static int32_t s_listidx = 0; + static int32_t s_subSetIdx = 0; + static int32_t s_len = 0; + int8_t index = 0 ; + bool isEntryFound = false; + + if (text == NULL) { + logerr("Invalid memory location \n"); + rl_attempted_completion_over = 1; + return NULL; + } + + if (state == 0) { + s_listidx = 0; + s_subSetIdx = 0; + s_len = strlen(text); + if (occli_init_subSetParams(text) != SUCCESS) { + rl_attempted_completion_over = 1; + return NULL; + } + } + + while ((paramstr = s_allParams[s_listidx]) != NULL) { + isEntryFound = false; + s_listidx++; + if (strncmp(s_strCli, paramstr, s_len) == 0) { + strcpy(subStr, paramstr); + token = strtok(subStr + s_len, "."); + + memset(tempStr, 0, OCCLI_STRING_MAX_LEN); + rl_completion_append_character = '\0'; + if (token == NULL) { + /* + * case where the user has entered the complete string, + * autofill is not needed in this case , append a space + */ + sprintf(tempStr, "%s ", text); + } else { + /* Autofill will be needed in all cases here */ + if (strncmp(text, "", 1) == 0) { + /* case where the user hasn't entered any string */ + sprintf(tempStr, "%s", token); + } else if(strncmp(paramstr + s_len, "." , 1) == 0) { + /* + * case where the user has entered complete string + * for either subsystem/component (ie) "system" + */ + sprintf(tempStr, "%s.%s", text,token); + } else { + /* + * case where the user has entered subset of the string + * for example "sys" + */ + sprintf(tempStr, "%s%s", text,token); + } + } + /* + * The for loop below is to ensure that duplicate entries arent + * displayed in the cli + */ + for (index = 0; index < s_subSetIdx; index++) { + if (strcmp(s_subSetParams[index], tempStr) == 0) { + isEntryFound = true; + break; + } + } + if(isEntryFound != true) { + strcpy(s_subSetParams[s_subSetIdx], tempStr); + s_subSetIdx++; + return strdup(s_subSetParams[s_subSetIdx - 1]); + } + } + } + return NULL; +} +/************************************************************************** + * Function Name : occli_custom_completion + * Description : This Function used to handle the TAB operation + * Input(s) : text, start, end + * Output(s) : + ***************************************************************************/ +static char** occli_custom_completion(const char* text, int32_t start, + int32_t end) +{ + char** matches = NULL; + int8_t ret = FAILED; + + if (text == NULL) { + logerr("Invalid memory location \n"); + rl_attempted_completion_over = 1; + return NULL; + } + + ret = occli_copy_text(); + if (ret != SUCCESS) { + rl_attempted_completion_over = 1; + return NULL; + } + + if (start == 0) { + matches = rl_completion_matches(text, occli_all_param_generator); + } else { + rl_attempted_completion_over = 1; + } + + return matches; +} + +/************************************************************************** + * Function Name : occli_strjoin + * Description : This Function used to join the string + * Input(s) : srcstr, delimstr + * Output(s) : deststrPtr + ***************************************************************************/ +static int8_t occli_strjoin(char **deststrPtr, const char *srcstr, + const char *delimstr) +{ + char *tmp; + const int32_t alloclen = OCCLI_STRING_SIZE; + size_t destSize, deststrLen, srcstrLen, delimstrLen; + + if (deststrPtr == NULL || srcstr == NULL || delimstr == NULL) { + logerr("NULL pointer error"); + return -EFAULT; + } + + if (*deststrPtr == NULL) { + *deststrPtr = calloc(alloclen, sizeof(char)); + if (*deststrPtr == NULL) { + logerr("calloc error"); + return -ENOMEM; + } + deststrLen = strlen(*deststrPtr); + } else { + delimstrLen = strlen(delimstr); + srcstrLen = strlen(srcstr); + deststrLen = strlen(*deststrPtr); + destSize = ((deststrLen / alloclen) + 1) * alloclen; + + if ((srcstrLen + delimstrLen + 1) > (destSize - deststrLen)) { + /* allocate more memory to concatenate the srcstr */ + tmp = *deststrPtr; + *deststrPtr = realloc(*deststrPtr, destSize + alloclen); + if (*deststrPtr == NULL) { + logerr("realloc error"); + free(tmp); + return -ENOMEM; + } + } + } + + /* strcat the delimiting string to deststr, only when the deststr is not + an empty string */ + if (deststrLen > 0) { + strcat(*deststrPtr, delimstr); + } + /* strcat the new string */ + strcat(*deststrPtr, srcstr); + + logdebug("*deststrPtr='%s'", *deststrPtr); + + return SUCCESS; +} + +/************************************************************************** + * Function Name : occli_alertthread_messenger_to_ocmw + * Description : This Function is used to handle the alert message + * Input(s) : pThreadData + * Output(s) : + ***************************************************************************/ +void * occli_alertthread_messenger_to_ocmw(void *pThreadData) +{ + char response[RES_STR_BUFF_SIZE] = {0}; + int32_t ret = 0; + + /* Receive the CLI command execution response string from OCMW over UDP + * socket */ + + while (1) { + memset(response, 0, sizeof(response)); + ret = occli_recv_alertmsg_from_ocmw(response, sizeof(response)); + if (ret < 0) { + printf("occli_recv_alertmsg_from_ocmw failed: error value : %d\n", ret); + } else { + printf("%s\n", response); + } + } +} +/************************************************************************** + * Function Name : occli_parse_cliString + * Description : This Function is used to check the validity of the + * cli string + * Input(s) : cliString + * Output(s) : SUCCESS/FAILURE + ***************************************************************************/ +int8_t occli_parse_cliString(char *cliString) +{ + int8_t ret = FAILED; + int16_t index = 0; + char tempStr[OCCLI_STRING_MAX_LEN] = {0}; + char *token = NULL; + + strcpy(tempStr, cliString); + token = strtok(tempStr, " "); + + for(index = 0; ((index < OCCLI_MAX_CLISTRING) && + (s_allParams[index] != NULL)); index++) { + + if (strcmp(token, s_allParams[index]) == 0) { + ret = SUCCESS; + break; + } + } + + return ret; +} +/************************************************************************** + * Function Name : occli_frame_commands + * Description : This Function is used to frame the cli commands + * Input(s) : root, occliData->option + * Output(s) : s_allParams, occliData->totalStr, occliData->sizeNum + ***************************************************************************/ +int8_t occli_frame_commands(const Component *root, + OCCLI_ARRAY_PARAM *occliData) +{ + const Component *subSystem = root; + const Component *component = subSystem->components; + const Component *subComponent = NULL; + const Command *command = NULL; + const Driver *driver = NULL; + + + if ((root == NULL) || + (occliData == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + /* subsytem->component->command */ + subSystem = root; + while (subSystem && subSystem->name) { + component = subSystem->components; + while (component && component->name) { + command = component->commands; + while (command && + command->name) { + if (occliData->option == OCCLI_CALC_SCHEMA_SIZE) { + occliData->sizeNum += 1; + } else { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_SNPRINTF_MAX_LEN, "%s.%s.%s", + subSystem->name, component->name, command->name); + } + command += 1; + } + component += 1; + } + subSystem += 1; + } + + /* subsytem->component->driver->command */ + subSystem = root; + while (subSystem && subSystem->name) { + component = subSystem->components; + while (component && component->name) { + driver = component->driver; + if(driver != NULL) { + command = driver->commands; + while (command && + command->name) { + if (occliData->option == OCCLI_CALC_SCHEMA_SIZE) { + occliData->sizeNum += 1; + } else { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_SNPRINTF_MAX_LEN, "%s.%s.%s", + subSystem->name, component->name, + command->name); + } + command += 1; + } + } + component += 1; + } + subSystem += 1; + } + + /* subsytem->component->subComponent->driver->command */ + subSystem = root; + while (subSystem && subSystem->name) { + component = subSystem->components; + while (component && component->name) { + subComponent = component->components; + while (subComponent && subComponent->name) { + driver = subComponent->driver; + if(driver != NULL) { + command = driver->commands; + while (command && + command->name) { + if (occliData->option == OCCLI_CALC_SCHEMA_SIZE) { + occliData->sizeNum += 1; + } else { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_STRING_MAX_LEN, "%s.%s.%s.%s", + subSystem->name, component->name, + subComponent->name, command->name); + } + command += 1; + } + } + subComponent += 1; + } + component += 1; + } + subSystem += 1; + } + return SUCCESS; +} +/************************************************************************** + * Function Name : occli_frame_string_from_schemaDriver + * Description : This Function is used to frame the cli string + * Input(s) : param, strFrame, msgTypeStr + * Output(s) : ocmwclistr, occliData + ***************************************************************************/ +int8_t occli_frame_string_from_schemaDriver(const Parameter *param, + OCCLI_ARRAY_PARAM *occliData, + strMsgFrame *strFrame) +{ + if ((occliData == NULL) || (param == NULL) || (strFrame == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + if (occliData->option == OCCLI_CALC_SCHEMA_SIZE) { + occliData->sizeNum += 1; + } else { + if (strlen(strFrame->subcomponent)) { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_SNPRINTF_MAX_LEN, "%s.%s.%s.%s.%s.%s", + strFrame->subsystem, strFrame->component, + strFrame->msgtype, strFrame->subcomponent, + param->name, strFrame->parameter); + } else { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_SNPRINTF_MAX_LEN, "%s.%s.%s.%s.%s", + strFrame->subsystem, strFrame->component, + strFrame->msgtype, param->name, strFrame->parameter); + } + } + return SUCCESS; +} +// TO use for POST +/************************************************************************** + * Function Name : occli_frame_string_from_postDriver + * Description : This Function is used to frame the cli string + * Input(s) : param, strFrame, msgTypeStr + * Output(s) : ocmwclistr, occliData + ***************************************************************************/ +int8_t occli_frame_string_from_postDriver(const Post *param, + OCCLI_ARRAY_PARAM *occliData, + strMsgFrame *strFrame) +{ + if ((occliData == NULL) || (param == NULL) || (strFrame == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + if (occliData->option == OCCLI_CALC_SCHEMA_SIZE) { + occliData->sizeNum += 1; + } else { + if (strlen(strFrame->subcomponent)) { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_SNPRINTF_MAX_LEN, "%s.%s.%s.%s.%s.%s", + strFrame->subsystem, strFrame->component, + strFrame->msgtype, strFrame->subcomponent, + param->name, strFrame->parameter); + } else { + snprintf(s_allParams[occliData->totalStr++], + OCCLI_SNPRINTF_MAX_LEN, "%s.%s.%s.%s.%s", + strFrame->subsystem, strFrame->component, + strFrame->msgtype, param->name, strFrame->parameter); + } + } + return SUCCESS; +} +/************************************************************************** + * Function Name : occli_frame_string_from_schema + * Description : This Function is used to frame the cli string + * Input(s) : devDriver, strFrame + * Output(s) : ocmwclistr, occliData + ***************************************************************************/ +int8_t occli_frame_string_from_schema(const Driver *devDriver, + OCCLI_ARRAY_PARAM *occliData, + strMsgFrame *strFrame) +{ + const Post *postParam = NULL; + const Parameter *param = NULL; + int8_t ret = SUCCESS; + + if ((devDriver == NULL) || (occliData == NULL) || (strFrame == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + postParam = devDriver->post; + while (postParam && postParam->name) { + strcpy(strFrame->msgtype, "post"); + if (strncmp(postParam->name, "enable", strlen(postParam->name)) == 0) { + strcpy(strFrame->parameter, "set"); + } else { + strcpy(strFrame->parameter, "get"); + } + ret = occli_frame_string_from_postDriver(postParam, occliData, strFrame); + postParam++; + } + + param = devDriver->config; + while (param && param->name) { + strcpy(strFrame->msgtype, "config"); + strcpy(strFrame->parameter, "set"); + ret = occli_frame_string_from_schemaDriver(param, occliData, strFrame); + + strcpy(strFrame->parameter, "get"); + ret = occli_frame_string_from_schemaDriver(param, occliData, strFrame); + param++; + } + + param = devDriver->status; + while (param && param->name) { + strcpy(strFrame->msgtype, "status"); + strcpy(strFrame->parameter, "get"); + ret = occli_frame_string_from_schemaDriver(param, occliData, strFrame); + param++; + } + +#ifdef OCCLI_ALERT_STRING + param = devDriver->alerts; + strcpy(strFrame->msgtype, "alert"); + ret = occli_frame_string_from_schemaDriver(param, occliData, strFrame); +#endif + + return ret; +} +/************************************************************************** + * Function Name : occli_frame_string + * Description : This Function is used to frame the cli string + * Input(s) : root + * Output(s) : ocmwclistr, occliData + ***************************************************************************/ +int8_t occli_frame_string(const Component *root, OCCLI_ARRAY_PARAM *occliData) +{ + const Component *component = NULL, *subComponent = NULL, *subSystem = root; + const Driver *devDriver = NULL; + int8_t ret = 0; + + strMsgFrame *strFrame = (strMsgFrame *) malloc(sizeof(strMsgFrame)); + + if ((strFrame == NULL) || (root == NULL) || + (occliData == NULL)) { + logerr("Invalid Memory \n"); + return FAILED; + } + + /* Config/Status/Alerts Table array entry Creation */ + while (subSystem && subSystem->name) { + memset(strFrame, '\0', sizeof(strMsgFrame)); + strcpy(strFrame->subsystem, subSystem->name); + component = subSystem->components; + while (component && component->name) { + memset(strFrame->subcomponent, '\0', OCCLI_CHAR_ARRAY_SIZE); + strcpy(strFrame->component, component->name); + devDriver = component->driver; + if (devDriver != NULL) { + ret = occli_frame_string_from_schema(devDriver, + occliData, strFrame); + if (ret == FAILED) { + return ret; + } + } + subComponent = component->components; + while (subComponent && subComponent->name) { + strcpy(strFrame->subcomponent, subComponent->name); + devDriver = subComponent->driver; + if (devDriver != NULL) { + ret = occli_frame_string_from_schema(devDriver, + occliData, strFrame); + if (ret == FAILED) { + return ret; + } + } + subComponent += 1; + } + component += 1; + } + subSystem += 1; + } + free(strFrame); + return SUCCESS; +} + +/************************************************************************** + * Function Name : main + * Description : + * Input(s) : argc, argv + * Output(s) : + ***************************************************************************/ +int32_t main(int32_t argc, char *argv[]) +{ + char *line = NULL; + char *clistr = NULL; + char response[RES_STR_BUFF_SIZE] = {0}; + char historyFile[HIT_FILE_BUFF_SIZE]; + char *cmdstr = NULL; + const char* prompt = "opencellular# "; + int32_t index = 0; + int32_t ret = 0; + pthread_t alertThreadId; + sMsgParam msgFrameParam; + OCCLI_ARRAY_PARAM occliArray; + + /* Initialize logging */ + initlog("occli"); + + memset(&msgFrameParam, 0, sizeof(sMsgParam)); + memset (&occliArray, 0, sizeof(OCCLI_ARRAY_PARAM)); + + occliArray.option = OCCLI_CALC_SCHEMA_SIZE; + + ret = occli_frame_string(sys_schema, &occliArray); + if (ret != 0) { + logerr("init_ocmw_comm() failed."); + return FAILED; + } + + ret = occli_frame_commands(sys_schema, &occliArray); + if (ret != 0) { + logerr("init_ocmw_comm() failed."); + return FAILED; + } + + for (index= 0; index< occliArray.sizeNum; index++) { + if(!(s_allParams[index] = (char *)malloc(OCCLI_STRING_MAX_LEN))) { + return FAILED; + } + + } + + occliArray.option = OCCLI_PARSE_SCHEMA; + ret = occli_frame_string(sys_schema, &occliArray); + if (ret != 0) { + logerr("init_ocmw_comm() failed."); + return FAILED; + } + + ret = occli_frame_commands(sys_schema, &occliArray); + if (ret != 0) { + logerr("init_ocmw_comm() failed."); + return FAILED; + } + + /* Initialize Middleware IPC communication */ + ret = occli_init_comm(); + if (ret != 0) { + logerr("init_ocmw_comm() failed."); + return FAILED; + } + + /* Execute the OC command (argv[1:]) and exit */ + if (strcmp("occmd", basename(argv[0])) == 0) { + for (index= 1; index < argc; index++) { + if (occli_strjoin(&cmdstr, argv[index], " ") != 0) { + logerr("occli_strjoin error"); + break; + } + } + + ret = occli_parse_cliString(cmdstr); + if (ret != SUCCESS) { + printf("%s : Error : Invalid String\n", cmdstr); + free(cmdstr); + cmdstr = NULL; + } + + if (cmdstr != NULL) { + logdebug("cmdstr='%s'", cmdstr); + occli_send_cmd_to_ocmw(cmdstr, strlen(cmdstr)); + memset(response, 0, sizeof(response)); + occli_recv_cmd_resp_from_ocmw(response, sizeof(response)); + + printf("%s\n", response); + free(cmdstr); + } else { + printf("internal error\n"); + } + } + /* Entering interactive CLI */ + else if (strcmp("occli", basename(argv[0])) == 0) { + ret = pthread_create(&alertThreadId, NULL, + occli_alertthread_messenger_to_ocmw, NULL); + + if (ret != 0) { + return ret; + } + + /* Initialize readline */ + using_history(); + if ((snprintf(historyFile, HIT_FILE_BUFF_SIZE, "%s/%s", getenv("HOME"), + HISTORY)) < 0) { + return FAILED; + } + + read_history(historyFile); + rl_attempted_completion_function = occli_custom_completion; + + /*Printing hints at the start of opencelluar */ + occli_print_opencelluar(); + + while (1) { + line = readline(prompt); + if (line == NULL) { + break; + } + clistr = line; + + /* trim initial white spaces */ + while (isblank(*clistr)) { + ++clistr; + } + occli_trim_extra_spaces(clistr); + if (strcmp(clistr, "") == 0) { + continue; + } + + /* Quit the CLI, when command 'quit' is received */ + if (strcmp(clistr, "quit") == 0) { + free(line); + break; + } + /* Print the help manu */ + if((strstr(clistr, "help"))) { + if ((strstr(clistr, "--help"))) { + ret = occli_printHelpMenu(sys_schema, clistr); + if (ret == FAILED) { + logerr("occli_printHelpMenu failed.\n"); + } + continue; + } else { + printf("%s : Error : Incorrect request\n", clistr); + printf ("Usage : subsystem --help" + " OR subsystem.component --help\n"); + continue; + } + } + + ret = occli_parse_cliString(clistr); + if (ret != SUCCESS) { + printf("%s : Error : Invalid String\n", clistr); + continue; + } + + add_history(clistr); + + occli_send_cmd_to_ocmw(clistr, strlen(clistr)); + + memset(response, 0, sizeof(response)); + occli_recv_cmd_resp_from_ocmw(response, sizeof(response)); + + /* Print the command execution results in the CLI */ + printf("%s\n", response); + + free(line); + } + + write_history(historyFile); + } + + for (index= 0; ((s_allParams[index] != NULL) && + (index < OCCLI_MAX_CLISTRING)); index++) { + free(s_allParams[index]); + } + + for (index= 0; ((s_subSetParams[index] != NULL) && + (index < OCCLI_MAX_SUBSTRING)); index++) { + free(s_subSetParams[index]); + } + occli_deinit_comm(); + deinitlog(); + + return SUCCESS; +} diff --git a/firmware/host/occli/occli_ocmw_comm.c b/firmware/host/occli/occli_ocmw_comm.c new file mode 100644 index 0000000000..d3b97819c1 --- /dev/null +++ b/firmware/host/occli/occli_ocmw_comm.c @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* OC includes */ +#include +#include + +static int32_t s_sockFd = 0; +static int32_t s_alertSockFd = 0; +static struct sockaddr_in s_siServer, s_alertServer; +static char s_displayStr[OCCLI_SNPRINTF_MAX_LEN]; + +/************************************************************************** + * Function Name : occli_init_comm + * Description : This Function used to initialize the communication + * between middleware code + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t occli_init_comm(void) +{ + int32_t ret = 0; + int32_t inetAtonRet = 0; + struct timeval timeValObj; + + timeValObj.tv_sec = OCCLI_TIMEOUT_PERIOD; + timeValObj.tv_usec = 0; + + /* Create socket */ + s_sockFd = socket(OCMW_SOCK_DOMAIN, OCMW_SOCK_TYPE, OCMW_SOCK_PROTOCOL); + if (s_sockFd < 0) { + ret = -errno; + logerr("socket creation error [%d-%s]", errno, strerror(errno)); + return ret; + } + + /* Initialize socket structure */ + memset(&s_siServer, 0, sizeof(s_siServer)); + s_siServer.sin_family = OCMW_SOCK_DOMAIN; + s_siServer.sin_port = htons(OCMW_SOCK_SERVER_PORT); + inetAtonRet = inet_aton(OCMW_SOCK_SERVER_IP, &s_siServer.sin_addr); + if (inetAtonRet == 0) { + logerr("inet_aton failed"); + ret = FAILED; + return ret; + } + + if (setsockopt(s_sockFd, SOL_SOCKET, SO_RCVTIMEO, + &timeValObj, sizeof(timeValObj)) < 0) { + logerr("setsockopt failed"); + ret = FAILED; + return ret; + } + + /* For Alert Capture */ + s_alertSockFd = socket(OCMW_SOCK_ALERT_DOMAIN, OCMW_SOCK_ALERT_TYPE, + OCMW_SOCK_ALERT_PROTOCOL); + if (s_alertSockFd < 0) { + ret = -errno; + logerr("socket creation error [%d-%s]", errno, strerror(errno)); + return ret; + } + + /* Initialize socket structure */ + memset(&s_alertServer, 0, sizeof(s_alertServer)); + s_alertServer.sin_family = OCMW_SOCK_ALERT_DOMAIN; + s_alertServer.sin_port = htons(OCMW_SOCK_ALERT_SERVER_PORT); + inetAtonRet = inet_aton(OCMW_SOCK_ALERT_SERVER_IP, &s_alertServer.sin_addr); + if (inetAtonRet == 0) { + logerr("inet_aton failed"); + ret = FAILED; + return ret; + } + + /* Bind host address to the socket */ + ret = bind(s_alertSockFd, (struct sockaddr*) &s_alertServer, + sizeof(s_alertServer)); + if (ret < 0) { + ret = -errno; + logerr("bind error [%d-%s]", errno, strerror(errno)); + return ret; + } + + return SUCCESS; +} + +/************************************************************************** + * Function Name : occli_deinit_comm + * Description : This Function used to deinitialize the communication + * betwwen middleware code + * Input(s) : + * Output(s) : + ***************************************************************************/ +int8_t occli_deinit_comm(void) +{ + /* Close the IPC socket */ + close(s_sockFd); + s_sockFd = 0; + return SUCCESS; +} + +/************************************************************************** + * Function Name : occli_send_cmd_to_ocmw + * Description : This Function used to send command to middleware + * Input(s) : cmd, cmdlen + * Output(s) : + ***************************************************************************/ +int32_t occli_send_cmd_to_ocmw(const char *cmd, int32_t cmdlen) +{ + char errstr[OCMW_SOCKET_ERROR_SIZE]; + int32_t ret = 0; + int32_t strLen = sizeof(s_siServer); + + strncpy(s_displayStr, cmd, cmdlen); + /* Send the CLI command string to OCMW over UDP socket */ + ret = sendto(s_sockFd, cmd, cmdlen, 0, + (const struct sockaddr *) &s_siServer, strLen); + if (ret < 0) { + strerror_r(errno, errstr, OCMW_SOCKET_ERROR_SIZE); + logerr("Error: 'sendto' [%d-%s]", errno, errstr); + printf("%s : Error : Socket error", s_displayStr); + } + return ret; +} + +/************************************************************************** + * Function Name : occli_recv_cmd_resp_from_ocmw + * Description : This Function used to receive message from middlware + * Input(s) : + * Output(s) : resp, resplen + ***************************************************************************/ +int32_t occli_recv_cmd_resp_from_ocmw(char *resp, int32_t resplen) +{ + char errstr[OCMW_SOCKET_ERROR_SIZE]; + int32_t ret = 0; + int32_t strLen = sizeof(s_siServer); + + /* Receive the CLI command execution response string from OCMW over UDP + socket */ + ret = recvfrom(s_sockFd, resp, resplen, 0, + (struct sockaddr*) &s_siServer, (socklen_t*) &strLen); + if (ret < 0) { + strerror_r(errno, errstr, OCMW_SOCKET_ERROR_SIZE); + logerr("Error: 'recvfrom' [%d-%s]", ret, errstr); + printf("%s : Error : Timeout from Middleware", s_displayStr); + } + return ret; +} + +/************************************************************************** + * Function Name : occli_recv_alertmsg_from_ocmw + * Description : This Function used to receive alert message from + * middleware + * Input(s) : + * Output(s) : resp, resplen + ***************************************************************************/ +int32_t occli_recv_alertmsg_from_ocmw(char *resp, int32_t resplen) +{ + char errstr[OCMW_SOCKET_ERROR_SIZE]; + int32_t ret = 0; + int32_t strLen = sizeof(s_alertServer); + + /* Receive the Alert Message string from OCMW over UDP socket */ + ret = recvfrom(s_alertSockFd, resp, resplen, 0, + (struct sockaddr*) &s_alertServer, (socklen_t*) &strLen); + if (ret < 0) { + strerror_r(errno, errstr, OCMW_SOCKET_ERROR_SIZE); + logerr("Error: 'recvfrom' [%d-%s]", ret, errstr); + printf("Error: 'recvfrom' [%d-%s]", ret, errstr); + } + return ret; +} diff --git a/firmware/host/ocmw/ocmw_clicmd.c b/firmware/host/ocmw/ocmw_clicmd.c new file mode 100644 index 0000000000..f0b04134bb --- /dev/null +++ b/firmware/host/ocmw/ocmw_clicmd.c @@ -0,0 +1,1216 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +/* OC includes */ +#include +#include +#include +#include +#include + +#define INVALID_SYNTAX "Error : Invalid syntax" +#define INSUFFICIENT_PARAM "Error : Insufficient parameters" + +extern int8_t obcTestingmoduleData[MAX_PARM_COUNT]; +extern int8_t dataOutBufFromEc[MAX_PARM_COUNT]; +extern int8_t eepromStatusFlag; +extern int64_t recvdParamVal; +extern int8_t eepromStatusFlag; +extern int8_t eepromStatusFlag; +extern int32_t eepromFlag; +extern uint8_t ocwarePostArrayIndex; +debugI2CData I2CInfo; +debugMDIOData MDIOInfo; + +struct matchString { + const char *key; + ocmw_token_t token; +} ocmwTokenTable[] = { + { "set", SET_STR }, + { "get", GET_STR }, + { "reset", RESET_STR }, + { "enable", ENABLE_STR }, + { "disable", DISABLE_STR }, + {"active", ACTIVE_STR }, + { "echo", ECHO_STR }, + { "disconnect_nw", DISCONNECT_STR }, + { "connect_nw", CONNECT_STR }, + { "send", SEND_STR }, + { "dial", DIAL_STR }, + { "answer", ANSWER_STR }, + { "hangup", HANGUP_STR }, + { "en_loopBk", ELOOPBK_STR }, + { "dis_loopBk", DLOOPBK_STR }, + { "en_pktGen", EPKTGEN_STR }, + { "dis_pktGen", DPKTGEN_STR }, + { NULL, MAX_STR }, +}; + +struct matchSetGet { + const char *key; + ocmw_setGet token; +} ocmwSetGetTable[] = { + { "hci.led.fw", HCI_STR }, + { "debug", DEBUG_STR }, + {"system.comp_all.post.results", RESULT_STR }, + {"system.comp_all.post.enable", ENABLE_SET_STR }, + { NULL, GETSETMAX }, +}; +/************************************************************************** + * Function Name : ocmw_tokenize_class + * Description : This Function used to extract the class from the param + * string + * Input(s) : str, option + * Output(s) : param + ***************************************************************************/ +static int32_t ocmw_tokenize_class(char *str, char *param, int32_t option) +{ + char *token; + int32_t count = 0; + + token = strtok(str, " ."); + if (token == NULL) + return -1; + + while (token) { + if (count == 2) { + strncpy(param, token, PARAMSTR_NUMBER_LEN); + break; + } + token = strtok(NULL, " ."); + count++; + + if(option == 1){ + strncpy(param, token, PARAMSTR_NUMBER_LEN); + break; + } + } + return SUCCESS; +} + +/************************************************************************** + * Function Name : ocmw_tokenize + * Description : This Function used to extract the CLI string + * Input(s) : cmdstr + * Output(s) : strTokenCount, strTokenArray + ***************************************************************************/ +static int32_t ocmw_tokenize(const char *cmdstr, + int32_t *strTokenCount, char ***strTokenArray) +{ + char *str = NULL; + char *saveptr = NULL; + char *paramStr = NULL; + char *token = NULL; + char **localStrTokenArray = NULL; + char **temp = NULL; + const char *delim = " "; + int32_t localStrTokenCount = 0; + int32_t index = 0; + + /* Split the actiontype from the cmdstr */ + paramStr = strrchr(cmdstr, '.'); + *paramStr = ' '; + + for (index = 1, str = (char*) cmdstr;; index++, str = NULL) { + token = strtok_r(str, delim, &saveptr); + if (token == NULL) { + break; + } + + localStrTokenCount++; + temp = localStrTokenArray; + localStrTokenArray = realloc(localStrTokenArray, + sizeof(char *) * localStrTokenCount); + if (localStrTokenArray == NULL) { + logerr("realloc failed"); + /* Free the original block of memory before realloc */ + if (temp != NULL) { + free(temp); + } + return FAILED; + } + localStrTokenArray[localStrTokenCount - 1] = token; + } + + *strTokenCount = localStrTokenCount; + *strTokenArray = localStrTokenArray; + return SUCCESS; +} + +/************************************************************************** + * Function Name : ocmw_check_numeric_number + * Description : This Function used to validate the mobile number + * Input(s) : numstring + * Output(s) : + ***************************************************************************/ +int32_t ocmw_check_numeric_number(char *numstring) +{ + int32_t index = 0; + int32_t len = strlen(numstring); + + while (index < len) { + if ((*(numstring + index) < '0') || + (*(numstring + index) > '9')) { + return FAILED; + } + index++; + } + return SUCCESS; +} +#if 0 +/************************************************************************** + * Function Name : ocmw_string_parse + * Description : This Function used to parse the param string + * Input(s) : string + * Output(s) : outStr + ***************************************************************************/ +int8_t ocmw_string_parse(char *string, char *outStr) +{ + char *token; + char string1[CHAR_SIZE_12] = { 0 }; + char string2[CHAR_SIZE_12] = { 0 }; + + token = strtok(string, " ."); + if (token == NULL) { + return FAILED; + } + + strncpy(string1, token, CHAR_SIZE_12); + token = strtok(NULL, " ."); + if (token == NULL) { + return FAILED; + } + strncpy(string2, token, CHAR_SIZE_12); + + if ((snprintf(outStr, CHAR_SIZE_32, "%s.%s", string1, string2)) < 0) { + return FAILED; + } + return SUCCESS; +} +#endif +/************************************************************************** + * Function Name : ocmw_handle_set_config + * Description : This Function used to handle the set config commands + * Input(s) : strTokenArray + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_set_config(char* strTokenArray[], char *response) +{ + char *paramStr; + void *paramvalue; + int32_t ret = 0; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + paramStr = strTokenArray[0]; + paramvalue = strTokenArray[2]; + strcpy(tempParamStr, strTokenArray[0]); + + ret = ocmw_msgproc_send_msg(&strTokenArray[0], OCMP_AXN_TYPE_SET, + OCMP_MSG_TYPE_CONFIG, (int8_t *) paramStr, paramvalue); + + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %s : %s", strTokenArray[0], + strTokenArray[1], strTokenArray[2], + (ret != 0) ? "Failed" : "Success")) < 0) { + return FAILED; + } + + return ret; +} + +/************************************************************************** + * Function Name : ocmw_handle_show_config + * Description : This Function used to handle the show config commands + * Input(s) : strTokenArray + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_show_config(char* strTokenArray[], char *response) +{ + char *paramStr; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + int32_t paramVal = 0; + int32_t ret = 0; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + paramStr = strTokenArray[0]; + strcpy(tempParamStr, strTokenArray[0]); + + + ret = ocmw_msgproc_send_msg(&strTokenArray[0], OCMP_AXN_TYPE_GET, + OCMP_MSG_TYPE_CONFIG, (int8_t *) paramStr, ¶mVal); + + if (ret != 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s : Failed", + tempParamStr, strTokenArray[1])) < 0) { + return FAILED; + } + } else { + if (eepromFlag > 0){ + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %s", + tempParamStr, strTokenArray[1], dataOutBufFromEc)) < 0) { + return FAILED; + } + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %" PRId64, + (int8_t *)tempParamStr, strTokenArray[1], recvdParamVal)) <0) { + return FAILED; + } + } + } + return ret; +} + +/************************************************************************** + * Function Name : ocmw_handle_show_status + * Description : This Function used to handle the status commands + * Input(s) : strTokenArray + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_show_status(char* strTokenArray[], char *response) +{ + char *paramStr; + int32_t ret = 0; + int32_t value = 0; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + paramStr = strTokenArray[0]; + strcpy(tempParamStr, strTokenArray[0]); + + + ret = ocmw_msgproc_send_msg(&strTokenArray[0], OCMP_AXN_TYPE_GET, + OCMP_MSG_TYPE_STATUS, (int8_t *) paramStr, (void*) &value); + + if (ret != 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s : Failed", + tempParamStr, strTokenArray[1])) < 0) { + return FAILED; + } + } else if (eepromFlag > 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %s", + tempParamStr, strTokenArray[1], dataOutBufFromEc)) < 0) { + return FAILED; + } + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %" PRId64, + tempParamStr, strTokenArray[1], recvdParamVal)) < 0) { + return FAILED; + } + } + + return ret; +} + +/************************************************************************** + * Function Name : ocmw_handle_debug_command_function + * Description : This Function used to handle the debug commands + * Input(s) : strTokenArray, action + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_debug_command_function(char* strTokenArray[], + char *response) +{ + char paramStr[PARAM_STR_BUFF_SIZE] = {0}; + char displayStr[PARAM_STR_BUFF_SIZE] = {0}; + void *paramvalue = NULL; + int32_t value = 0; + int32_t ret = 0; + + debugGPIOData GPIOInfo; + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + if((strncmp("debug", strTokenArray[0], + strlen("debug")) == 0) && + (strncmp(strTokenArray[1], "set", strlen("set")) + == 0)) { + /* Registers debug option */ + if((strncmp("debug.I2C", strTokenArray[0], + strlen("debug.I2C")) == 0) && + (strncmp(strTokenArray[1], "set", strlen("set")) + == 0)) { + I2CInfo.slaveAddress = atoi(strTokenArray[2]); + I2CInfo.numOfBytes = atoi(strTokenArray[3]); + I2CInfo.regAddress = atoi(strTokenArray[4]); + I2CInfo.regValue = atoi(strTokenArray[5]); + paramvalue = (void*) &I2CInfo; + sprintf(displayStr, "%s (slave address :%s noOfBytes :%s" + " Register Address :%s) %s= %s", strTokenArray[0], + strTokenArray[2], strTokenArray[3], + strTokenArray[4], strTokenArray[1], strTokenArray[5]); + } else if ((strncmp("debug.ethernet", strTokenArray[0], + strlen("debug.ethernet")) == 0)) { + MDIOInfo.regAddress = atoi(strTokenArray[2]); + MDIOInfo.regValue = atoi(strTokenArray[3]); + paramvalue = (void*) &MDIOInfo; + sprintf(displayStr, "%s (Register Address :%s) %s = %s", + strTokenArray[0], strTokenArray[2], + strTokenArray[1], strTokenArray[3]); + } else { + GPIOInfo.pin = atoi(strTokenArray[2]); + GPIOInfo.value = atoi(strTokenArray[3]); + paramvalue = (void*) &GPIOInfo; + sprintf(displayStr, "%s (Pin No :%s) %s = %s", + strTokenArray[0], strTokenArray[2], + strTokenArray[1], strTokenArray[3]); + } + } else if((strncmp("debug", strTokenArray[0], + strlen("debug")) == 0) && + (strncmp(strTokenArray[1], "get", strlen("get")) + == 0)) { + /* Registers debug option */ + if((strncmp("debug.I2C", strTokenArray[0], + strlen("debug.I2C")) == 0) && + (strncmp(strTokenArray[1], "get", strlen("get")) + == 0)) { + I2CInfo.slaveAddress = atoi(strTokenArray[2]); + I2CInfo.numOfBytes = atoi(strTokenArray[3]); + I2CInfo.regAddress = atoi(strTokenArray[4]); + paramvalue = (void*) &I2CInfo; + sprintf(displayStr, "%s (slave address :%s noOfBytes :%s" + " Register Address :%s) %s", strTokenArray[0], + strTokenArray[2], strTokenArray[3], + strTokenArray[4], strTokenArray[1]); + } else if ((strncmp("debug.ethernet", strTokenArray[0], + strlen("debug.ethernet")) == 0)) { + MDIOInfo.regAddress = atoi(strTokenArray[2]); + paramvalue = (void*) &MDIOInfo; + sprintf(displayStr, "%s (Register Address :%s) %s", + strTokenArray[0], strTokenArray[2], + strTokenArray[1]); + } else { + GPIOInfo.pin = atoi(strTokenArray[2]); + paramvalue = (void*) &GPIOInfo; + sprintf(displayStr, "%s (Pin No :%s) %s", + strTokenArray[0], strTokenArray[2], + strTokenArray[1]); + } + } else { + paramvalue = (void*) &value; + } + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", + strTokenArray[1],strTokenArray[0])) < 0) { + return FAILED; + } + ret = ocmw_msgproc_send_msg(&strTokenArray[0], 0, + OCMP_MSG_TYPE_COMMAND, (int8_t *) paramStr, paramvalue); + + if (ret != SUCCESS) { + snprintf(response, RES_STR_BUFF_SIZE, "%s : Failed", displayStr); + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s %s", + strTokenArray[0], dataOutBufFromEc)) < 0) { + return FAILED; + } + } + return ret; +} + +/************************************************************************** + * Function Name : ocmw_handle_testmod_command_function + * Description : This Function used to handle the test modules commands + * Input(s) : strTokenArray, action + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_testmod_command_function(char* strTokenArray[], + char *response) +{ + char paramStr[PARAM_STR_BUFF_SIZE] = {0}; + char msgstr[PARAM_STR_BUFF_SIZE] = {0}; + void *paramvalue = NULL; + int32_t value = 0; + int32_t len = 0; + int32_t ret = 0; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + + if ((strncmp(strTokenArray[1], "send", strlen("send"))) == + 0) { + if (strlen(strTokenArray[2]) > OCMW_MAX_IMEI_SIZE) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s " + "(number = %s, msg = %s) : Error : Number " + "Invalid", strTokenArray[0], strTokenArray[1], + strTokenArray[2], strTokenArray[3])) < 0) { + return FAILED; + } + return FAILED; + } + if (ocmw_check_numeric_number(strTokenArray[2]) != SUCCESS) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s " + "(number = %s, msg = %s) : Error : Number " + "Invalid", strTokenArray[0], strTokenArray[1], + strTokenArray[2], strTokenArray[3])) < 0) { + return FAILED; + } + return FAILED; + } + len = strlen(strTokenArray[3]); + len = + (len < OCMW_MAX_MSG_SIZE) ? len : OCMW_MAX_MSG_SIZE - 1; + if ((snprintf(msgstr, PARAM_STR_BUFF_SIZE, "%s", + strTokenArray[2])) + < 0) { + return FAILED; + } + if ((snprintf(&msgstr[TESTMOD_MAX_LEN], PARAM_STR_BUFF_SIZE, "%s", + strTokenArray[3])) < 0) { + return FAILED; + } + paramvalue = (void *) msgstr; + } else if (strncmp(strTokenArray[1], "dial", strlen("dial")) == + 0) { + if (strlen(strTokenArray[2]) > OCMW_MAX_IMEI_SIZE) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s " + "(number = %s) : Error : Number " + "Invalid", strTokenArray[0], strTokenArray[1], strTokenArray[2])) < 0) { + return FAILED; + } + return FAILED; + } + if (ocmw_check_numeric_number(strTokenArray[2]) != SUCCESS) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s " + "(number = %s) : Error : Number " + "Invalid", strTokenArray[0], strTokenArray[1], strTokenArray[2])) < 0) { + return FAILED; + } + return FAILED; + } + paramvalue = (void*) (strTokenArray[2]); + } else { + paramvalue = (void*) &value; + } + strcpy(tempParamStr,strTokenArray[0]); + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", + strTokenArray[1], strTokenArray[0])) < 0) { + return FAILED; + } + ret = ocmw_msgproc_send_msg(&strTokenArray[0], 0, + OCMP_MSG_TYPE_COMMAND, (int8_t *) paramStr,paramvalue); + if (strncmp(strTokenArray[1], "get", strlen("get")) == 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %s", + tempParamStr, strTokenArray[1], dataOutBufFromEc)) < 0) { + return FAILED; + } + } else if (strncmp(strTokenArray[1], "send", strlen("send")) == 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s (number = %s msg = %s)" + " : %s", strTokenArray[0], strTokenArray[1], strTokenArray[2], + strTokenArray[3], (ret != SUCCESS) ? "Failed" : "Success")) < 0) { + return FAILED; + } + } else if (strncmp(strTokenArray[1], "dial", strlen("dial")) == 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s (number = %s) :" + " %s", strTokenArray[0], strTokenArray[1], strTokenArray[2], + (ret != SUCCESS) ? "Failed" : "Success")) < 0) { + return FAILED; + } + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s : %s", strTokenArray[0], + strTokenArray[1], (ret != SUCCESS) ? "Failed" : "Success")) < + 0) { + return FAILED; + } + } + return ret; +} +/************************************************************************** + + * Function Name : ocmw_handle_ethernet_command_function + * Description : This Function used to handle the loopBack and packent + * genrator commands + * Input(s) : strTokenArray, action + * Output(s) : response + ***************************************************************************/ +static int8_t ocmw_handle_ethernet_command_function(char* strTokenArray[], + char *response) +{ + char paramStr[PARAM_STR_BUFF_SIZE] = { 0 }; + void *paramvalue = NULL; + + int32_t value = 0; + int32_t ret = 0; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + value = atoi(strTokenArray[2]); + + if (((value > 2) || (value < 0)) && + (strstr(strTokenArray[1],"loopBk"))) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s " + "(number = %s) : Error : Number Invalid", + strTokenArray[0], strTokenArray[1], strTokenArray[2])) < 0) { + + return FAILED; + } + return FAILED; + } + + paramvalue = (void*) &value; + strcpy(tempParamStr,strTokenArray[0]); + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", + strTokenArray[1],strTokenArray[0])) < 0) { + return FAILED; + } + ret = ocmw_msgproc_send_msg(&strTokenArray[0], 0, + OCMP_MSG_TYPE_COMMAND, (int8_t *) paramStr, paramvalue); + if (strncmp(strTokenArray[1], "dis_pktGen", strlen("dis_pktGen")) == 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s : %s", + strTokenArray[0], strTokenArray[1], (ret != 0) ? "Failed" : + "Success")) < 0) { + return FAILED; + } + } else { + /* processing enable_pktGen */ + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s %s : %s", + strTokenArray[0], strTokenArray[1], strTokenArray[2], + (ret != 0) ? "Failed" : "Success")) < 0) { + return FAILED; + } + } + return ret; +} +/************************************************************************** + * Function Name : ocmw_handle_hci_led_set_command_function + * Description : This Function used to handle the test modules commands + * Input(s) : strTokenArray, action + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_hci_led_set_command_function(char* strTokenArray[], + char *response) +{ + char paramStr[PARAM_STR_BUFF_SIZE] = { 0 }; + void *paramvalue = NULL; + int32_t value = 0; + int32_t ret = 0; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + value = atoi(strTokenArray[2]); + paramvalue = (void*) &value; + strcpy(tempParamStr,strTokenArray[0]); + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", + strTokenArray[1],strTokenArray[0])) < 0) { + return FAILED; + } + ret = ocmw_msgproc_send_msg(&strTokenArray[0], 0, + OCMP_MSG_TYPE_COMMAND, (int8_t *) paramStr, paramvalue); + if (strncmp(strTokenArray[1], "get", strlen("get")) + == 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s = %s", + tempParamStr, strTokenArray[1],dataOutBufFromEc)) < 0) { + return FAILED; + } + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s %s : %s", + strTokenArray[0], strTokenArray[1], strTokenArray[2], + (ret != 0) ? "Failed" : "Success")) < 0) { + return FAILED; + } + } + return ret; +} + +/************************************************************************** + * Function Name : ocmw_handle_command_function + * Description : This Function used to handle the command messages + * Input(s) : strTokenArray, action + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_command_function(char* strTokenArray[], + char *response) +{ + char paramStr[PARAM_STR_BUFF_SIZE]; + int32_t ret = 0; + int32_t paramVal = 0; + char tempParamStr[PARAM_STR_MAX_BUFF_SIZE] = {0}; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + strcpy(tempParamStr, strTokenArray[0]); + + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", strTokenArray[1], + strTokenArray[0])) < 0) { + return FAILED; + } + + ret = ocmw_msgproc_send_msg(&strTokenArray[0], 0, + OCMP_MSG_TYPE_COMMAND, (int8_t *) paramStr, ¶mVal); + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s.%s : %s", + strTokenArray[0], strTokenArray[1], + (ret != 0) ? "Failed" : "Success")) < 0) { + return FAILED; + } + + return ret; +} + +/************************************************************************** + * Function Name : ocmw_handle_post_command + * Description : This Function used to handle the post commands + * Input(s) : strTokenArray + * Output(s) : response + ***************************************************************************/ +static int32_t ocmw_handle_post_command(char* strTokenArray[], char *response) +{ + char paramStr[PARAM_STR_BUFF_SIZE], tmp[TEMP_STR_BUFF_SIZE]; + char subSys[PARAM_STR_BUFF_SIZE]; + int32_t ret = 0; + int32_t index = 0; + int32_t paramVal = 0; + int32_t count = 0; + ocwarePostResults postResult; + ocwarePostReplyCode reply; + + if (strTokenArray == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + + strcpy(subSys,postResult.results[0].subsysName); + if (strcmp("set", strTokenArray[1]) == 0) { + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", + strTokenArray[0], strTokenArray[1])) < 0) { + return FAILED; + } + ret = ocmw_msgproc_send_msg(&strTokenArray[0], OCMP_AXN_TYPE_SET, + OCMP_MSG_TYPE_POST, (int8_t *) paramStr,¶mVal); + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s : %s", paramStr, + (ret != 0) ? "Failed" : "Success")) < + 0) { + return FAILED; + } + } else if (strcmp("get", strTokenArray[1]) == 0) { + if ((snprintf(paramStr, PARAM_STR_BUFF_SIZE, "%s.%s", strTokenArray[0], + strTokenArray[1])) < 0) { + return FAILED; + } + ret = ocmw_msgproc_send_msg(&strTokenArray[0], OCMP_AXN_TYPE_GET, + OCMP_MSG_TYPE_POST, (int8_t *) paramStr, ¶mVal); + if (ret != 0) { + if ((snprintf(response, RES_STR_BUFF_SIZE, "%s : Failed", paramStr)) + < 0) { + return FAILED; + } + } + postResult.count = ocwarePostArrayIndex; + + ret = ocmw_retrieve_post_results(&postResult); + if (ret < 0) { + logerr("%s error", paramStr); + return FAILED; + } + + strncpy(response, + "-------------------------------------------------------------------------------\n", + RES_STR_BUFF_SIZE); + if ((snprintf(tmp, TEMP_STR_BUFF_SIZE, "%-16s%-40s%-20s\n", + "Subsystem", "Device Name", "POST Status")) < 0) { + return FAILED; + } + + strncat(response, tmp, TEMP_STR_BUFF_SIZE); + if ((snprintf(tmp, TEMP_STR_BUFF_SIZE, + "-------------------------------------------------------------------------------\n")) + < 0) { + return FAILED; + } + strncat(response, tmp, TEMP_STR_BUFF_SIZE); + for (index = 0; index < postResult.count; index++) { + reply.msgtype = OCMP_MSG_TYPE_POST; + reply.replycode = postResult.results[index].status; + + ret = ocmw_retrieve_reply_code_desc(&reply); + if (ret < 0) { + strncpy(reply.desc, "", PARAM_STR_BUFF_SIZE); + } + if (strcmp(subSys,postResult.results[index].subsysName) != 0) { + strcpy(subSys,postResult.results[index].subsysName); + count = 0; + } + + if (count > 0) { + strcpy(postResult.results[index].subsysName, " "); + if ((snprintf(tmp, TEMP_STR_BUFF_SIZE, "%-16s%-40s%-20s\n", + postResult.results[index].subsysName, + postResult.results[index].deviceName, + reply.desc)) < 0) { + return FAILED; + } + strncat(response, tmp, TEMP_STR_BUFF_SIZE); + } else { + strcpy(subSys,postResult.results[index].subsysName); + postResult.results[index].subsysName[0] = + toupper(postResult.results[index].subsysName[0]); + if ((snprintf(tmp, TEMP_STR_BUFF_SIZE, "%-16s\n", + postResult.results[index].subsysName)) < 0) { + return FAILED; + } + strncat(response, tmp, TEMP_STR_BUFF_SIZE); + strcpy(postResult.results[index].subsysName, " "); + if ((snprintf(tmp, TEMP_STR_BUFF_SIZE, "%-16s%-40s%-20s\n", + postResult.results[index].subsysName, + postResult.results[index].deviceName, + reply.desc)) < 0) { + return FAILED; + } + strncat(response, tmp, TEMP_STR_BUFF_SIZE); + count++; + } + } + + if ((snprintf(tmp, TEMP_STR_BUFF_SIZE, + "-------------------------------------------------------------------------------\n")) + < 0) { + return FAILED; + } + + strncat(response, tmp, TEMP_STR_BUFF_SIZE); + + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, + "%s.%s : Error : Unknown parameter ", strTokenArray[0], strTokenArray[1])) < 0) { + return FAILED; + } + return FAILED; + } + return ret; +} +/************************************************************************** + * Function Name : ocmw_free_pointer + * Description : This is an inline function to free memory + * Input(s) : strTokenArray + * Output(s) : strTokenArray + ***************************************************************************/ +inline void ocmw_free_pointer(char **strTokenArray) { + if (strTokenArray) { + free(strTokenArray); + } + return; +} +/************************************************************************** + * Function Name : ocmw_match_set_get_string + * Description : This Function used to handle the cli set get + * Input(s) : str + * Output(s) : + ***************************************************************************/ +static ocmw_token_t ocmw_match_set_get_string(char *str) +{ + struct matchSetGet *index = ocmwSetGetTable; + for(; index->key != NULL && + strncmp(index->key, str, strlen(index->key)) != 0; ++index); + return index->token; +} +/************************************************************************** + * Function Name : ocmw_match_string + * Description : This Function used to handle the cli commands + * Input(s) : str + * Output(s) : + ***************************************************************************/ +static ocmw_token_t ocmw_match_string(char *str) +{ + struct matchString *index = ocmwTokenTable; + for(; index->key != NULL && + strncmp(index->key, str, strlen(index->key)) != 0; ++index); + return index->token; +} +/************************************************************************** + * Function Name : ocmw_frame_errorString + * Description : This Function used to handle the cli commands error + * Input(s) : cmdStr, errorString + * Output(s) : response + ***************************************************************************/ +int32_t ocmw_frame_errorString(const char *cmdStr, char *errorString, + char *response) +{ + if (errorString == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + if (snprintf(response, RES_STR_BUFF_SIZE, "%s : %s", + cmdStr, errorString)) { + logerr("%s(): Sprintf error", __func__); + return FAILED; + } + strcat(response, "\nPlease refer help menu:\n\"" + " --help or . --help\""); + return SUCCESS; +} +/************************************************************************** + * Function Name : ocmw_clicmd_handler + * Description : This Function used to handle the cli commands + * Input(s) : cmdstr + * Output(s) : response + ***************************************************************************/ +int32_t ocmw_clicmd_handler(const char *cmdStr, char *response) +{ + char **strTokenArray = NULL; + char class[PARAMSTR_NUMBER_LEN] = {0}; + char paramStr[PARAM_STR_BUFF_SIZE] = {0}; + int32_t strTokenCount = 0; + int32_t ret = 0; + + if (cmdStr == NULL || response == NULL) { + logerr("%s(): NULL pointer error", __func__); + return FAILED; + } + + if (strcmp(cmdStr, "") == 0) + return FAILED; + + ret = ocmw_tokenize(cmdStr, &strTokenCount, &strTokenArray); + if (ret < 0) { + logerr("Error: command string ocmw_tokenize failed"); + if ((snprintf(response, RES_STR_BUFF_SIZE, + "%s : Internal error occured in parsing CLI parameters", + cmdStr)) < 0) { + return FAILED; + } + ocmw_free_pointer(strTokenArray); + return FAILED; + } else { + if(strTokenCount > 1) { + strncpy(paramStr, strTokenArray[0], strlen(strTokenArray[0])); + /* Process the command */ + switch(ocmw_match_string(strTokenArray[1])) { + case SET_STR: + switch(ocmw_match_set_get_string(strTokenArray[0])) { + case HCI_STR: + if (strTokenCount == 3) { + ret = ocmw_handle_hci_led_set_command_function( + strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 3 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case DEBUG_STR: + if (strncmp("debug.I2C", strTokenArray[0], + strlen("debug.I2C")) == 0) { + if (strTokenCount == 6) { + ret = ocmw_handle_debug_command_function( + strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 6 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } else { + if (strTokenCount == 4) { + ret = ocmw_handle_debug_command_function( + strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 4 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } + break; + case ENABLE_SET_STR: + if (strTokenCount == 2) { + ret = ocmw_handle_post_command(strTokenArray, response); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 2 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + default: + if (strTokenCount == 3) { + ocmw_tokenize_class(paramStr, class, 2); + if (strcmp("config", class) == 0) { + ret = ocmw_handle_set_config(&strTokenArray[0], + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + if ((snprintf(response, + RES_STR_BUFF_SIZE, "[Error]: " + "Incorrect %s request '%s'", + strTokenArray[0],strTokenArray[1])) < 0) { + return FAILED; + } + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } else { + ret = (strTokenCount < 3 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + } + break; + case GET_STR: + switch(ocmw_match_set_get_string(strTokenArray[0])) { + case RESULT_STR: + if (strTokenCount == 2) { + ret = ocmw_handle_post_command(strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 2 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case DEBUG_STR: + if (strncmp("debug.I2C", strTokenArray[0], + strlen("debug.I2C")) == 0) { + if (strTokenCount == 5) { + ret = ocmw_handle_debug_command_function( + strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 5 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } else { + if (strTokenCount == 3) { + ret = ocmw_handle_debug_command_function( + strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 3 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } + break; + default : + if (strTokenCount == 2) { + ocmw_tokenize_class(paramStr, class, 2); + if (strcmp("config", class) == 0) { + ret = ocmw_handle_show_config(&strTokenArray[0], + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else if (strcmp("status", class) == 0) { + ret = ocmw_handle_show_status(&strTokenArray[0], + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else if (strcmp("alerts", class) == 0) { + /* SCHEMA change :: Alert is not implimented */ + /* ret = ocmw_handle_show_alerts(&strTokenArray[0], response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS;*/ + } else { + if ((snprintf(response, + RES_STR_BUFF_SIZE, "[Error]: " + "Incorrect %s request '%s'", + strTokenArray[0], strTokenArray[1])) < 0) { + return FAILED; + } + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } else { + ret = (strTokenCount < 2 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + } + case RESET_STR: + case ENABLE_STR: + case DISABLE_STR: + case ACTIVE_STR: + case ECHO_STR: + if (strTokenCount == 2) { + ret = ocmw_handle_command_function(strTokenArray, response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 2 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case DISCONNECT_STR: + case CONNECT_STR: + case ANSWER_STR: + case HANGUP_STR: + if (strTokenCount == 2) { + ret = ocmw_handle_testmod_command_function(strTokenArray, + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 2 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case SEND_STR: + if (strTokenCount == 4) { + ret = ocmw_handle_testmod_command_function(strTokenArray, + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 4 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case DIAL_STR: + if (strTokenCount == 3) { + ret = ocmw_handle_testmod_command_function(strTokenArray, + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 3 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case ELOOPBK_STR: + case DLOOPBK_STR: + case EPKTGEN_STR: + if (strTokenCount == 3) { + ret = ocmw_handle_ethernet_command_function(strTokenArray, + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 3 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + case DPKTGEN_STR: + if (strTokenCount == 2) { + ret = ocmw_handle_ethernet_command_function(strTokenArray, + response); + ocmw_free_pointer(strTokenArray); + return (ret != 0) ? FAILED : SUCCESS; + } else { + ret = (strTokenCount < 2 ? + ocmw_frame_errorString(cmdStr, + INSUFFICIENT_PARAM, response) : + ocmw_frame_errorString(cmdStr, + INVALID_SYNTAX, response)); + ocmw_free_pointer(strTokenArray); + return FAILED; + } + break; + default: + break; + } + } else { + if ((snprintf(response, RES_STR_BUFF_SIZE, + "%s : Error : Invalid parameters \n Please refer help menu" + ":\n\" --help or " + ". --help\"", cmdStr)) < 0) { + return FAILED; + } + ocmw_free_pointer(strTokenArray); + return FAILED; + } + } + ocmw_free_pointer(strTokenArray); + return ret; +} diff --git a/firmware/host/ocmw/ocmw_core.c b/firmware/host/ocmw/ocmw_core.c new file mode 100644 index 0000000000..e650c5e5a2 --- /dev/null +++ b/firmware/host/ocmw/ocmw_core.c @@ -0,0 +1,818 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* OC includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +static int32_t loopCountPost = 0; +extern debugI2CData I2CInfo; +extern debugMDIOData MDIOInfo; +extern uint8_t mcuMsgBuf[OCMP_MSG_SIZE]; +extern ocmwSchemaSendBuf *ecSendBufBkp; +int32_t responseCount = 0; +static int8_t s_paramInfoBackup[MAX_PARM_COUNT]; +static int32_t s_semTimeOut; +static int32_t s_totalSubsystem = 0; +extern const Component sys_schema[]; +subSystemInfo systemInfo; + +extern ocwarePostResultData ocwarePostArray[TEMP_STR_BUFF_SIZE]; +extern uint8_t ocwarePostArrayIndex; +ocwarePostReplyCode ocmwReplyCode[] = { + /* Message Type, reply code, Description */ + {OCMP_MSG_TYPE_POST, POST_DEV_NOSTATUS , "POST DEV NOSTATUS"}, + {OCMP_MSG_TYPE_POST, POST_DEV_MISSING, "DEV MISSING"}, + {OCMP_MSG_TYPE_POST, POST_DEV_ID_MISMATCH, "DEV ID MISMATCH"}, + {OCMP_MSG_TYPE_POST, POST_DEV_FOUND, "DEV FOUND"}, + {OCMP_MSG_TYPE_POST, POST_DEV_CFG_DONE, "CFG DONE"}, + {OCMP_MSG_TYPE_POST, POST_DEV_NO_CFG_REQ, "NO CFG REQUIRED"}, + {OCMP_MSG_TYPE_POST, POST_DEV_CFG_FAIL, "CFG FAILED"}, + {OCMP_MSG_TYPE_POST, POST_DEV_FAULTY, "FAULT"}, + {OCMP_MSG_TYPE_POST, POST_DEV_CRITICAL_FAULT, "CRITICAL FAULT"}, + {OCMP_MSG_TYPE_POST, POST_DEV_NO_DRIVER_EXIST, "NO DRIVER EXIST"} +}; +/****************************************************************************** + * Function Name : ocmw_free_global_pointer + * Description : This Function used to free the memory allocated for + * global variable + * Input(s) : ptr + * Output(s) : +******************************************************************************/ +inline void ocmw_free_global_pointer(void **ptr) +{ + if(*ptr != NULL) { + free(*ptr); + *ptr = NULL; + } + return; +} +/****************************************************************************** + * Function Name : ocmw_retrieve_post_results_count + * Description : This Function used to count the post structure size + * Input(s) : postResult + * Output(s) : + ******************************************************************************/ +char ocmw_retrieve_post_results_count (ocwarePostResults *postResult) +{ + postResult->count = + sizeof(ocwarePostArray)/sizeof(ocwarePostArray[0]); + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_retrieve_post_results + * Description : This Function used to get the post results + * Input(s) : postResult + * Output(s) : + ******************************************************************************/ +char ocmw_retrieve_post_results (ocwarePostResults *postResult) +{ + memcpy(postResult->results, ocwarePostArray, + postResult->count * sizeof(ocwarePostResultData)); + memset(ocwarePostArray,0,sizeof(ocwarePostResultData)); + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_retrieve_reply_code_desc + * Description : This Function used to get the reply code based the post + result data + * Input(s) : replyCode + * Output(s) : + ******************************************************************************/ +char ocmw_retrieve_reply_code_desc (ocwarePostReplyCode *replyCode) +{ + int32_t postSize = 0; + int32_t sysIndex = 0; + + postSize = sizeof(ocmwReplyCode)/sizeof(ocmwReplyCode[0]); + + for (sysIndex = 0; sysIndex < postSize; sysIndex++) { + if ((ocmwReplyCode[sysIndex].msgtype == replyCode->msgtype) && + (ocmwReplyCode[sysIndex].replycode == replyCode->replycode)) { + memset(replyCode->desc, 0, OCMW_POST_DESC_SIZE); + strncpy(replyCode->desc, ocmwReplyCode[sysIndex].desc, + strlen(ocmwReplyCode[sysIndex].desc)); + } + } + + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_update_post_status + * Description : This Function used to update the post results + * Input(s) : subsystem, devsn, status + * Output(s) : + ******************************************************************************/ +char ocmw_update_post_status(uint8_t subsystem, uint8_t devsn, + uint8_t status) +{ + int32_t sysIndex = 0; + for (sysIndex = 0; sysIndex < ocwarePostArrayIndex; sysIndex++) { + if ((ocwarePostArray[sysIndex].subsystem == subsystem) && + (ocwarePostArray[sysIndex].devsn == devsn)) { + ocwarePostArray[sysIndex].status = status; + } + } + + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_init + * Description : This Function used to initialize the mware + * Input(s) : + * Output(s) : + ******************************************************************************/ +int32_t ocmw_init() +{ +#ifdef INTERFACE_ETHERNET + pthread_t ethMsgPaserThreadId; +#else + pthread_t uartMsgPaserThreadId; +#endif + int32_t ret = 0; + ret = sem_init(&semecMsgParser, 0, 0); + if (ret != 0) { + logerr("sem_init(): semecMsgParser failed."); + return ret; + } + + ret = ocwdg_init(); + if (ret != 0) { + logerr("ocwdg_init() failed."); + return ret; + } + + ret = sem_init(&semCliReturn, 0, 0); + if (ret != 0) { + logerr("sem_init(): semCliReturn failed."); + return ret; + } + + ret = sem_init(&semCommandPost, 0, 0); + if (ret != 0) { + logerr("sem_init(): semCommandPost failed."); + return ret; + } else { +#ifdef INTERFACE_ETHERNET + /* Create the msg parser thread to parse + * the msg coming from ethernet ec to ap + */ + ret = pthread_create(ðMsgPaserThreadId, NULL, + ocmw_thread_ethmsgparser, NULL); + if (ret != 0) { + return ret; + } +#else + /* Create the msg parser thread to parse + * the msg coming from uart ec to ap + */ + ret = pthread_create(&uartMsgPaserThreadId, NULL, + ocmw_thread_uartmsgparser, NULL); + if (ret != 0) { + logerr("pthread_create() failed."); + } +#endif /* INTERFACE_ETHERNET */ + } + return ret; +} + +/************************************************************************** + * Function Name : ocmw_tokenize_class_str + * Description : This Function used to extract the Subsystem,componentID, Messagetype, + * parameter and Subcomponent from the param string + * Input(s) : str + * Output(s) : msgFrame + ***************************************************************************/ +static int32_t ocmw_tokenize_class_str( const int8_t *str, + strMsgFrame *msgFrame, uint8_t msgtype) +{ + char *token; + int32_t count = 0; + char *tempstr = (char *)malloc(PARAM_STR_MAX_BUFF_SIZE); + + if(str == NULL) + return FAILED; + + memset(tempstr,0,PARAM_STR_MAX_BUFF_SIZE); + memcpy(tempstr, str,PARAM_STR_MAX_BUFF_SIZE); + memset(msgFrame,0,sizeof(strMsgFrame)); + + token = strtok(tempstr, " ."); + + if (token == NULL) + return FAILED; + + if (msgtype == OCMP_MSG_TYPE_COMMAND) { + if ((strcmp(token,"set") != 0) && + ((strcmp(token,"get") != 0))) { + strcpy(msgFrame->parameter, token); + while (token) { + if (count == 1) { + strcpy(msgFrame->subsystem, token); + } else if (count == 2) { + strcpy(msgFrame->component, token); + } + token = strtok(NULL, " ."); + count ++; + if (token == NULL) + break; + } + if (count == 2) { + strcpy(msgFrame->component, "comp_all"); + } + } else { + while (token) { + if (count == 1) { + strcpy(msgFrame->subsystem, token); + } else if (count == 2) { + strcpy(msgFrame->component, token); + } else if (count == 3) { + strcpy(msgFrame->subcomponent, token); + } else if (count == 0) { + strcpy(msgFrame->parameter, token); + } + token = strtok(NULL, " ."); + count ++; + if (token == NULL) + break; + } + if (count == 2) { + strcpy(msgFrame->component, "comp_all"); + } + + } + } else { + strcpy(msgFrame->subsystem, token); + while (token) { + if (count == 1) { + strcpy(msgFrame->component, token); + } else if (count == 2) { + strcpy(msgFrame->msgtype, token); + } else if (count == 3) { + strcpy(msgFrame->subcomponent, token); + } else if(count == 4) { + strcpy(msgFrame->parameter, token); + } + token = strtok(NULL, " ."); + count++; + } + if (count < 5) { + strcpy(msgFrame->parameter, msgFrame->subcomponent); + } + + if (strncmp (msgFrame->component, "post", strlen("post")) == 0) { + strcpy(msgFrame->component, "post"); + strcpy(msgFrame->msgtype, "post"); + strcpy(msgFrame->parameter, msgFrame->subcomponent); + } + } + + free(tempstr); + + return SUCCESS; +} +/****************************************************************************** + * Function Name : ocmw_fill_payload_data_for_commands + * Description : Packetize the msg payload for commands + * Input(s) :strTokenArray, msgFrame, ecMsgFrame, paramVal + * Output(s) : + ******************************************************************************/ +void ocmw_fill_payload_data_for_commands(char * strTokenArray[], + strMsgFrame *msgFrame, OCMPMessageFrame *ecMsgFrame, void* paramVal) +{ + if (msgFrame == NULL) { + return; + } + // Handling sending data for test module + if (strncmp("testmodule", msgFrame->subsystem, + strlen(msgFrame->subsystem)) == 0 ) { + if ((strncmp(strTokenArray[1], "send", strlen("send")) == 0) || + (strncmp(strTokenArray[1], "dial", strlen("dial")) == 0)) { + memcpy(&ecMsgFrame->message.info[0], paramVal, + MAX_PARM_COUNT); + } else { + memset(ecMsgFrame->message.info, 0, MAX_PARM_COUNT); + } + } + // Handling ethernet packet genrator command + if (strncmp("ethernet", msgFrame->subsystem, + strlen(msgFrame->subsystem)) == 0 ) { + if(strstr(strTokenArray[1], "loopBk")) { + memcpy(&ecMsgFrame->message.info[0], paramVal, sizeof(uint8_t)); + } else if ((strncmp(strTokenArray[1], "en_pktGen", + strlen("en_pktGen")) == 0)) { + memcpy(&ecMsgFrame->message.info[0], + (uint16_t *)paramVal, sizeof(uint16_t)); + } + } +} +/****************************************************************************** + * Function Name : ocmw_msg_packetize_and_send + * Description : Packetize the msg frame before sending data to ec + * Input(s) :actionType, msgType, paramStr, interface, paramVal + * Output(s) : + ******************************************************************************/ +int32_t ocmw_msg_packetize_and_send(char * strTokenArray[], uint8_t action, + uint8_t msgType, const int8_t * paramStr, uint8_t interface, void* paramVal) +{ + int32_t ret = 0; + int32_t paramValue = 0; + int32_t dataSize = 0; + int32_t pos = 0; + int32_t paramValLen = 0; + int32_t paramValFlag = 0; + const int8_t *tempStr = paramStr; + strMsgFrame msgFramestruct; + OCMPMessageFrame ecMsgFrame; + OCMPHeader ecMsgHeader; + OCMPMessage ecCoreMsg; + + static int32_t loopCountSend = 0; + ocmwSchemaSendBuf ecSendBuf; + + paramValLen = strlen((char *)paramVal); + if (!((msgType == OCMP_MSG_TYPE_COMMAND) && + ((strncmp(strTokenArray[1], "get", strlen("get")) == 0) || + (strncmp(strTokenArray[1], "set", strlen("get")) == 0)))) { + if (paramValLen == 1 || paramValLen <= 5) { + logdebug ("Paramvalue is of integer type : %d\n", atoi( paramVal)); + } + else { + paramValFlag = 1; + logdebug ("Paramvalue is of string type : %s \n", (char *)paramVal); + } + } else { + paramValFlag = 1; + logdebug ("Paramvalue is of string type : %s \n", (char *)paramVal); + } + + if (paramStr == NULL) { + logdebug(" Paramstr is NULL \n"); + return ret = FAILED; + } else { + + ocmw_tokenize_class_str(tempStr,&msgFramestruct,msgType); + if (msgType == OCMP_MSG_TYPE_COMMAND) { + ret = ocmw_parse_command_msgframe(sys_schema, &msgFramestruct, + action, &ecSendBuf); + } else if (msgType == OCMP_MSG_TYPE_POST) { + strcpy((char*)s_paramInfoBackup,msgFramestruct.parameter); + ret = ocmw_parse_post_msgframe(sys_schema, &msgFramestruct, + action, &ecSendBuf); + } else { + ret = ocmw_parse_msgframe(sys_schema, &msgFramestruct, action, + &ecSendBuf); + } + if (ret < 0) { + return ret; + } + } + + /* Frame the header packet for sending data to ec */ + ecMsgHeader.ocmpFrameLen = 0; + ecMsgHeader.ocmpInterface = interface; + ecMsgHeader.ocmpSeqNumber = 0; + ecMsgHeader.ocmpSof = OCMP_MSG_SOF; + ecMsgHeader.ocmpTimestamp = 0; + + /* Frame the Core packet for sending data to ec */ + ecCoreMsg.action = ecSendBuf.actionType; + ecCoreMsg.msgtype = ecSendBuf.msgType; + ecCoreMsg.componentID = ecSendBuf.componentId; + ecCoreMsg.parameters = ecSendBuf.paramId; + ecCoreMsg.subsystem = ecSendBuf.subsystem; + + /* Construct the final packet */ + ecMsgFrame.header = ecMsgHeader; + ecMsgFrame.message = ecCoreMsg; + + /* Populate the Core packet payload */ + ecMsgFrame.message.info = (int8_t *) malloc( + sizeof(int8_t) * MAX_PARM_COUNT); + if (ecMsgFrame.message.info == NULL) { + logdebug("\n Memory allocation failed \n"); + return ret = FAILED; + } + memset(ecMsgFrame.message.info, 0, MAX_PARM_COUNT); + if ((msgType == OCMP_MSG_TYPE_POST) && + (strncmp(strTokenArray[1], "set", strlen("set"))== 0)) { + logdebug("OCMP_MSG_TYPE_POST:ENABLE:%s()\n", __func__); + } + if(strncmp(msgFramestruct.subsystem,"debug",strlen("debug")) == 0) { + if (strncmp(msgFramestruct.component,"I2C", + strlen("I2C")) == 0) { + if((strncmp(strTokenArray[1], "get", strlen("get")) == 0)) { + dataSize = 3 * sizeof (int8_t); + } else { + dataSize = sizeof(debugI2CData); + } + } else if (strncmp(msgFramestruct.component,"ethernet", + strlen("ethernet")) == 0) { + if((strncmp(strTokenArray[1], "get", strlen("get")) == 0)) { + dataSize = sizeof (uint16_t); + } else { + dataSize = sizeof(debugMDIOData); + } + } else { + if((strncmp(strTokenArray[1], "get", strlen("get")) == 0)) { + dataSize = sizeof (int8_t); + } else { + dataSize = sizeof(debugGPIOData); + } + } + paramValLen = dataSize; + } else { + dataSize = ecSendBuf.paramSize; + } + if((strncmp(strTokenArray[1], "set", strlen("set")) == 0) && + (msgType != OCMP_MSG_TYPE_POST)) { + pos = ecSendBuf.paramPos; + if (paramValFlag == 0) { + paramValue = atoi( paramVal); + memcpy(&ecMsgFrame.message.info[pos], ¶mValue, dataSize); + } else { + if (strncmp(msgFramestruct.component,"I2C", + strlen("I2C")) == 0) { + ecMsgFrame.message.info[pos] = I2CInfo.slaveAddress; + ecMsgFrame.message.info[pos + 1] = + I2CInfo.numOfBytes; + ecMsgFrame.message.info[pos + 2] = + I2CInfo.regAddress; + if (I2CInfo.numOfBytes == 1) { + ecMsgFrame.message.info[pos + 3] = + (uint8_t)I2CInfo.regValue; + } else { + ecMsgFrame.message.info[pos + 4] = + (uint8_t)(I2CInfo.regValue & 0xff); + ecMsgFrame.message.info[pos + 3] = + (uint8_t) + ((I2CInfo.regValue & 0xff00) >> 8); + } + } else if (strncmp(msgFramestruct.component,"ethernet", + strlen("ethernet")) == 0) { + ecMsgFrame.message.info[pos] = (uint8_t) + (MDIOInfo.regAddress & 0xff); + ecMsgFrame.message.info[pos + 1] = (uint8_t) + ((MDIOInfo.regAddress & 0xff00) >> 8); + ecMsgFrame.message.info[pos + 2] = + (uint8_t)(MDIOInfo.regValue & 0xff); + ecMsgFrame.message.info[pos + 3] = + (uint8_t) + ((MDIOInfo.regValue & 0xff00) >> 8); + + } else { + memcpy(&ecMsgFrame.message.info[pos], (char *) paramVal, + paramValLen); + } + } + } + if((strncmp(strTokenArray[1], "get", strlen("get")) == 0) && + (ecMsgFrame.message.subsystem == DEBUG_SUBSYSTEM_NBR)) { + pos = ecSendBuf.paramPos; + memcpy(&ecMsgFrame.message.info[pos], (char *) paramVal, + paramValLen); + + } + //Fill payload data for commands + ocmw_fill_payload_data_for_commands(&strTokenArray[0], &msgFramestruct, + &ecMsgFrame, paramVal); + + if (!((msgType == OCMP_MSG_TYPE_POST) && + (strncmp(strTokenArray[1], "get", strlen("get")) == 0))) { + ocmw_send_msg(ecMsgFrame, interface); + } + + /* Wait on the POST msgtype semaphore */ + if ((msgType == OCMP_MSG_TYPE_POST) && + ((strncmp(strTokenArray[1], "get", strlen("get")) == 0))) { + ocmw_frame_subsystem_from_schema(sys_schema, &systemInfo); + s_totalSubsystem = systemInfo.totalNum; + ocmw_frame_postTable_from_schema(sys_schema); + loopCountSend = systemInfo.Info[0].number; + loopCountPost = systemInfo.Info[0].number; + + while(loopCountSend < s_totalSubsystem) { + memset(&(ecMsgFrame.message.info[0]), + loopCountSend, 1); + /* Send the message to ec */ + ocmw_send_msg(ecMsgFrame, interface); + loopCountSend++; + + /* Waiting on the lock to be released by receiving thread */ + ret = ocmw_sem_wait(&semCommandPost, OCMW_TIMED_WAIT_INDEX); + if (ret != 0) { + perror("sem_wait"); + } + + /* + * Logic to check if firmware has sent post data currently we + * expect only actiontype mismatch other errors can be taken care + * as required + */ + if (loopCountSend != loopCountPost) { + logerr("POST: Error : Actiontype mismatch in message from FW"); + free(ecMsgFrame.message.info); + return FAILED; + } + } + loopCountPost = systemInfo.Info[0].number; + loopCountSend = systemInfo.Info[0].number; + } + + free(ecMsgFrame.message.info); + + /* Semaphore wait function call */ + ret = ocmw_sem_wait(&semCliReturn, OCMW_TIMED_WAIT_INDEX); + if (ret == FAILED) { + logdebug("Message is not received from EC: releasing the lock \n"); + return ret; + } + + if (responseCount == 0) { + ret = FAILED; + } else { + ret = 0; + responseCount = 0; + } + logdebug(" \n Semaphore released : %s() \n", __func__); + + return ret; +} + +/****************************************************************************** + * Function Name : ocmw_thread_uartmsgparser + * Description : Thread to parse the data coming from EC to AP + * through uart communication + * Input(s) : pthreadData + * Output(s) : + ******************************************************************************/ +void * ocmw_thread_uartmsgparser(void *pthreadData) +{ + logdebug("Uart task created \n"); + while (1) { + /* Waiting on the semecMsgParser to be released by uart */ + sem_wait(&semecMsgParser); + ocmw_ec_msgparser(); + } +} + +/****************************************************************************** + * Function Name : ocmw_thread_ethmsgparser + * Description : Thread to parse the data coming from EC to AP + * through ethernet communication + * Input(s) : pthreadData + * Output(s) : + ******************************************************************************/ +void * ocmw_thread_ethmsgparser(void *pthreadData) +{ + int8_t ethRecvBuf[OCMP_MSG_SIZE] = {0}; + + logdebug("Ethernet task created \n"); + while (1) { + memset(ethRecvBuf, 0, sizeof(ethRecvBuf)); + ocmw_recv_eth_msgfrom_ec(ethRecvBuf, sizeof(ethRecvBuf),OCMW_EC_DEV); + ocmw_ec_msgparser(); + } +} + +/****************************************************************************** + * Function Name : ocmw_ec_msgparser + * Description : parse the data coming from EC to AP + * Input(s) : + * Output(s) : + ******************************************************************************/ +void ocmw_ec_msgparser(void) +{ + uint8_t msgType = 0; + uint8_t actionType = 0; + uint8_t subsystemPost = 0; + uint8_t devsn = 0; + uint8_t status = 0; + uint8_t indexCount = 0; + uint16_t paramInfo = 0; + int32_t ret = 0; + int32_t sendPktNonpayloadSize = 0; + sMsgParam dmsgFrameParam; + OCMPMessageFrame ecReceivedMsg; + + sendPktNonpayloadSize = (sizeof(OCMPMessage) - sizeof(void *) + + sizeof(OCMPHeader)); + + ecReceivedMsg.message.info = (void *) malloc( + sizeof(char) * MAX_PARM_COUNT); + if (ecReceivedMsg.message.info == NULL) { + logerr("Memory allocation failed for " + "ecReceivedMsg.message.info \n"); + + return; + } + + /* parse the data packet */ + memcpy((void *) &ecReceivedMsg, (void *) mcuMsgBuf, sendPktNonpayloadSize); + memcpy(ecReceivedMsg.message.info, &mcuMsgBuf[sendPktNonpayloadSize], + MAX_PARM_COUNT); + + msgType = ecReceivedMsg.message.msgtype; + actionType = ecReceivedMsg.message.action; + paramInfo = ecReceivedMsg.message.parameters; + + /* + * TODO:Temporary fix for handling alerts + */ + if (msgType == OCMP_MSG_TYPE_ALERT) { + free(ecReceivedMsg.message.info); + return; + } + + printf("Received from ec :\n"); + for (indexCount = 0; indexCount < OCMP_MSG_SIZE; indexCount++) { + printf("0x%x ", mcuMsgBuf[indexCount]); + } + printf("\n"); + + /* In case of timeout, return from the thread + * without processing the data to avoid sync issue. + */ + if (s_semTimeOut) { + s_semTimeOut = 0; + ocmw_free_global_pointer((void**)&ecSendBufBkp); + return; + } + + if ((msgType == OCMP_MSG_TYPE_POST) && + strcmp((char*)s_paramInfoBackup,"set") == 0) { + if (actionType == OCMP_AXN_TYPE_REPLY) { + responseCount++; + } + /* Release the lock on which cli is waiting */ + ocmw_free_global_pointer((void**)&ecSendBufBkp); + sem_post(&semCliReturn); + return; + } + + /* Release the lock on the POST msgtype semaphore */ + if (msgType == OCMP_MSG_TYPE_POST) { + if (actionType != OCMP_AXN_TYPE_REPLY) { + ocmw_free_global_pointer((void**)&ecSendBufBkp); + ret = sem_post(&semCommandPost); + if (ret != 0) { + perror("sem_wait"); + } + return; + } + + for (; loopCountPost < s_totalSubsystem;) { + /* Waiting on the lock to be released by receiving thread */ + for (indexCount = 0; indexCount < paramInfo; indexCount++) { + subsystemPost = ecReceivedMsg.message.info[indexCount + * POST_MAIN_PAYLOAD_SIZE + + POST_MAIN_PAYLOAD_SUBSYSTEM_OFFSET]; + devsn = ecReceivedMsg.message.info[indexCount + * POST_MAIN_PAYLOAD_SIZE + + POST_MAIN_PAYLOAD_DEVSN_OFFSET]; + status = ecReceivedMsg.message.info[indexCount + * POST_MAIN_PAYLOAD_SIZE + + POST_MAIN_PAYLOAD_STATUS_OFFSET]; + ret = ocmw_update_post_status(subsystemPost, devsn, status); + } + + loopCountPost++; + + ret = sem_post(&semCommandPost); + if (ret != 0) { + perror("sem_wait"); + } + if (loopCountPost < s_totalSubsystem) { + /* Do Nothing */ + } else { + /* Release the lock on which watchdog thread is waiting */ + responseCount++; + ocmw_free_global_pointer((void**)&ecSendBufBkp); + sem_post(&semCliReturn); + } + return; + } + } + + memset(&dmsgFrameParam, 0, sizeof(sMsgParam)); + ocmw_deserialization_msgframe(sys_schema, &dmsgFrameParam, &ecReceivedMsg); + /* Released the lock so that cli is released from the lock */ + if (ecReceivedMsg.message.info) { + free(ecReceivedMsg.message.info); + } + sem_post(&semCliReturn); +} + +/****************************************************************************** + * Function Name : ocmw_send_msg + * Description : Send the message from ap to ec via uart/usb/ethernet. + * Input(s) : ecMsgFrame, interface + * Output(s) : + ******************************************************************************/ +int32_t ocmw_send_msg(OCMPMessageFrame ecMsgFrame, uint8_t interface) +{ + int32_t ret = 0; + int32_t sentDev = OCMW_EC_DEV; +#ifdef INTERFACE_STUB_EC + int8_t ethRecvBuf[OCMP_MSG_SIZE]; +#endif + switch (interface) { + case OCMP_COMM_IFACE_UART: + case OCMP_COMM_IFACE_USB: + /* Send the packetize data to ec through uart*/ + ret = ocmw_send_uart_msg_to_ec((uint8_t *) &ecMsgFrame, + OCMP_MSG_SIZE); + break; + + case OCMP_COMM_IFACE_ETHERNET: + sentDev = OCMW_EC_DEV; +#ifdef INTERFACE_STUB_EC + sentDev = OCMW_EC_STUB_DEV; +#else + sentDev = OCMW_EC_DEV; +#endif + /* Send the packetize data to ec through ethernet*/ + ret = ocmw_send_eth_msgto_ec((int8_t *) &ecMsgFrame, + OCMP_MSG_SIZE, sentDev); +#ifdef INTERFACE_STUB_EC + memset(ethRecvBuf, 0, sizeof(ethRecvBuf)); + ocmw_recv_eth_msgfrom_ec(ethRecvBuf, sizeof(ethRecvBuf), OCMW_EC_STUB_DEV); + ocmw_ec_msgparser(); +#endif + break; + + case OCMP_COMM_IFACE_SBD: + break; + default: + break; + } + + if (ret != 0) { + logerr("ocmw_send_msg() failed \n"); + } + return ret; +} + +/****************************************************************************** + * Function Name : ocmw_sem_wait + * Description : semaphore wait function to wait either for infinite time + * or for timeout period. + * Input(s) : semId, semWaitType + * Output(s) : + ******************************************************************************/ +int32_t ocmw_sem_wait(sem_t *semId, int32_t semWaitType) +{ + int32_t ret = 0; + struct timespec timeSpecObj; + + if (semId == NULL) { + logerr("Invalid semId \n"); + ret = FAILED; + return ret; + } + + if (semWaitType == OCMW_BUSY_WAIT_INDEX) { + /* Waiting on the lock to be released by receiving thread */ + ret = ocmw_sem_wait_nointr(semId); + if (ret != 0) { + perror("sem_wait"); + } + } else if (semWaitType == OCMW_TIMED_WAIT_INDEX) { + ret = clock_gettime(CLOCK_REALTIME, &timeSpecObj); + if (ret != 0) { + perror("clock_gettime"); + } + timeSpecObj.tv_sec += OCMW_SEM_WAIT_TIME; + timeSpecObj.tv_nsec += 0; + + ret = ocmw_sem_timedwait_nointr(semId, &timeSpecObj); + if (ret != 0) { + if (errno == ETIMEDOUT) { + logdebug("sem_timedwait() timed out\n"); + } else { + perror("sem_timedwait"); + } + logdebug("Message is not received from EC: releasing the lock \n"); + s_semTimeOut = 1; + } + } else { + printf("Invalid param \n"); + } + return ret; +} diff --git a/firmware/host/ocmw/ocmw_eth_comm.c b/firmware/host/ocmw/ocmw_eth_comm.c new file mode 100644 index 0000000000..2dd8e75286 --- /dev/null +++ b/firmware/host/ocmw/ocmw_eth_comm.c @@ -0,0 +1,236 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include + +/* OC includes */ +#include +#include +#include +#include + +#define OCMW_ERR_STR_LEN 80 +#define OCWARE_STUB_TIMEOUT_PERIOD 12 + +extern uint8_t mcuMsgBuf[OCMP_MSG_SIZE]; + +static int32_t comSockfd = 0, stub_sockfd = 0; +static struct sockaddr_in sicomServer, stub_server; + +/************************************************************************** + * Function Name : ocmw_init_eth_comm + * Description : This Function used to initialize the ethernet + * communication + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t ocmw_init_eth_comm(int32_t sentDev) +{ + int32_t rc = 0; + int32_t inetAton = 0; + printf("Ethernet init start \n"); + struct timeval timeValObj; + timeValObj.tv_sec = OCWARE_STUB_TIMEOUT_PERIOD; + timeValObj.tv_usec = 0; + if (sentDev == OCMW_EC_DEV){ + /* Create socket */ + comSockfd = socket(OCMW_ETH_SOCK_DOMAIN, OCMW_ETH_SOCK_TYPE, + OCMW_ETH_SOCK_PROTOCOL); + if (comSockfd < 0) { + rc = -errno; + logerr("socket creation error [%d-%s]", errno, strerror(errno)); + } + + /* Initialize socket structure */ + memset(&sicomServer, 0, sizeof(sicomServer)); + sicomServer.sin_family = OCMW_ETH_SOCK_DOMAIN; + sicomServer.sin_port = htons(OCMW_ETH_SOCK_SERVER_PORT); + inetAton = inet_aton(OCMW_ETH_SOCK_SERVER_IP, &sicomServer.sin_addr); + if (inetAton == 0) { + printf("inet_aton failed"); + rc = -1; + } + + rc = connect(comSockfd, (struct sockaddr *) &sicomServer, + sizeof(sicomServer)); + if (rc != 0) { + perror("socket connect failed:"); + } + + if (rc != 0) { + ocmw_deinit_eth_comm(OCMW_EC_DEV); + } else { + printf("Ehernet init finished \n"); + } + } else { + /* Create socket */ + stub_sockfd = socket(OCMW_SOCK_STUB_DOMAIN, OCMW_SOCK_STUB_TYPE, + OCMW_SOCK_STUB_PROTOCOL); + if (stub_sockfd < 0) { + rc = -errno; + logerr("socket creation error [%d-%s]", errno, strerror(errno)); + } + + /* Initialize socket structure */ + memset(&stub_server, 0, sizeof(stub_server)); + stub_server.sin_family = OCMW_SOCK_STUB_DOMAIN; + stub_server.sin_port = htons(OCMW_SOCK_STUB_SERVER_PORT); + stub_server.sin_addr.s_addr = inet_addr(OCMW_SOCK_SERVER_IP); + inetAton = inet_aton(OCMW_SOCK_STUB_SERVER_IP, &stub_server.sin_addr); + if (inetAton == 0) { + printf("inet_aton failed"); + rc = -1; + } + + if (setsockopt(stub_sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeValObj, + sizeof(timeValObj)) < 0) { + logerr("setsockopt failed"); + rc = -1; + return rc; + } + + if (rc != 0) { + ocmw_deinit_eth_comm(OCMW_EC_STUB_DEV); + } else { + printf("Ehernet init finished \n"); + } + } + return rc; +} + +/************************************************************************** + * Function Name : ocmw_deinit_eth_comm + * Description : This Function used to uninitialize the ethernet + * communication + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t ocmw_deinit_eth_comm( int sentDev) +{ + if (sentDev == OCMW_EC_DEV){ + close(comSockfd); + comSockfd = 0; /* Close the IPC socket */ + } else { + close(stub_sockfd); + stub_sockfd = 0; /* Close the IPC socket */ + } + return 0; +} + +/************************************************************************** + * Function Name : ocmw_send_eth_msgto_ec + * Description : This Function used to send the message to ec + * Input(s) : cmd, cmdlen + * Output(s) : + ***************************************************************************/ +int32_t ocmw_send_eth_msgto_ec(const int8_t *cmd, int32_t cmdlen, int sentDev) +{ + const int32_t errstrLen = OCMW_ERR_STR_LEN; + char errstr[errstrLen]; + uint8_t buf[OCMP_MSG_SIZE]; + int32_t rc = 0; + int32_t loopCount = 0; + int32_t sendPktNonpayloadSize = 0; + OCMPMessageFrame *ecMsgFrame; + + if (cmd == NULL) { + logerr("Error: Memory allocation problem"); + return -1; + } + if (cmdlen > OCMP_MSG_SIZE) { + logerr("Error: msgstr size is more than %d bytes", OCMP_MSG_SIZE); + return -EMSGSIZE; + } + + ecMsgFrame = (OCMPMessageFrame *) cmd; + sendPktNonpayloadSize = (sizeof(OCMPMessage) - sizeof(void *) + + sizeof(OCMPHeader)); + + /* create message frame */ + memset(buf, 0, sizeof(buf)); + memcpy(buf, ecMsgFrame, sendPktNonpayloadSize); + memcpy(&buf[sendPktNonpayloadSize], ((ecMsgFrame->message).info), + MAX_PARM_COUNT); +#ifndef MSG_LOG + printf(" \n send_msg_to_ec \n"); + for (loopCount = 0; loopCount < OCMP_MSG_SIZE; loopCount++) { + printf("0x%x ", buf[loopCount] & 0x00ff); + } + printf("\n"); +#endif /* MSG_LOG */ + + if (sentDev == OCMW_EC_DEV){ + rc = send(comSockfd, buf, OCMP_MSG_SIZE, 0); + if (rc < 0) { + strerror_r(errno, errstr, errstrLen); + logerr("Error: 'send' [%d-%s]", errno, errstr); + } + } else { + rc = sendto(stub_sockfd, buf, OCMP_MSG_SIZE, 0, + (struct sockaddr *) &stub_server, sizeof(stub_server) ); + if (rc < 0) { + strerror_r(errno, errstr, errstrLen); + logerr("Error: 'send' [%d-%s]", errno, errstr); + } + } + return rc; +} + +/************************************************************************** + * Function Name : ocmw_recv_eth_msgfrom_ec + * Description : This Function used to receive the ec message + * Input(s) : + * Output(s) : resp, resplen + ***************************************************************************/ +int32_t ocmw_recv_eth_msgfrom_ec(int8_t *resp, int32_t resplen, int sentDev) +{ +#if defined(INTERFACE_STUB_EC) || defined(INTERFACE_ETHERNET) + const int32_t errstrLen = OCMW_ERR_STR_LEN; + char errstr[errstrLen]; +#endif + int32_t rc = 0; + int32_t loopCount = 0; +#ifdef INTERFACE_STUB_EC + int32_t dataLen = sizeof(stub_server); +#endif + + /* + * Receive the CLI command execution response string from OCMW over + * UDP socket + */ +#ifdef INTERFACE_ETHERNET + rc = recv(comSockfd, resp, resplen, 0); + if (rc < 0) { + strerror_r(rc, errstr, errstrLen); + logerr("Error: 'recv' [%d-%s]", rc, errstr); + } +#endif +#ifdef INTERFACE_STUB_EC + rc = recvfrom(stub_sockfd, resp, OCMP_MSG_SIZE, 0, + (struct sockaddr *) &stub_server, + (socklen_t*)&dataLen); + if (rc < 0) { + strerror_r(rc, errstr, errstrLen); + logerr("Error: 'recv' [%d-%s]", rc, errstr); + printf("\n Error: Recv from in OCWARE_STUB"); + } +#endif + + /* Store the ethernet msg into global buffer */ + memcpy(mcuMsgBuf, resp, resplen); + + printf("Message received from ec via ethernet :\n"); + for (loopCount = 0; loopCount < resplen; loopCount++) { + printf("0x%x ", (0xff) & resp[loopCount]); + } + printf("\n"); + return rc; +} diff --git a/firmware/host/ocmw/ocmw_helper.c b/firmware/host/ocmw/ocmw_helper.c new file mode 100644 index 0000000000..e37429b477 --- /dev/null +++ b/firmware/host/ocmw/ocmw_helper.c @@ -0,0 +1,156 @@ +/** + + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* OC includes */ +#include +#include +#include +#include +#include +#include + +#define SIZE_INT sizeof (int32_t) + +int8_t eepromStatusFlag = 0; + +/****************************************************************************** + * Function Name : ocmw_sem_wait_nointr + * Description : static inline function for avoiding interruption caused + * to sem_wait() library call + * Input(s) : sem + * Output(s) : + ******************************************************************************/ +inline int32_t ocmw_sem_wait_nointr(sem_t *sem) +{ + while (sem_wait(sem)) + if (errno == EINTR) + errno = 0; + else + return -1; + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_sem_timedwait_nointr + * Description : static inline function for avoiding interruption caused + * to sem_timedwait() library call + * Input(s) : sem, timeout + * Output(s) : + ******************************************************************************/ +inline int32_t ocmw_sem_timedwait_nointr(sem_t *sem, + const struct timespec *timeout) +{ + while (sem_timedwait(sem, timeout)) + if (errno == EINTR) + errno = 0; + else + return -1; + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_dataparsing_from_db + * Description : This Function used to parase the data from db + * Input(s) : paramIndex, paramSizebuf + * Output(s) : dataSize, pos + ******************************************************************************/ +void ocmw_dataparsing_from_db(int32_t paramIndex, int32_t *paramSizebuf, + int32_t *dataSize, int32_t *pos) +{ + int32_t count; + int32_t paramIdPresence; + int32_t loc; + + count = 0; + paramIdPresence = 0; + loc = 0; + + if ((paramSizebuf == NULL) || (dataSize == NULL) || (pos == NULL)) { + return; + } + + *dataSize = 0; + *pos = 0; + + for (count = 0; count < MAX_PARM_COUNT; count++) { + paramIdPresence = (paramIndex) / ((int) pow(2, count)); + if (paramIdPresence == 1) { + break; + } + + else { + loc = loc + paramSizebuf[count]; + } + } + + *dataSize = paramSizebuf[count]; + *pos = loc; +} + +/****************************************************************************** + * Function Name : ocmw_dataparsing_from_ec + * Description : This Function used to parse the uart message from ec + * Input(s) : input, bufParamStruct + * Output(s) : + ******************************************************************************/ +void ocmw_dataparsing_from_ec(ocmwSendRecvBuf *input, + bufParam * bufParamStruct) +{ + int32_t count = 0; + int32_t paramIdPresence = 0; + int32_t pos = 0; + int32_t paramidSize = 0; + int32_t index = 0; + + if ((input == NULL) || (bufParamStruct == NULL)) { + printf("Memory address is invalid : %s()\n", __func__); + return; + } + + int16_t paramInfo = input->paramInfo; + int32_t numOfele = input->numOfele; + int8_t *pbuf = input->pbuf; + int32_t *paramSizebuf = input->paramSizebuf; + + for (count = 0; count < numOfele; count++) { + bufParamStruct[count].paramindex = (paramInfo & ((int32_t) pow(2, + count + index))); + + paramIdPresence = bufParamStruct[count].paramindex / pow(2, + count + index); + + if (paramIdPresence == 0) { + paramidSize = 0; + } else { + paramidSize = paramSizebuf[count]; + } + + switch (paramidSize) { + case VOID: + bufParamStruct[count].paramval = 0; + break; + case CHAR: + bufParamStruct[count].paramval = *((int8_t *) &pbuf[pos]); + break; + + case SHORT: + bufParamStruct[count].paramval = *((int16_t *) &pbuf[pos]); + break; + + case INT: + bufParamStruct[count].paramval = *((int32_t *) &pbuf[pos]); + break; + + default: + return; + break; + } + } +} diff --git a/firmware/host/ocmw/ocmw_main.c b/firmware/host/ocmw/ocmw_main.c new file mode 100644 index 0000000000..09b2eb5778 --- /dev/null +++ b/firmware/host/ocmw/ocmw_main.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include + +/* OC includes */ +#include +#include +#include +#include +#include + +uint8_t mcuMsgBuf[OCMP_MSG_SIZE]; + +/************************************************************************** + * Function Name : main + * Description : + * Input(s) : argc, argv + * Output(s) : + ***************************************************************************/ +int32_t main(int32_t argc, char **argv) +{ + char cmdstr[CMD_STR_BUFF_SIZE] = {0}; + char response[RES_STR_BUFF_SIZE] = {0}; + int32_t ret = 0; + + /* Initialize logging */ + initlog("ocmw"); + + ret = ocmw_init_occli_comm(); + if (ret != 0) { + logerr("init_occli_comm() failed."); + return FAILED; + } + + /* Initialize UART for EC communication */ + ret = ocmw_init_ec_comm(&ocmw_ec_uart_msg_hndlr); + if (ret != 0) { + logerr("ocmw_init_ec_comm() failed."); + return FAILED; + } + +#ifdef INTERFACE_ETHERNET + ret = ocmw_init_eth_comm(OCMW_EC_DEV); + if(ret != 0) { + printf ("ocmw_init_eth_comm() failed \n"); + return FAILED; + } +#endif /* INTERFACE_ETHERNET */ + +#ifdef INTERFACE_STUB_EC + ret = ocmw_init_eth_comm(OCMW_EC_STUB_DEV); + if(ret != 0) { + printf ("init_eth_comm() failed \n"); + return FAILED; + } +#endif /* INTERFACE_ETHERNET */ + + ret = ocmw_init(); + if (ret != 0) { + logerr("ocmw_init() failed."); + return FAILED; + } + + while (1) { + memset(cmdstr, 0, sizeof(cmdstr)); + memset(response, 0, sizeof(response)); + + ret = ocmw_recv_clicmd_from_occli(cmdstr, sizeof(cmdstr)); + if (ret == FAILED) + continue; /* retry on error */ + + ocmw_clicmd_handler(cmdstr, response); + ocmw_send_clicmd_resp_to_occli(response, strlen(response)); + } + + ocmw_deinit_occli_comm(); + ocmw_deinit_occli_alert_comm(); + ocmw_deinit_ec_comm(); + deinitlog(); + return SUCCESS; +} diff --git a/firmware/host/ocmw/ocmw_msgproc.c b/firmware/host/ocmw/ocmw_msgproc.c new file mode 100755 index 0000000000..69980f8b2a --- /dev/null +++ b/firmware/host/ocmw/ocmw_msgproc.c @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include +#include +#include + +#include +#include "ocmw_core.h" +#include "ocmw_msgproc.h" +#include "ocmp_frame.h" + +/************************************************************************** + * Function Name : ocmw_msgproc_send_msg + * Description : This Function configures the header + * Input(s) : strTokenArray, action, msgtype, paramstr + * Output(s) : paramvalue + ***************************************************************************/ +int ocmw_msgproc_send_msg(char * strTokenArray[], uint8_t action, + int8_t msgtype, const int8_t* paramstr, void *paramvalue) +{ + int32_t ret = 0; + uint8_t interface = 0; +#if defined(INTERFACE_STUB_EC) || defined(INTERFACE_ETHERNET) + interface = OCMP_COMM_IFACE_ETHERNET; +#elif INTERFACE_USB + interface = OCMP_COMM_IFACE_USB; +#else + interface = OCMP_COMM_IFACE_UART; +#endif /* INTERFACE_ETHERNET */ + ret = ocmw_msg_packetize_and_send(&strTokenArray[0], action, msgtype, + paramstr, interface, paramvalue); + if (ret != 0) { + logerr("ocmw_msg_packetize_and_send failed \n"); + } + return ret; +} + diff --git a/firmware/host/ocmw/ocmw_occli_comm.c b/firmware/host/ocmw/ocmw_occli_comm.c new file mode 100644 index 0000000000..c2f943b4e9 --- /dev/null +++ b/firmware/host/ocmw/ocmw_occli_comm.c @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* OC includes */ +#include +#include +#include + +static int32_t s_ssockFd = 0; +static struct sockaddr_in s_siServer, s_siClient; + +static int32_t s_ssockfdAlert = 0; +static struct sockaddr_in s_siServerAlert; + +/************************************************************************** + * Function Name : ocmw_init_occli_comm + * Description : This Function used to initialize the cli communication + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t ocmw_init_occli_comm() +{ + int32_t ret = 0; + + /* Create socket */ + s_ssockFd = socket(OCMW_SOCK_DOMAIN, OCMW_SOCK_TYPE, OCMW_SOCK_PROTOCOL); + if (s_ssockFd < 0) { + ret = -errno; + logerr("socket creation error [%d-%s]", errno, strerror(errno)); + return ret; + } + + /* Initialize socket structure */ + memset(&s_siServer, 0, sizeof(s_siServer)); + s_siServer.sin_family = OCMW_SOCK_DOMAIN; + s_siServer.sin_addr.s_addr = INADDR_ANY; + s_siServer.sin_port = htons(OCMW_SOCK_SERVER_PORT); + + /* Bind host address to the socket */ + ret = bind(s_ssockFd, (struct sockaddr*) &s_siServer, sizeof(s_siServer)); + if (ret < 0) { + ret = -errno; + logerr("bind error [%d-%s]", errno, strerror(errno)); + return ret; + } + + if (ret != 0) { + ocmw_deinit_occli_comm(); + return ret; + } + + /***** Alert related socket init *****/ + /* Create socket */ + s_ssockfdAlert = socket(OCMW_SOCK_DOMAIN, OCMW_SOCK_TYPE, + OCMW_SOCK_PROTOCOL); + if (s_ssockfdAlert < 0) { + ret = -errno; + logerr("socket creation error [%d-%s]", errno, strerror(errno)); + return ret; + } + + if (ret != 0) { + ocmw_deinit_occli_alert_comm(); + } else { + /* Initialize socket structure */ + memset(&s_siServerAlert, 0, sizeof(s_siServerAlert)); + s_siServerAlert.sin_family = OCMW_SOCK_DOMAIN; + s_siServerAlert.sin_addr.s_addr = INADDR_ANY; + s_siServerAlert.sin_port = htons(OCMW_SOCK_SERVER_ALERT_PORT); + } + return ret; +} + +/************************************************************************** + * Function Name : ocmw_deinit_occli_comm + * Description : This Function used to deinitialize the cli communication + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t ocmw_deinit_occli_comm(void) +{ + close(s_ssockFd); + s_ssockFd = 0; /* Close the IPC socket */ + return SUCCESS; +} + +/************************************************************************** + * Function Name : ocmw_deinit_occli_alert_comm + * Description : This Function used deinitialize the alert communication + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t ocmw_deinit_occli_alert_comm(void) +{ + close(s_ssockfdAlert); + s_ssockfdAlert = 0; /* Close the IPC socket */ + return SUCCESS; +} + +/************************************************************************** + * Function Name : ocmw_send_clicmd_resp_to_occli + * Description : This Function used to send command response to cli + * Input(s) : buf, buflen + * Output(s) : + ***************************************************************************/ +int32_t ocmw_send_clicmd_resp_to_occli(const char* buf, int32_t buflen) +{ + char errstr[OCMW_SOCKET_ERROR_SIZE]; + int32_t ret = 0; + int32_t destLen = sizeof(s_siClient); + + /* Send the message buffer over IPC */ + ret = sendto(s_ssockFd, buf, buflen, 0, + (const struct sockaddr *) &s_siClient, destLen); + if (ret == -1) { + strerror_r(errno, errstr, OCMW_SOCKET_ERROR_SIZE); + logerr("Error: 'sendto' [%d-%s]", errno, errstr); + } + return ret; /* error or number of bytes sent */ +} + +/************************************************************************** + * Function Name : ocmw_recv_clicmd_from_occli + * Description : This Function used to recv the command from cli + * Input(s) : buflen + * Output(s) : buf + ***************************************************************************/ +int32_t ocmw_recv_clicmd_from_occli(char* buf, int32_t buflen) +{ + char errstr[OCMW_SOCKET_ERROR_SIZE]; + int32_t ret = 0; + int32_t destLen = sizeof(s_siClient); + + /* Receive oc messages from other processes */ + ret = recvfrom(s_ssockFd, buf, buflen, 0, + (struct sockaddr*) &s_siClient, (socklen_t*) &destLen); + if (ret <= 0) { + strerror_r(errno, errstr, OCMW_SOCKET_ERROR_SIZE); + logerr("Error: 'recvfrom' [%d-%s]", errno, errstr); + ret = -1; + } + return ret; /* error or number of bytes received */ +} + +/************************************************************************** + * Function Name : ocmw_send_alert_to_occli + * Description : This Function used to send alerts to cli + * Input(s) : buf, buflen + * Output(s) : + ***************************************************************************/ +int32_t ocmw_send_alert_to_occli(const char* buf, int32_t buflen) +{ + char errstr[OCMW_SOCKET_ERROR_SIZE]; + int32_t ret = 0; + int32_t destLen = sizeof(s_siServerAlert); + + /* Send the message buffer over IPC */ + ret = sendto(s_ssockfdAlert, buf, buflen, 0, + (const struct sockaddr *) &s_siServerAlert, destLen); + if (ret == -1) { + strerror_r(errno, errstr, OCMW_SOCKET_ERROR_SIZE); + logerr("Error: 'sendto' [%d-%s]", errno, errstr); + } + return ret; /* error or number of bytes sent */ +} diff --git a/firmware/host/ocmw/ocmw_schema.c b/firmware/host/ocmw/ocmw_schema.c new file mode 100644 index 0000000000..2fbcc87dc1 --- /dev/null +++ b/firmware/host/ocmw/ocmw_schema.c @@ -0,0 +1,1104 @@ +#include +#include +#include + +int64_t recvdParamVal; +extern int32_t responseCount; +int32_t eepromFlag; +static int32_t s_typeFlag; +char dataOutBufFromEc[PARAM_STR_BUFF_SIZE] = {0}; +static char *s_paramEnumValue[OCMW_VALUE_TYPE_MFG] = {0}; +ocmwSchemaSendBuf *ecSendBufBkp; +ocwarePostResultData ocwarePostArray[TEMP_STR_BUFF_SIZE] = {{0}}; +uint8_t ocwarePostArrayIndex; +/****************************************************************************** + * Function Name : ocmw_parse_eepromdata_from_ec + * Description : parse the eeprom data coming from EC to AP + * Input(s) : ecInputData + * Output(s) : + ******************************************************************************/ +int8_t ocmw_parse_eepromdata_from_ec (ocmwSendRecvBuf ecInputData) +{ + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + if (ecInputData.msgType == OCMP_MSG_TYPE_STATUS) { + memcpy(dataOutBufFromEc, &ecInputData.pbuf[ecSendBufBkp->paramPos], + sizeof(ecInputData.pbuf)); + }else if (ecInputData.msgType == OCMP_MSG_TYPE_CONFIG) { + memcpy(dataOutBufFromEc, ecInputData.pbuf, EEPROM_CONFIG_SIZE); + } + + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_parse_testingmodule_struct_from_ec + * Description : parse the testmodule struct data coming from EC to AP + * Input(s) : ecInputData + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_testingmodule_struct_from_ec(ocmwSendRecvBuf ecInputData) +{ + uint32_t paramVal2 = 0; + eOperatorStat paramVal = 0; + size_t size = 0; + + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + size = sizeof(dataOutBufFromEc); + + paramVal = *((uint8_t *) + &(ecInputData.pbuf[TWO_G_SIM_NET_OPTR_STATUS_OFFSET])); + paramVal2 = *((uint16_t *) ecInputData.pbuf); + switch (paramVal) { + case TWOG_SIM_STAT_UNKNOWN: + snprintf(dataOutBufFromEc, size, + "Operator code : %u Operator status : %u(STAT_UNKNOWN)", + paramVal2, paramVal); + break; + + case TWOG_SIM_STAT_AVAILABLE: + snprintf(dataOutBufFromEc, size, + "Operator code : %u Operator status : %u(STAT_AVAILABLE)", + paramVal2, paramVal); + break; + + case TWOG_SIM_STAT_CURRENT: + snprintf(dataOutBufFromEc, size, + "Operator code : %u Operator status : %u(STAT_CURRENT)", + paramVal2, paramVal); + break; + + case TWOG_SIM_STAT_FORBIDDEN: + snprintf(dataOutBufFromEc, size, + "Operator code : %u Operator status : %u(STAT_FORBIDDEN)", + paramVal2, paramVal); + break; + + default: + break; + } + + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_parse_obc_struct_from_ec + * Description : parse the obc data coming from EC to AP + * Input(s) : ecInputData + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_obc_struct_from_ec(ocmwSendRecvBuf ecInputData) +{ + uint32_t paramVal2 = 0; + Source paramVal = 0; + size_t size = 0; + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + size = sizeof(dataOutBufFromEc); + + paramVal = (ecInputData.pbuf[ecSendBufBkp->paramPos]); + paramVal2 = *((uint16_t *) + &(ecInputData.pbuf[IRIDIUM_LASTERR_ERROR_CODE_OFFSET])); + switch (paramVal) { + case ERR_RC_INTERNAL: + snprintf(dataOutBufFromEc, size, + "Error Source : %u(ERR_RC_INTERNAL) Error Code : %u", + paramVal, paramVal2); + break; + + case ERR_SRC_CMS: + snprintf(dataOutBufFromEc, size, + "Error Source : %u(ERR_SRC_CMS) Error Code : %u", + paramVal, paramVal2); + break; + + case ERR_SRC_CME: + snprintf(dataOutBufFromEc, size, + "Error Source : %u(ERR_SRC_CME) Error Code : %u", + paramVal, paramVal2); + break; + + default: + break; + } + + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_get_paramSize + * Description : get the parameter size as per schema + * Input(s) : paramtype, msgtype, param_name + * Output(s) : + ******************************************************************************/ +int8_t ocmw_get_paramSize(const char* paramtype, int8_t msgtype, + const char* param_name) +{ + int8_t paramSize = 0; + + if (paramtype == NULL) { + printf("Invalid paramtype\n"); + return FAILED; + } + + if (!strcmp("uint16",paramtype)) { + paramSize = sizeof(uint16_t); + s_typeFlag = OCMW_VALUE_TYPE_UINT16; + } else if (!strcmp("int16",paramtype)) { + paramSize = sizeof(int16_t); + s_typeFlag = OCMW_VALUE_TYPE_INT16; + } else if (!strcmp("uint8",paramtype)) { + paramSize = sizeof(uint8_t); + s_typeFlag = OCMW_VALUE_TYPE_UINT8; + } else if (!strcmp("int8",paramtype)) { + paramSize = sizeof(int8_t); + s_typeFlag = OCMW_VALUE_TYPE_INT8; + } else if (!strcmp("uint32",paramtype)) { + paramSize = sizeof(uint32_t); + s_typeFlag = OCMW_VALUE_TYPE_UINT32; + } else if (!strcmp("uint64",paramtype)) { + paramSize = sizeof(uint64_t); + } else if (!strcmp("enum",paramtype)) { + s_typeFlag = OCMW_VALUE_TYPE_STRUCT; + paramSize = OCMW_VALUE_TYPE_ENUM; + } else { + paramSize = sizeof(int8_t); + } + + return paramSize; +} + +/****************************************************************************** + * Function Name : ocmw_frame_subsystem_from_schema + * Description : frame subsyetem as per schema + * Input(s) : schema, subSystemInfo + * Output(s) : + ******************************************************************************/ +int32_t ocmw_frame_subsystem_from_schema(const Component *subSystem, + subSystemInfo *systemInfo) +{ + int32_t index = 0; + memset(&systemInfo->totalNum,0,sizeof(0)); + while (subSystem && subSystem->name) { + systemInfo->totalNum += 1; + systemInfo->Info[index].number = index; + strncpy(systemInfo->Info[index].name, subSystem->name, + strlen(subSystem->name)); + index++; + subSystem += 1; + } + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_frame_postTable_from_schema + * Description : frame post as per schema + * Input(s) : schema, postInfo + * Output(s) : + ******************************************************************************/ +int32_t ocmw_frame_postTable_from_schema(const Component *subSystem) +{ + int32_t index = 0; + int32_t count = 0; + const Component *component = NULL; + const Component *subComponent = NULL; + uint8_t subSystemNum = 0; + char tempComp[PARAM_STR_BUFF_SIZE] = {0}; + char tempCompdev[PARAM_STR_BUFF_SIZE] = {0}; + ocwarePostArrayIndex = 0; + while (subSystem && subSystem->name) { + count = 1; + component = subSystem->components; + while (component && component->name) { + subComponent = component->components; + if ((subComponent == NULL) && + ((!(component->postDisabled)))) { + memset(tempComp, 0, strlen(tempComp)); + strncpy(tempComp,component->name,strlen(component->name)); + tempComp[0] = toupper(tempComp[0]); + strncpy((ocwarePostArray[index].subsysName), + subSystem->name, strlen(subSystem->name)); + strncpy((ocwarePostArray[index].deviceName), + tempComp, strlen(tempComp)); + ocwarePostArray[index].devsn = count++; + ocwarePostArray[index].subsystem = subSystemNum; + ocwarePostArrayIndex++; + index++; + } + while (subComponent && subComponent->name) { + if (!(subComponent->postDisabled)) { + strncpy(ocwarePostArray[index].subsysName, + subSystem->name, strlen(subSystem->name)); + memset(ocwarePostArray[index].deviceName, 0, + sizeof(ocwarePostArray[index].deviceName)); + memset(tempComp, 0, strlen(tempComp)); + memset(tempCompdev, 0, strlen(tempCompdev)); + strncpy(tempComp, component->name, strlen(component->name)); + strncpy(tempCompdev, subComponent->name, + strlen(subComponent->name)); + tempComp[0] = toupper(tempComp[0]); + tempCompdev[0] = toupper(tempCompdev[0]); + + if (!strcmp(component->name,"comp_all")) { + strcpy((ocwarePostArray[index].deviceName), + tempCompdev); + } else { + if ((snprintf(ocwarePostArray[index].deviceName, + OCMW_POST_DEVICE_SIZE, "%s %s", + tempComp, tempCompdev)) < 0) { + return FAILED; + } + } + ocwarePostArray[index].devsn = count++; + ocwarePostArray[index].subsystem = subSystemNum; + ocwarePostArrayIndex++; + index++; + } + subComponent += 1; + } + component += 1; + } + printf("\n"); + subSystem += 1; + subSystemNum++; + } + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_get_noOfElements + * Description : get the number of parameter for components + * Input(s) : param_list + * Output(s) : noOfElement, size + ******************************************************************************/ +void ocmw_get_noOfElements(const Parameter *param_list, int32_t *noOfElement, + int32_t *size) +{ + int8_t elementCount = 0; + int8_t pSize = 0; + + if (param_list == NULL) { + *noOfElement = 0; + *size = 0; + return; + } + while (param_list->name) { + if ((!strcmp("uint16", DATA_TYPE_MAP[param_list->type])) || + (!strcmp("int16", DATA_TYPE_MAP[param_list->type]))) { + pSize = pSize + sizeof(uint16_t); + } else { + pSize = pSize + sizeof(int8_t); + } + elementCount++; + param_list++; + } + *noOfElement = elementCount; + *size = pSize; +} + +/****************************************************************************** + * Function Name : ocmw_parse_command_msgframe + * Description : parse the command + * Input(s) : Schema, msgFrame, actiontype, ecSendBuf + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_command_msgframe(const Component *compBase, + strMsgFrame *msgFrame, uint8_t actiontype, + ocmwSchemaSendBuf *ecSendBuf) +{ + const Component *component = NULL; + const Component *subSystem = compBase; + const Component *subcomponent = NULL; + const Command *comm = NULL; + const Driver *driver = NULL; + sMsgParam *sMsgFrameParam = (sMsgParam *) malloc(sizeof(sMsgParam)); + int16_t paramId = 0; + int8_t subCount = 0; + int8_t actionType = 0; + int8_t count = 0; + int8_t componentCount = 0; + int8_t paramSize = 0; + int8_t paramPos = 0; + recvdParamVal = 0; + eepromFlag = 0; + s_typeFlag = 0; + + if (subSystem == NULL) { + printf("Invalid Memory\n"); + return -1; + } + if (sMsgFrameParam == NULL) { + return -1; + } + memset(sMsgFrameParam, 0, sizeof(sMsgParam)); + if (ecSendBufBkp == NULL) { + ecSendBufBkp = + (ocmwSchemaSendBuf *) malloc(sizeof(ocmwSchemaSendBuf)); + } + if (ecSendBufBkp == NULL) { + return -1; + } + memset(ecSendBufBkp, 0, sizeof(ocmwSchemaSendBuf)); + /* Component id is starting from 1 */ + sMsgFrameParam->component = 1; + while (subSystem && subSystem->name) { + if (strncmp(subSystem->name, msgFrame->subsystem, + strlen(msgFrame->subsystem)) == 0) { + ecSendBuf->subsystem = (sMsgFrameParam->subsystem); + component = subSystem->components; + while (component && component->name) { + if (strcmp(component->name, msgFrame->component) == 0) { + ecSendBuf->componentId = sMsgFrameParam->component; + comm = component->commands; + /* + * Here we check if command is present in + * subsystem->component->command + */ + while (comm && comm->name) { + if (strncmp(comm->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + paramId = 0; + actionType = count; + subCount ++; + break; + } + count++; + comm += 1; + } + if (subCount != 0) + break; + driver = component->driver; + /* + * Here we check if command is present in + * subsystem->component->driver->command + */ + componentCount = 0; + if(driver != NULL) { + comm = driver->commands; + while (comm && comm->name) { + if (strncmp(comm->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + paramId = 0; + actionType = componentCount; + subCount ++; + break; + } + componentCount++; + comm += 1; + } + } + if (subCount != 0) + break; + /* + * Here we check if command is present in + * subsystem->component->subcomponent->driver->command + */ + count = 1; + subcomponent = component->components; + while (subcomponent && subcomponent->name) { + if (strcmp(subcomponent->name, msgFrame->subcomponent) + == 0) { + driver = subcomponent->driver; + if(driver != NULL) { + comm = driver->commands; + componentCount = 0; + while (comm && comm->name) { + if (strncmp(comm->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + /* + * Here subcomponentId = paramId + */ + paramId = count; + actionType = componentCount; + subCount ++; + /*break as we found the command */ + break; + } + comm += 1; + componentCount++; + } + break; + } + } + count++; + sMsgFrameParam->parameter += 1; + subcomponent += 1; + } + } + sMsgFrameParam->component += 1; + component += 1; + } + /* + * Break here because we are searching in only one subsystem + */ + break; + } + sMsgFrameParam->subsystem += 1; + subSystem += 1; + } + ecSendBuf->msgType = OCMP_MSG_TYPE_COMMAND; + ecSendBuf->actionType = actionType; + ecSendBuf->paramPos = paramPos; + ecSendBuf->paramId = paramId; + ecSendBuf->paramSize = paramSize; + if(msgFrame->parameter) { + memset(ecSendBuf->commandType, 0, + strlen(ecSendBuf->commandType)); + strncpy(ecSendBuf->commandType, msgFrame->parameter, + strlen(msgFrame->parameter)); + } + memcpy(ecSendBufBkp,ecSendBuf,sizeof(ocmwSchemaSendBuf)); + + free(sMsgFrameParam); + + if (subCount == 0) { + return FAILED; + } + + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_parse_post_msgframe + * Description : parse the post + * Input(s) : Schema, msgFrame, actiontype, ecSendBuf + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_post_msgframe(const Component *compBase, + strMsgFrame *msgFrame, uint8_t actiontype, + ocmwSchemaSendBuf *ecSendBuf) +{ + const Component *component = NULL; + const Component *subSystem = compBase; + const Post *param = NULL; + const Driver *devDriver = NULL; + int16_t paramId = 0; + int8_t count = 0; + int8_t paramSize = 0; + int8_t paramPos = 0; + sMsgParam *sMsgFrameParam = (sMsgParam *) malloc(sizeof(sMsgParam)); + if (sMsgFrameParam == NULL) { + return FAILED; + } + if (ecSendBufBkp == NULL) { + ecSendBufBkp = + (ocmwSchemaSendBuf *) malloc(sizeof(ocmwSchemaSendBuf)); + } + if (ecSendBufBkp == NULL) { + return FAILED; + } + recvdParamVal = 0; + eepromFlag = 0; + s_typeFlag = 0; + if (subSystem == NULL) { + printf("Invalid Memory\n"); + return FAILED; + } + memset(sMsgFrameParam, 0, sizeof(sMsgParam)); + sMsgFrameParam->component = 1; + memset(ecSendBufBkp, 0, sizeof(ocmwSchemaSendBuf)); + while (subSystem && subSystem->name) { + if (strncmp(subSystem->name, msgFrame->subsystem, + strlen(msgFrame->subsystem)) == 0) { + ecSendBuf->subsystem = (sMsgFrameParam->subsystem); + component = subSystem->components; + while (component && component->name) { + if (strcmp(component->name, msgFrame->component) == 0) { + ecSendBuf->componentId = (sMsgFrameParam->component); + devDriver = component->driver; + ecSendBuf->msgType = OCMP_MSG_TYPE_POST; + ecSendBuf->actionType = actiontype; + param = devDriver->post; + while (param && param->name) { + if (strncmp(param->name, msgFrame->subcomponent, + strlen(msgFrame->subcomponent)) == 0) { + paramId = pow(2,count); + break; + } + count++; + param += 1; + } + break; + } + sMsgFrameParam->component += 1; + component += 1; + } + break; + } + sMsgFrameParam->subsystem += 1; + subSystem += 1; + } + ecSendBuf->paramPos = paramPos; + ecSendBuf->paramId = paramId; + ecSendBuf->paramSize = paramSize; + memcpy(ecSendBufBkp, ecSendBuf, sizeof(ocmwSchemaSendBuf)); + free(sMsgFrameParam); + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_parse_driver_from_component + * Description : parse driver as per schema + * Input(s) : msgFrame, ecSendBuf, devDriver, actiontype + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_driver_from_component(strMsgFrame *msgFrame, + ocmwSchemaSendBuf *ecSendBuf, const Driver *devDriver, + uint8_t actiontype) +{ + const Parameter *param = NULL; + Enum_Map *value_enum = NULL; + int8_t count = 0; + int8_t index = 0; + int8_t regValue = 0; + int32_t temp = 0; + if (strncmp(msgFrame->msgtype, "config", strlen("config")) == 0) { + param = devDriver->config; + ecSendBuf->msgType = OCMP_MSG_TYPE_CONFIG; + ecSendBuf->actionType = actiontype; + while (param && param->name) { + if (strncmp(param->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + ecSendBuf->paramId = pow(2,count); + ecSendBuf->paramPos = temp + ecSendBuf->paramPos; + ecSendBuf->paramSize = ocmw_get_paramSize ( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_CONFIG, param->name); + break; + } + count = count + 1; + if ((!strcmp("uint16", DATA_TYPE_MAP[param->type])) || + (!strcmp("int16", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = ecSendBuf->paramPos + sizeof(uint16_t); + } else if ((!strcmp("uint8", DATA_TYPE_MAP[param->type])) || + (!strcmp("int8", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = ecSendBuf->paramPos + sizeof(uint8_t); + } + param += 1; + } + } else if (strncmp(msgFrame->msgtype, "status", strlen("status")) == 0) { + param = devDriver->status; + ecSendBuf->msgType = OCMP_MSG_TYPE_STATUS; + ecSendBuf->actionType = actiontype; + while (param && param->name) { + if (strncmp(param->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + ecSendBuf->paramId = pow(2,count); + if ((strncmp(param->name,"registration", + strlen(msgFrame->parameter)) == 0) || + (strncmp(param->name,"gps_lock", + strlen(msgFrame->parameter)) == 0)) { + value_enum = param->values; + for (index =index; index < OCMW_VALUE_TYPE_MFG; index++) { + s_paramEnumValue[index] = (char *)malloc(BUF_SIZE); + } + while (value_enum && value_enum->name) { + regValue = value_enum->value; + strncpy((s_paramEnumValue[regValue]), value_enum->name, + ENUM_BUF_SIZE); + value_enum += 1; + } + s_typeFlag = OCMW_VALUE_TYPE_STRUCT; + } else if(strncmp(param->name, "network_operatorinfo", + strlen(msgFrame->parameter)) == 0) { + s_typeFlag = OCMW_VALUE_TYPE_NWOP_STRUCT; + } + if ((strncmp(msgFrame->subsystem, "obc", + strlen(msgFrame->subsystem)) == 0) || + (strncmp(msgFrame->subsystem, "testmodule", + strlen(msgFrame->subsystem)) == 0)) { + ecSendBuf->paramPos = 0; + } else { + ecSendBuf->paramPos = temp + ecSendBuf->paramPos; + } + if ((param->size) && + (strcmp(DATA_TYPE_MAP[param->type],"enum") != 0)) { + ecSendBuf->paramSize = param->size; + } else { + ecSendBuf->paramSize = ocmw_get_paramSize( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_STATUS, param->name); + } + break; + } + count = count + 1; + if ((!strcmp("uint16", DATA_TYPE_MAP[param->type])) || + (!strcmp("int16", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = ecSendBuf->paramPos + sizeof(uint16_t); + } else if ((!strcmp("uint8", DATA_TYPE_MAP[param->type])) || + (!strcmp("int8", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = ecSendBuf->paramPos + sizeof(uint8_t); + } else if (!strcmp("string", DATA_TYPE_MAP[param->type])) { + ecSendBuf->paramPos = ecSendBuf->paramPos + + EEPROM_STATUS_MAX_SIZE; + } + param += 1; + } + } else if (strncmp(msgFrame->msgtype, "alerts", strlen("alerts")) == 0) { + param = devDriver->alerts; + } + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_parse_driver_from_subcomponent + * Description : parse driver as per schema + * Input(s) : msgFrame, ecSendBuf, subComponent, actiontype + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_driver_from_subcomponent (strMsgFrame *msgFrame, + ocmwSchemaSendBuf *ecSendBuf, const Component *subComponent, + uint8_t actiontype) +{ + const Driver *devDriver = NULL; + const Parameter *param = NULL; + int32_t noOfElementTemp = 0; + int32_t noOfElement = 0; + int32_t temp = 0; + int32_t size = 0; + int8_t count = 0; + while (subComponent && subComponent->name) { + devDriver = subComponent->driver; + temp = temp + size; + if (strncmp(msgFrame->msgtype, "config", strlen("config")) == 0) { + param = devDriver->config; + ocmw_get_noOfElements(param,&noOfElement, &size); + } else if (strncmp(msgFrame->msgtype, "status", + strlen("status")) == 0) { + param = devDriver->status; + ocmw_get_noOfElements(param,&noOfElement, &size); + } + if (strncmp(subComponent->name, msgFrame->subcomponent, + strlen(msgFrame->subcomponent)) == 0) { + devDriver = subComponent->driver; + if (strncmp(msgFrame->msgtype, "config", strlen("config")) == 0) { + param = devDriver->config; + ecSendBuf->msgType = OCMP_MSG_TYPE_CONFIG; + ecSendBuf->actionType = actiontype; + while (param && param->name) { + if (strncmp(param->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + ecSendBuf->paramId = pow(2, + count + noOfElementTemp); + ecSendBuf->paramPos = temp + ecSendBuf->paramPos; + if (param->size) { + ecSendBuf->paramSize = param->size; + } else { + ecSendBuf->paramSize = ocmw_get_paramSize( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_CONFIG, param->name); + } + break; + } + count = count + 1; + if ((!strcmp("uint16", DATA_TYPE_MAP[param->type])) || + (!strcmp("int16", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = + ecSendBuf->paramPos + sizeof(uint16_t); + } else if ((!strcmp("uint8", DATA_TYPE_MAP[param->type])) + || (!strcmp("int8", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = + ecSendBuf->paramPos + sizeof(uint8_t); + } + param += 1; + } + } else if (strncmp(msgFrame->msgtype, "status", + strlen("status")) == 0) { + param = devDriver->status; + ecSendBuf->msgType = OCMP_MSG_TYPE_STATUS; + ecSendBuf->actionType = actiontype; + while (param && param->name) { + if (strncmp(param->name, msgFrame->parameter, + strlen(msgFrame->parameter)) == 0) { + ecSendBuf->paramId = + pow(2, count + noOfElementTemp); + ecSendBuf->paramPos = temp + ecSendBuf->paramPos; + if (param->size) { + ecSendBuf->paramSize = param->size; + } else { + ecSendBuf->paramSize = ocmw_get_paramSize ( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_STATUS, param->name); + } + break; + } + count = count + 1; + if ((!strcmp("uint16", DATA_TYPE_MAP[param->type])) || + (!strcmp("int16", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = + ecSendBuf->paramPos + sizeof(uint16_t); + } else if ((!strcmp("uint8", DATA_TYPE_MAP[param->type])) + || (!strcmp("int8", DATA_TYPE_MAP[param->type]))) { + ecSendBuf->paramPos = + ecSendBuf->paramPos + sizeof(uint8_t); + } else if (!strcmp("string", DATA_TYPE_MAP[param->type])) { + ecSendBuf->paramPos = ecSendBuf->paramPos + + EEPROM_STATUS_MAX_SIZE; + } + param += 1; + } + } else if (strncmp(msgFrame->msgtype, "alerts", + strlen("alerts")) == 0) { + param = devDriver->alerts; + } + break; + } + noOfElementTemp = noOfElementTemp + noOfElement; + subComponent += 1; + } + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_parse_msgframe + * Description : parse msgframe as per schema + * Input(s) : compBase, msgFrame, actiontype, ecSendBuf + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_msgframe(const Component *compBase, strMsgFrame *msgFrame, + uint8_t actiontype,ocmwSchemaSendBuf *ecSendBuf) +{ + const Component *component = NULL; + const Component *subComponent = NULL; + const Component *subSystem = compBase; + const Driver *devDriver = NULL; + sMsgParam *sMsgFrameParam = (sMsgParam *) malloc(sizeof(sMsgParam)); + recvdParamVal = 0; + eepromFlag = 0; + s_typeFlag = 0; + + if (sMsgFrameParam == NULL) { + return FAILED; + } + memset(ecSendBuf, 0, sizeof(ocmwSchemaSendBuf)); + memset(sMsgFrameParam, 0, sizeof(sMsgParam)); + + if (ecSendBufBkp == NULL) { + ecSendBufBkp = + (ocmwSchemaSendBuf *) malloc(sizeof(ocmwSchemaSendBuf)); + } + if (ecSendBufBkp == NULL) { + return -1; + } + memset(ecSendBufBkp, 0, sizeof(ocmwSchemaSendBuf)); + if (subSystem == NULL) { + printf("Invalid Memory\n"); + return FAILED; + } + + /* Component id is starting from 1*/ + sMsgFrameParam->component = 1; + while (subSystem && subSystem->name) { + if (strncmp(subSystem->name, msgFrame->subsystem, + strlen(msgFrame->subsystem)) == 0) { + ecSendBuf->subsystem = (sMsgFrameParam->subsystem); + component = subSystem->components; + while (component && component->name) { + if (strcmp(component->name, msgFrame->component) == 0) { + ecSendBuf->componentId = sMsgFrameParam->component; + devDriver = component->driver; + if (devDriver != NULL) { + ocmw_parse_driver_from_component(msgFrame, + ecSendBuf,devDriver,actiontype); + } + subComponent = component->components; + if (subComponent != NULL){ + ocmw_parse_driver_from_subcomponent(msgFrame, + ecSendBuf,subComponent,actiontype); + } + break; + } + sMsgFrameParam->component += 1; + component += 1; + } + break; + } + printf("\n"); + sMsgFrameParam->subsystem += 1; + subSystem += 1; + } + memcpy(ecSendBufBkp, ecSendBuf, sizeof(ocmwSchemaSendBuf)); + free(sMsgFrameParam); + + return SUCCESS; +} +/****************************************************************************** + * Function Name : ocmw_parse_message_fram_from_ec + * Description : parse the msgframe data coming from EC to AP + * Input(s) : ecReceivedMsg + * Output(s) : + ******************************************************************************/ +int32_t ocmw_parse_message_fram_from_ec(OCMPMessageFrame *ecReceivedMsg) +{ + int32_t ret = 0; + int32_t index = 0; + int32_t paramVal = 0; + char regStr[BUF_SIZE] = {0}; + size_t size = 0; + + ocmwSendRecvBuf ecInputData; + switch(ecSendBufBkp->paramSize) { + case (sizeof(uint16_t)): + if (s_typeFlag == OCMW_VALUE_TYPE_UINT16) { + recvdParamVal = + *((uint16_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + } else if (s_typeFlag == OCMW_VALUE_TYPE_INT16) { + recvdParamVal = + *((int16_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + } + break; + case (sizeof(uint8_t)) : + if (s_typeFlag == OCMW_VALUE_TYPE_UINT8) { + recvdParamVal = + *((uint8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + } else if (s_typeFlag == OCMW_VALUE_TYPE_INT8) { + recvdParamVal = + *((int8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + } else if (s_typeFlag == OCMW_VALUE_TYPE_ENUM) { + recvdParamVal = + *((int8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + } + break; + case (sizeof(uint32_t)): + if (s_typeFlag == OCMW_VALUE_TYPE_UINT32) { + recvdParamVal = + *((uint32_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + } else { + memset(dataOutBufFromEc, 0 , + sizeof(dataOutBufFromEc)); + memcpy(dataOutBufFromEc, ecReceivedMsg->message.info, + OCMW_VALUE_TYPE_MODEL); + eepromFlag++; + } + break; + case (sizeof(uint64_t)): + recvdParamVal = + *((uint64_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + break; + case EEPROM_CONFIG_MAX_SIZE: + case EEPROM_CONFIG_SIZE: + case EEPROM_SDR_STATUS_SIZE: + case EEPROM_STATUS_MAX_SIZE: + memset(&ecInputData, 0, sizeof(ocmwSendRecvBuf)); + ecInputData.numOfele = 0; + ecInputData.paramInfo = ecReceivedMsg->message.parameters; + ecInputData.componentId = ecReceivedMsg->message.componentID; + ecInputData.msgType = ecReceivedMsg->message.msgtype; + ecInputData.actionType = ecReceivedMsg->message.action; + ecInputData.subsystem = ecReceivedMsg->message.subsystem; + memcpy(ecInputData.pbuf, ecReceivedMsg->message.info, + MAX_PARM_COUNT); + ret = ocmw_parse_eepromdata_from_ec(ecInputData); + eepromFlag++; + break; + case OCMW_VALUE_TYPE_MFG: + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + memcpy(dataOutBufFromEc,ecReceivedMsg->message.info, + OCMW_VALUE_TYPE_MFG); + eepromFlag++; + break; + case OCMW_VALUE_TYPE_GETMODEL: + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + memcpy(dataOutBufFromEc, ecReceivedMsg->message.info, + OCMW_VALUE_TYPE_GETMODEL); + eepromFlag++; + break; + case OCMW_VALUE_TYPE_ENUM: + case OCMW_VALUE_TYPE_COMPLEX: + memset(&ecInputData, 0, sizeof(ocmwSendRecvBuf)); + ecInputData.numOfele = 0; + ecInputData.paramInfo = ecReceivedMsg->message.parameters; + ecInputData.componentId = ecReceivedMsg->message.componentID; + ecInputData.msgType = ecReceivedMsg->message.msgtype; + ecInputData.actionType = ecReceivedMsg->message.action; + ecInputData.subsystem = ecReceivedMsg->message.subsystem; + memcpy(ecInputData.pbuf, ecReceivedMsg->message.info, + MAX_PARM_COUNT); + if (s_typeFlag == OCMW_VALUE_TYPE_STRUCT) { + paramVal = *((uint8_t *) ecInputData.pbuf); + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + size = sizeof(dataOutBufFromEc); + if (s_paramEnumValue[paramVal]) { + strcpy(regStr,s_paramEnumValue[paramVal]); + snprintf(dataOutBufFromEc, size, + "%u(%s) ", paramVal,regStr); + for (index = 0; index < OCMW_VALUE_TYPE_MFG; index++) { + ocmw_free_global_pointer( + (void**)&s_paramEnumValue[index]); + } + } + }else if (s_typeFlag == OCMW_VALUE_TYPE_NWOP_STRUCT) { + ret = ocmw_parse_testingmodule_struct_from_ec(ecInputData); + } else { + ret = ocmw_parse_obc_struct_from_ec(ecInputData); + } + eepromFlag++; + break; + default: + break; + } + if (ret < 0) { + responseCount = 0; + } else { + responseCount++; + } + return SUCCESS; +} + +/****************************************************************************** + * Function Name : ocmw_deserialise_debug_gpio_value + * Description : parse the msgframe data coming from EC to AP + * Input(s) : ecReceivedMsg + * Output(s) : dataOutBufFromEc + ******************************************************************************/ +void ocmw_deserialise_debug_gpio_value(OCMPMessageFrame *ecReceivedMsg) +{ + int8_t pin = 0; + int8_t value = 0; + size_t size = 0; + + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + size = sizeof(dataOutBufFromEc); + pin = *((uint8_t *)&(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + value = *((uint8_t *)&(ecReceivedMsg->message.info[ecSendBufBkp->paramPos + + 1])); + snprintf(dataOutBufFromEc, size, "(Pin No : %d) %s = %d", pin, + ecSendBufBkp->commandType, value); + return; +} +/****************************************************************************** + * Function Name : ocmw_deserialise_debug_mdio_value + * Description : parse the msgframe data coming from EC to AP + * Input(s) : ecReceivedMsg + * Output(s) : dataOutBufFromEc + ******************************************************************************/ +void ocmw_deserialise_debug_mdio_value(OCMPMessageFrame *ecReceivedMsg) +{ + uint16_t registerAddress = 0; + uint16_t registerData = 0; + size_t size = 0; + registerAddress = *((uint16_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + registerData = *((uint16_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos + 2])); + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + size = sizeof(dataOutBufFromEc); + snprintf(dataOutBufFromEc, size, "(Register Address : %d) %s = %d", + registerAddress, ecSendBufBkp->commandType, registerData); + return; +} +/****************************************************************************** + * Function Name : ocmw_deserialise_debug_i2c_value + * Description : parse the msgframe data coming from EC to AP + * Input(s) : ecReceivedMsg + * Output(s) : dataOutBufFromEc + ******************************************************************************/ +void ocmw_deserialise_debug_i2c_value(OCMPMessageFrame *ecReceivedMsg) +{ + uint8_t slaveAddress = 0; + uint8_t noOfBytes = 0; + uint8_t registerAddress = 0; + uint16_t registerData = 0; + size_t size = 0; + + slaveAddress = *((uint8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos])); + noOfBytes = *((uint8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos + 1])); + registerAddress = *((uint8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos + 2])); + + if (noOfBytes == OCMW_VALUE_TYPE_UINT8) { + registerData = *((uint8_t *) + &(ecReceivedMsg->message.info[ecSendBufBkp->paramPos + 3])); + } else { + registerData = ((uint16_t )((((uint8_t) + (ecReceivedMsg->message.info[ecSendBufBkp->paramPos + + 3]) & 0xff) << 8) | + ((uint8_t) + ((ecReceivedMsg->message.info[ecSendBufBkp->paramPos + + 4])) & 0xff))); + } + + memset(dataOutBufFromEc, 0, sizeof(dataOutBufFromEc)); + size = sizeof(dataOutBufFromEc); + snprintf(dataOutBufFromEc, size, "(slave address :%d noOfBytes :%d Register" + " Address :%d) %s = %d", slaveAddress, noOfBytes, + registerAddress, ecSendBufBkp->commandType, registerData); + + if (strcmp(ecSendBufBkp->commandType, "set") == 0) { + strcat(dataOutBufFromEc, " : Success"); + } + return; +} +/****************************************************************************** + * Function Name : ocmw_deserialization_msgframe + * Description : parse the msgframe data coming from EC to AP + * Input(s) : subSystem, ecReceivedMsg + * Output(s) : dMsgFrameParam + ******************************************************************************/ +void ocmw_deserialization_msgframe(const Component *subSystem, + sMsgParam *dMsgFrameParam, OCMPMessageFrame *ecReceivedMsg) +{ + int32_t ret = 0; + int8_t index = 0; + + if (subSystem == NULL) { + return; + } + + if (ecReceivedMsg->message.parameters != 0) { + if ((ecReceivedMsg->message.subsystem == + ecSendBufBkp->subsystem) && + (ecReceivedMsg->message.componentID == + ecSendBufBkp->componentId) && + (ecReceivedMsg->message.msgtype == + ecSendBufBkp->msgType) && + (ecReceivedMsg->message.action == + OCMP_AXN_TYPE_REPLY) && + (ecReceivedMsg->message.parameters == + ecSendBufBkp->paramId)) { + + ret = ocmw_parse_message_fram_from_ec(ecReceivedMsg); + if (ret < 0) { + printf("\nocmw_parse_message_fram_from_ec error"); + } + } + } + if (ecReceivedMsg->message.msgtype == OCMP_MSG_TYPE_COMMAND) { + if ((ecReceivedMsg->message.subsystem == + ecSendBufBkp->subsystem) && + (ecReceivedMsg->message.componentID == + ecSendBufBkp->componentId) && + (ecReceivedMsg->message.msgtype == + ecSendBufBkp->msgType) && + (ecReceivedMsg->message.action == + OCMP_AXN_TYPE_REPLY) && + (ecReceivedMsg->message.parameters == + ecSendBufBkp->paramId)) { + if ((ecReceivedMsg->message.subsystem == DEBUG_SUBSYSTEM_NBR)) { + if (ecReceivedMsg->message.componentID < DEBUG_I2C) { + ocmw_deserialise_debug_i2c_value(ecReceivedMsg); + } else if (ecReceivedMsg->message.componentID == + DEBUG_MDIO) { + ocmw_deserialise_debug_mdio_value(ecReceivedMsg); + } else { + ocmw_deserialise_debug_gpio_value(ecReceivedMsg); + } + } + responseCount++; + } + } + /* Free backup info if stored */ + for (index = 0; index < OCMW_VALUE_TYPE_MFG; index++) { + ocmw_free_global_pointer((void**)&s_paramEnumValue[index]); + } + if (ecSendBufBkp) { + ocmw_free_global_pointer((void**)&ecSendBufBkp); + } +} diff --git a/firmware/host/ocmw/ocmw_uart_comm.c b/firmware/host/ocmw/ocmw_uart_comm.c new file mode 100644 index 0000000000..445814cff9 --- /dev/null +++ b/firmware/host/ocmw/ocmw_uart_comm.c @@ -0,0 +1,312 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* OC includes */ +#include +#include +#include + +static int32_t s_fd = 0; +struct termios s_oldtio; +static handle_msg_from_ec_t s_uart_msg_hndlr = NULL; +static void sa_handler_read(int32_t status); +static bool S_STOP_UART_RX_SERVICE = true; +static pthread_t s_uartrxthread; +static volatile bool s_waitForUartMsg = true; +extern uint8_t mcuMsgBuf[OCMP_MSG_SIZE]; + +/************************************************************************** + * Function Name : ocmw_ec_uart_msg_hndlr + * Description : This Function used to handle uart messages + * Input(s) : msgstr, msgsize + * Output(s) : + ***************************************************************************/ +void ocmw_ec_uart_msg_hndlr(const unsigned char* msgstr, int32_t msgsize) +{ + /* Process the OC message received from EC */ + if (msgsize > OCMP_MSG_SIZE) { + logerr("message size is more than %d bytes", OCMP_MSG_SIZE); + return; + } + + /* Store the uart msg into global buffer */ + memcpy(mcuMsgBuf, msgstr, msgsize); + + /* Signal the msg parser for ec uart msg */ + sem_post(&semecMsgParser); + + return; +} + +/************************************************************************** + * Function Name : ocmw_recv_uart_msg_service + * Description : This Function used to receive uart messages + * Input(s) : + * Output(s) : args + ***************************************************************************/ +static void* ocmw_recv_uart_msg_service(void* args) +{ + unsigned char msg[OCMP_MSG_SIZE] = {0}; + unsigned char buf[OCMP_MSG_SIZE] = {0}; + int32_t ret = 0; + const unsigned int msglen = OCMP_MSG_SIZE; + + while (!S_STOP_UART_RX_SERVICE) { + /* Receive UART messages from EC */ + if (s_waitForUartMsg) { + usleep(10); + continue; + } + s_waitForUartMsg = true; + + /* Read message frame from tty */ + memset(msg, 0, msglen); + memset(buf, 0, OCMP_MSG_SIZE); + ret = read(s_fd, msg, msglen); + if (ret < 0) { + logerr("Error reading from %s (%d - %s)", ECTTY, errno, + strerror(errno)); + continue; + } + if (memcmp(msg, buf, OCMP_MSG_SIZE) == 0) { + continue; /* Not a valid UART message */ + } + + /* printf("Data from EC:\n"); */ + /* hexdisp(msg, msglen); */ + if (s_uart_msg_hndlr != NULL) { + (*s_uart_msg_hndlr)(msg, msglen); + } + } + return NULL; +} + +/************************************************************************** + * Function Name : sa_handler_read + * Description : This Function used to read the handler + * Input(s) : status + * Output(s) : + ***************************************************************************/ +static void sa_handler_read(int32_t status) +{ + s_waitForUartMsg = false; + return; +} + +/************************************************************************** + * Function Name : ocmw_init_ec_comm + * Description : This Function used to initialize the ec communication + * Input(s) : msghndlr + * Output(s) : + ***************************************************************************/ +int32_t ocmw_init_ec_comm(handle_msg_from_ec_t msghndlr) +{ + char pathName[100] = {0}; + int32_t ret = 0; + struct termios newtio; + struct sigaction saio; + + memset(pathName, 0, sizeof(pathName)); +#ifdef INTERFACE_USB + ret = ocmw_find_ttyacm_port(pathName); + if (ret != 0) { + return ret; + } +#else + memcpy(pathName, (char *) ECTTY, sizeof(ECTTY)); +#endif + /* + * Open the HSUART-1 port for communicating with EC + * + * O_NOCTTY - Not an interactive console + * O_NONBLOCK - Read need not be a blocking call + */ + s_fd = open(pathName, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (s_fd == -1) { + if (s_fd == -1) { + logerr("Error opening %s (%d - %s)", ECTTY, errno, + strerror(errno)); + return -1; + } + } + + /* Install signal handler for asynchronous read */ + saio.sa_handler = sa_handler_read; + sigemptyset(&saio.sa_mask); + saio.sa_flags = SA_RESTART; + saio.sa_restorer = NULL; + sigaction(SIGIO, &saio, NULL); + + /* Allow this process to receive SIGIO */ + fcntl(s_fd, F_SETOWN, getpid()); + + /* Set file descriptor to handle asynchronous reads */ + fcntl(s_fd, F_SETFL, O_ASYNC); + + tcgetattr(s_fd, &s_oldtio); + memset(&newtio, 0, sizeof(newtio)); + cfsetispeed(&newtio, B115200); /* Baud rate = 115200 */ + cfsetospeed(&newtio, B115200); + newtio.c_cflag &= ~PARENB; /* No parity check */ + newtio.c_cflag &= ~CSTOPB; /* 1 STOP bit */ + newtio.c_cflag &= ~CSIZE; /* 8 DATA bits */ + newtio.c_cflag |= CS8; + newtio.c_cflag &= ~CRTSCTS; /* No HW flow control */ + /* Enable always. CREAD - Enable receiver. + * CLOCAL - program doesn't own the tty. */ + newtio.c_cflag |= (CLOCAL | CREAD); + newtio.c_cc[VTIME] = 10; /* Inter character TIME=t*0.1s, where t=10. */ + newtio.c_cc[VMIN] = 0; //33; /* EC message frame size = 32 bytes */ + newtio.c_iflag &= ~(IXON | IXOFF | IXANY); /* No SW flow control */ + newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + newtio.c_oflag &= ~OPOST; + tcflush(s_fd, TCIFLUSH); + tcsetattr(s_fd, TCSANOW, &newtio); + + S_STOP_UART_RX_SERVICE = false; + ret = pthread_create(&s_uartrxthread, NULL, ocmw_recv_uart_msg_service, + NULL); + if (ret != 0) { + logerr("pthread creation failed [%d-%s]", errno, strerror(errno)); + } else { + s_uart_msg_hndlr = msghndlr; + } + + if (ret != 0) { + ocmw_deinit_ec_comm(); + } + return ret; +} + +/************************************************************************** + * Function Name : ocmw_deinit_ec_comm + * Description : This Function used to deinitialize the ec communication + * Input(s) : + * Output(s) : + ***************************************************************************/ +int32_t ocmw_deinit_ec_comm(void) +{ + S_STOP_UART_RX_SERVICE = true; + tcsetattr(s_fd, TCSANOW, &s_oldtio); + if (s_fd > 0) { + close(s_fd); + s_fd = 0; + } + if (s_uart_msg_hndlr != NULL) { + s_uart_msg_hndlr = NULL; + } + return SUCCESS; +} + +/************************************************************************** + * Function Name : ocmw_send_uart_msg_to_ec + * Description : This Function used to send uart message to ec + * Input(s) : msgstr, msgsize + * Output(s) : + ***************************************************************************/ +int32_t ocmw_send_uart_msg_to_ec(const uint8_t* msgstr, int32_t msgsize) +{ + uint8_t buf[OCMP_MSG_SIZE] = {0}; + int32_t ret = 0, bufWriteCount = 0; + int32_t sendPktNonpayloadSize = 0; + int32_t loopCount = 0; + OCMPMessageFrame *ecMsgFrame; + + ecMsgFrame = (OCMPMessageFrame *) msgstr; + + sendPktNonpayloadSize = (sizeof(OCMPMessage) - sizeof(void *) + + sizeof(OCMPHeader)); + + if (msgstr == NULL) { + logerr("Error: Memory allocation problem"); + return -1; + } + + if (msgsize > OCMP_MSG_SIZE) { + logerr("Error: msgstr size is more than %d bytes", OCMP_MSG_SIZE); + return -EMSGSIZE; + } + + /* create message frame */ + memset(buf, 0, sizeof(buf)); + memcpy(buf, msgstr, sendPktNonpayloadSize); + memcpy(&buf[sendPktNonpayloadSize], ((ecMsgFrame->message).info), + MAX_PARM_COUNT); + + /* Write message frame to tty */ + bufWriteCount = write(s_fd, buf, sizeof(buf)); + if (bufWriteCount < 0) { + ret = errno; + logerr("Error writing to %s (%d - %s)", ECTTY, ret, strerror(errno)); + return -ret; + } + +#ifndef MSG_LOG + printf(" \n send_msg_to_ec \n"); + + for (loopCount = 0; loopCount < OCMP_MSG_SIZE; loopCount++) { + printf("0x%x ", buf[loopCount] & 0x00ff); + } + + printf("\n"); +#endif /* MSG_LOG */ + + return ret; +} + +/************************************************************************** + * Function Name : ocmw_find_ttyacm_port + * Description : This Function used to find the tty port + * Input(s) : + * Output(s) : pathName + ***************************************************************************/ +int32_t ocmw_find_ttyacm_port(char *pathName) +{ + FILE *fp; + int32_t nodeNum = -1; + int32_t ret = 0; + + if (pathName == NULL) { + return ret = -1; + } + + /* Open the command for reading. */ + fp = popen(ECTTY, "r"); + if (fp == NULL) { + printf("Failed to run command\n"); + return ret = -1; + } + + fscanf(fp, "%d", &nodeNum); + if (nodeNum < 0) { + /* close */ + pclose(fp); + printf(" No ttyACM port found \n"); + return ret = -1; + } else { + sprintf(pathName, "/dev/ttyACM%d", nodeNum); + printf(" ttyACM port = %s \n", pathName); + /* close */ + pclose(fp); + } + return ret; +} diff --git a/firmware/host/ocwarestub/get_params_stub.sh b/firmware/host/ocwarestub/get_params_stub.sh new file mode 100755 index 0000000000..8b6e6d9f7d --- /dev/null +++ b/firmware/host/ocwarestub/get_params_stub.sh @@ -0,0 +1,390 @@ +#!/bin/sh +if [ -z "$1" ]; then + echo "Invalid Option" + echo "Usage : ./get_params " + exit +elif [ $1 = "bms" ]; then +if [ $2 = "config" ]; then +../bin/occmd bms.ec.config.temp_sensor1.lowlimit.get +../bin/occmd bms.ec.config.temp_sensor1.highlimit.get +../bin/occmd bms.ec.config.temp_sensor1.critlimit.get +../bin/occmd bms.ec.config.current_sensor1.currlimit.get +../bin/occmd bms.ec.config.current_sensor2.currlimit.get +elif [ $2 = "status" ]; then +../bin/occmd bms.ec.status.temp_sensor1.temperature.get +../bin/occmd bms.ec.status.current_sensor1.busvoltage.get +../bin/occmd bms.ec.status.current_sensor1.shuntvoltage.get +../bin/occmd bms.ec.status.current_sensor1.current.get +../bin/occmd bms.ec.status.current_sensor1.power.get +../bin/occmd bms.ec.status.current_sensor2.busvoltage.get +../bin/occmd bms.ec.status.current_sensor2.shuntvoltage.get +../bin/occmd bms.ec.status.current_sensor2.current.get +../bin/occmd bms.ec.status.current_sensor2.power.get +else + echo "Invalid Option" +fi +elif [ $1 = "gpp" ]; then +if [ $2 = "config" ]; then +../bin/occmd gpp.ap.config.temp_sensor1.lowlimit.get +../bin/occmd gpp.ap.config.temp_sensor1.highlimit.get +../bin/occmd gpp.ap.config.temp_sensor1.critlimit.get +../bin/occmd gpp.ap.config.temp_sensor2.lowlimit.get +../bin/occmd gpp.ap.config.temp_sensor2.highlimit.get +../bin/occmd gpp.ap.config.temp_sensor2.critlimit.get +../bin/occmd gpp.ap.config.temp_sensor3.lowlimit.get +../bin/occmd gpp.ap.config.temp_sensor3.highlimit.get +../bin/occmd gpp.ap.config.temp_sensor3.critlimit.get +../bin/occmd gpp.ap.config.current_sensor1.currlimit.get +../bin/occmd gpp.msata.config.current_sensor1.currlimit.get +elif [ $2 = "status" ]; then +../bin/occmd gpp.ap.status.temp_sensor1.temperature.get +../bin/occmd gpp.ap.status.temp_sensor2.temperature.get +../bin/occmd gpp.ap.status.temp_sensor3.temperature.get +../bin/occmd gpp.ap.status.current_sensor1.busvoltage.get +../bin/occmd gpp.ap.status.current_sensor1.shuntvoltage.get +../bin/occmd gpp.ap.status.current_sensor1.current.get +../bin/occmd gpp.ap.status.current_sensor1.power.get +../bin/occmd gpp.msata.status.current_sensor1.busvoltage.get +../bin/occmd gpp.msata.status.current_sensor1.shuntvoltage.get +../bin/occmd gpp.msata.status.current_sensor1.current.get +../bin/occmd gpp.msata.status.current_sensor1.power.get +else + echo "Invalid Option" +fi +elif [ $1 = "sdr" ]; then +if [ $2 = "config" ]; then +../bin/occmd sdr.comp_all.config.current_sensor1.currlimit.get +../bin/occmd sdr.fpga.config.temp_sensor1.lowlimit.get +../bin/occmd sdr.fpga.config.temp_sensor1.highlimit.get +../bin/occmd sdr.fpga.config.temp_sensor1.critlimit.get +../bin/occmd sdr.fpga.config.current_sensor1.currlimit.get +elif [ $2 = "status" ]; then +../bin/occmd sdr.comp_all.status.current_sensor1.busvoltage.get +../bin/occmd sdr.comp_all.status.current_sensor1.shuntvoltage.get +../bin/occmd sdr.comp_all.status.current_sensor1.current.get +../bin/occmd sdr.comp_all.status.current_sensor1.power.get +../bin/occmd sdr.fpga.status.temp_sensor1.temperature.get +../bin/occmd sdr.fpga.status.current_sensor1.busvoltage.get +../bin/occmd sdr.fpga.status.current_sensor1.shuntvoltage.get +../bin/occmd sdr.fpga.status.current_sensor1.current.get +../bin/occmd sdr.fpga.status.current_sensor1.power.get +../bin/occmd sdr.comp_all.status.eeprom.dev_id.get +else + echo "Invalid Option" +fi +elif [ $1 = "rf" ]; then +if [ $2 = "config" ]; then +../bin/occmd rffe.ch1_sensor.config.temp_sensor1.lowlimit.get +../bin/occmd rffe.ch1_sensor.config.temp_sensor1.highlimit.get +../bin/occmd rffe.ch1_sensor.config.temp_sensor1.critlimit.get +../bin/occmd rffe.ch1_sensor.config.current_sensor1.currlimit.get +../bin/occmd rffe.ch2_sensor.config.temp_sensor1.lowlimit.get +../bin/occmd rffe.ch2_sensor.config.temp_sensor1.highlimit.get +../bin/occmd rffe.ch2_sensor.config.temp_sensor1.critlimit.get +../bin/occmd rffe.ch2_sensor.config.current_sensor1.currlimit.get +#../bin/occmd rffe.ch1_fe.config.rf.band get +#../bin/occmd rffe.ch1_fe.config.rf.arfcn get +../bin/occmd rffe.ch1_fe.config.tx.atten.get +../bin/occmd rffe.ch1_fe.config.rx.atten.get +#../bin/occmd rffe.ch2_fe.config.rf.band get +#../bin/occmd rffe.ch2_fe.config.rf.arfcn get +../bin/occmd rffe.ch2_fe.config.tx.atten.get +../bin/occmd rffe.ch2_fe.config.rx.atten.get +elif [ $2 = "status" ]; then +../bin/occmd rffe.ch1_sensor.status.temp_sensor1.temperature.get +../bin/occmd rffe.ch1_sensor.status.current_sensor1.busvoltage.get +../bin/occmd rffe.ch1_sensor.status.current_sensor1.shuntvoltage.get +../bin/occmd rffe.ch1_sensor.status.current_sensor1.current.get +../bin/occmd rffe.ch1_sensor.status.current_sensor1.power.get +../bin/occmd rffe.ch2_sensor.status.temp_sensor1.temperature.get +../bin/occmd rffe.ch2_sensor.status.current_sensor1.busvoltage.get +../bin/occmd rffe.ch2_sensor.status.current_sensor1.shuntvoltage.get +../bin/occmd rffe.ch2_sensor.status.current_sensor1.current.get +../bin/occmd rffe.ch2_sensor.status.current_sensor1.power.get +../bin/occmd rffe.ch1_fe.status.power.forward.get +../bin/occmd rffe.ch1_fe.status.power.reverse.get +../bin/occmd rffe.ch2_fe.status.power.forward.get +../bin/occmd rffe.ch2_fe.status.power.reverse.get +../bin/occmd rffe.comp_all.status.eeprom.dev_id.get +else + echo "Invalid Option" +fi +elif [ $1 = "power" ]; then +if [ $2 = "config" ]; then +../bin/occmd power.leadacid_sensor.config.temp_sensor1.lowlimit.get +../bin/occmd power.leadacid_sensor.config.temp_sensor1.highlimit.get +../bin/occmd power.leadacid_sensor.config.temp_sensor1.critlimit.get +../bin/occmd power.leadacid.config.battery.batteryVoltageLow.get +../bin/occmd power.leadacid.config.battery.batteryVoltageHigh.get +../bin/occmd power.leadacid.config.battery.batteryCurrentLow.get +../bin/occmd power.leadacid.config.battery.inputVoltageLow.get +../bin/occmd power.leadacid.config.battery.inputCurrentHigh.get +../bin/occmd power.leadacid.config.battery.inputCurrentLimit.get +../bin/occmd power.leadacid.config.battery.icharge.get +../bin/occmd power.leadacid.config.battery.vcharge.get +../bin/occmd power.lion.config.battery.batteryVoltageLow.get +../bin/occmd power.lion.config.battery.batteryVoltageHigh.get +../bin/occmd power.lion.config.battery.batteryCurrentLow.get +../bin/occmd power.lion.config.battery.inputVoltageLow.get +../bin/occmd power.lion.config.battery.inputCurrentHigh.get +../bin/occmd power.lion.config.battery.inputCurrentLimit.get +../bin/occmd power.lion.config.battery.icharge.get +../bin/occmd power.lion.config.battery.vcharge.get +elif [ $2 = "status" ]; then +../bin/occmd power.leadacid_sensor.status.temp_sensor1.temperature.get +../bin/occmd power.leadacid.status.battery.batteryVoltage.get +../bin/occmd power.leadacid.status.battery.batteryCurrent.get +../bin/occmd power.leadacid.status.battery.systemVoltage.get +../bin/occmd power.leadacid.status.battery.inputVoltage.get +../bin/occmd power.leadacid.status.battery.inputCurrent.get +../bin/occmd power.leadacid.status.battery.dieTemperature.get +../bin/occmd power.lion.status.battery.batteryVoltage.get +../bin/occmd power.lion.status.battery.batteryCurrent.get +../bin/occmd power.lion.status.battery.systemVoltage.get +../bin/occmd power.lion.status.battery.inputVoltage.get +../bin/occmd power.lion.status.battery.inputCurrent.get +../bin/occmd power.lion.status.battery.dieTemperature.get +../bin/occmd power.comp_all.status.powerSource.extBattAccessebility.get +../bin/occmd power.comp_all.status.powerSource.extBattAvailability.get +../bin/occmd power.comp_all.status.powerSource.intBattAccessebility.get +../bin/occmd power.comp_all.status.powerSource.intBattAvailability.get +../bin/occmd power.comp_all.status.powerSource.poeAccessebility.get +../bin/occmd power.comp_all.status.powerSource.poeAvailability.get +../bin/occmd power.comp_all.status.powerSource.solarAccessebility.get +../bin/occmd power.comp_all.status.powerSource.solarAvailability.get +else + echo "Invalid Option" +fi +elif [ $1 = "ethernet" ]; then +if [ $2 = "config" ]; then +../bin/occmd ethernet.port0.config.speed.get +../bin/occmd ethernet.port0.config.duplex.get +../bin/occmd ethernet.port0.config.powerDown.get +../bin/occmd ethernet.port0.config.enable_sleepMode.get +../bin/occmd ethernet.port0.config.enable_interrupt.get +#../bin/occmd ethernet.port0.config.switch_reset get +#../bin/occmd ethernet.port0.config.restart_autoneg get +../bin/occmd ethernet.port1.config.speed.get +../bin/occmd ethernet.port1.config.duplex.get +../bin/occmd ethernet.port1.config.powerDown.get +../bin/occmd ethernet.port1.config.enable_sleepMode.get +../bin/occmd ethernet.port1.config.enable_interrupt.get +#../bin/occmd ethernet.port1.config.switch_reset get +#../bin/occmd ethernet.port1.config.restart_autoneg get +../bin/occmd ethernet.port2.config.speed.get +../bin/occmd ethernet.port2.config.duplex.get +../bin/occmd ethernet.port2.config.powerDown.get +../bin/occmd ethernet.port2.config.enable_sleepMode.get +../bin/occmd ethernet.port3.config.enable_interrupt.get +#../bin/occmd ethernet.port2.config.switch_reset get +#../bin/occmd ethernet.port2.config.restart_autoneg get +../bin/occmd ethernet.port3.config.speed.get +../bin/occmd ethernet.port3.config.duplex.get +../bin/occmd ethernet.port3.config.powerDown.get +../bin/occmd ethernet.port3.config.enable_sleepMode.get +../bin/occmd ethernet.port3.config.enable_interrupt.get +#../bin/occmd ethernet.port3.config.switch_reset get +#../bin/occmd ethernet.port3.config.restart_autoneg get +../bin/occmd ethernet.port4.config.speed.get +../bin/occmd ethernet.port4.config.duplex.get +../bin/occmd ethernet.port4.config.powerDown.get +../bin/occmd ethernet.port4.config.enable_sleepMode.get +../bin/occmd ethernet.port4.config.enable_interrupt.get +#../bin/occmd ethernet.port4.config.switch_reset get +#../bin/occmd ethernet.port4.config.restart_autoneg get +elif [ $2 = "status" ]; then +../bin/occmd ethernet.port0.status.speed.get +../bin/occmd ethernet.port0.status.duplex.get +../bin/occmd ethernet.port0.status.sleep_mode_en.get +../bin/occmd ethernet.port0.status.autoneg_on.get +../bin/occmd ethernet.port0.status.autoneg_complete.get +../bin/occmd ethernet.port0.status.link_up.get +../bin/occmd ethernet.port1.status.speed.get +../bin/occmd ethernet.port1.status.duplex.get +../bin/occmd ethernet.port1.status.sleep_mode_en.get +../bin/occmd ethernet.port1.status.autoneg_on.get +../bin/occmd ethernet.port1.status.autoneg_complete.get +../bin/occmd ethernet.port1.status.link_up.get +../bin/occmd ethernet.port2.status.speed.get +../bin/occmd ethernet.port2.status.duplex.get +../bin/occmd ethernet.port2.status.sleep_mode_en.get +../bin/occmd ethernet.port2.status.autoneg_on.get +../bin/occmd ethernet.port2.status.autoneg_complete.get +../bin/occmd ethernet.port2.status.link_up.get +../bin/occmd ethernet.port3.status.speed.get +../bin/occmd ethernet.port3.status.duplex.get +../bin/occmd ethernet.port3.status.sleep_mode_en.get +../bin/occmd ethernet.port3.status.autoneg_on.get +../bin/occmd ethernet.port3.status.autoneg_complete.get +../bin/occmd ethernet.port3.status.link_up.get +../bin/occmd ethernet.port4.status.speed.get +../bin/occmd ethernet.port4.status.duplex.get +../bin/occmd ethernet.port4.status.sleep_mode_en.get +../bin/occmd ethernet.port4.status.autoneg_on.get +../bin/occmd ethernet.port4.status.autoneg_complete.get +../bin/occmd ethernet.port4.status.link_up.get +else + echo "Invalid Option" +fi +elif [ $1 = "sync" ]; then +if [ $2 = "config" ]; then +../bin/occmd sync.sensor.config.temp_sensor1.lowlimit.get +../bin/occmd sync.sensor.config.temp_sensor1.highlimit.get +../bin/occmd sync.sensor.config.temp_sensor1.critlimit.get +elif [ $2 = "status" ]; then +../bin/occmd sync.gps.status.gps_lock.get +../bin/occmd sync.sensor.status.temp_sensor1.temperature.get +else + echo "Invalid Option" +fi +elif [ $1 = "testmodule" ]; then +if [ $2 = "status" ]; then +../bin/occmd testmodule.2gsim.status.imei.get +../bin/occmd testmodule.2gsim.status.imsi.get +../bin/occmd testmodule.2gsim.status.mfg.get +../bin/occmd testmodule.2gsim.status.model.get +../bin/occmd testmodule.2gsim.status.rssi.get +../bin/occmd testmodule.2gsim.status.ber.get +../bin/occmd testmodule.2gsim.status.registration.get +../bin/occmd testmodule.2gsim.status.network_operatorinfo.get +../bin/occmd testmodule.2gsim.status.cellid.get +../bin/occmd testmodule.2gsim.status.bsic.get +../bin/occmd testmodule.2gsim.status.lasterror.get +else + echo "Invalid Option" +fi +elif [ $1 = "obc" ]; then +if [ $2 = "status" ]; then +../bin/occmd obc.iridium.status.imei.get +../bin/occmd obc.iridium.status.mfg.get +../bin/occmd obc.iridium.status.model.get +../bin/occmd obc.iridium.status.signal_quality.get +../bin/occmd obc.iridium.status.registration.get +../bin/occmd obc.iridium.status.numberofoutgoingmessage.get +../bin/occmd obc.iridium.status.lasterror.get +else + echo "Invalid Option" +fi +elif [ $1 = "hci" ]; then +if [ $2 = "config" ]; then +../bin/occmd hci.led.config.temp_sensor1.lowlimit.get +../bin/occmd hci.led.config.temp_sensor1.highlimit.get +../bin/occmd hci.led.config.temp_sensor1.critlimit.get +elif [ $2 = "status" ]; then +../bin/occmd hci.led.status.temp_sensor1.temperature.get +#../bin/occmd hci.led.config.ledstate get +else + echo "Invalid Option" +fi +elif [ $1 = "system" ]; then +if [ $2 = "status" ]; then +../bin/occmd system.comp_all.status.eeprom_sid.gbcboardinfo.get +../bin/occmd system.comp_all.status.eeprom_sid.ocserialinfo.get +../bin/occmd system.comp_all.config.eeprom_mac.address.get +../bin/occmd system.comp_all.echo +../bin/occmd system.comp_all.reset + +../bin/occmd testmodule.2gsim.disconnect_nw +../bin/occmd testmodule.2gsim.connect_nw +../bin/occmd testmodule.2gsim.send 9789799425 hi +../bin/occmd testmodule.2gsim.dial 9789799425 +../bin/occmd testmodule.2gsim.answer_call +../bin/occmd testmodule.2gsim.hangup_call +../bin/occmd testmodule.comp_all.reset +../bin/occmd obc.iridium.reset +../bin/occmd ethernet.port0.reset +../bin/occmd ethernet.port1.reset +../bin/occmd ethernet.port2.reset +../bin/occmd ethernet.port3.reset +../bin/occmd power.pse.reset +../bin/occmd rffe.comp_all.reset +../bin/occmd gpp.ap.reset +../bin/occmd hci.led.fw.set 1 +../bin/occmd rffe.ch1_fe.enable +../bin/occmd rffe.ch1_fe.disable +../bin/occmd rffe.ch2_fe.disable +../bin/occmd rffe.ch2_fe.enable +../bin/occmd testmodule.2gsim.enable +../bin/occmd testmodule.2gsim.disable +../bin/occmd sdr.comp_all.reset +../bin/occmd sdr.fx3.reset +../bin/occmd ethernet.port0.en_loopBk 0 +../bin/occmd ethernet.port0.en_pktGen 8374 +../bin/occmd ethernet.port0.dis_pktGen +../bin/occmd ethernet.port0.dis_loopBk 0 +../bin/occmd ethernet.port1.en_loopBk 0 +../bin/occmd ethernet.port1.en_pktGen 8374 +../bin/occmd ethernet.port1.dis_pktGen +../bin/occmd ethernet.port1.dis_loopBk 0 +../bin/occmd ethernet.port2.en_loopBk 0 +../bin/occmd ethernet.port2.en_pktGen 8374 +../bin/occmd ethernet.port2.dis_pktGen +../bin/occmd ethernet.port2.dis_loopBk 0 +../bin/occmd ethernet.port3.en_loopBk 0 +../bin/occmd ethernet.port3.en_pktGen 8374 +../bin/occmd ethernet.port3.dis_pktGen +../bin/occmd ethernet.port3.dis_loopBk 0 +../bin/occmd ethernet.port4.en_loopBk 0 +../bin/occmd ethernet.port4.en_pktGen 8374 +../bin/occmd ethernet.port4.dis_pktGen +../bin/occmd ethernet.port4.dis_loopBk 0 +else + echo "Invalid Option" +fi +elif [ $1 = "debug" ]; then +if [ $2 = "I2C" ]; then +../bin/occmd debug.I2C.bus0.get 104 2 58 +../bin/occmd debug.I2C.bus1.get 24 2 2 +../bin/occmd debug.I2C.bus2.get 29 1 0 +../bin/occmd debug.I2C.bus3.get 68 2 255 +../bin/occmd debug.I2C.bus4.get 65 2 254 +../bin/occmd debug.I2C.bus6.get 64 2 5 +../bin/occmd debug.I2C.bus7.get 69 2 5 +../bin/occmd debug.I2C.bus8.get 26 2 6 +elif [ $2 = "GPIO" ]; then +../bin/occmd debug.ec.PA.get 1 +../bin/occmd debug.ec.PB.get 1 +../bin/occmd debug.ec.PC.get 1 +../bin/occmd debug.ec.PD.get 7 +../bin/occmd debug.ec.PE.get 1 +../bin/occmd debug.ec.PF.get 1 +../bin/occmd debug.ec.PG.get 1 +../bin/occmd debug.ec.PJ.get 1 +../bin/occmd debug.ec.PK.get 1 +../bin/occmd debug.ec.PL.get 5 +../bin/occmd debug.ec.PM.get 1 +../bin/occmd debug.ec.PN.get 1 +../bin/occmd debug.ec.PP.get 3 +../bin/occmd debug.ec.PQ.get 1 +../bin/occmd debug.gbc.ioexpanderx70.get 1 +../bin/occmd debug.gbc.ioexpanderx71.get 0 +../bin/occmd debug.sdr.ioexpanderx1E.get 1 +../bin/occmd debug.fe.ioexpanderx18.get 1 +../bin/occmd debug.fe.ioexpanderx1A.get 0 +../bin/occmd debug.fe.ioexpanderx1B.get 1 +../bin/occmd debug.fe.ioexpanderx1C.get 1 +../bin/occmd debug.fe.ioexpanderx1D.get 1 +../bin/occmd debug.sync.ioexpanderx71.get 1 +elif [ $2 = "MDIO" ]; then +../bin/occmd debug.ethernet.port0.get 1 +../bin/occmd debug.ethernet.port1.get 1 +../bin/occmd debug.ethernet.port2.get 1 +../bin/occmd debug.ethernet.port3.get 1 +../bin/occmd debug.ethernet.port4.get 1 +../bin/occmd debug.ethernet.global1.get 1 +../bin/occmd debug.ethernet.global2.get 1 +../bin/occmd debug.ethernet.swport0.get 1 +../bin/occmd debug.ethernet.swport1.get 1 +../bin/occmd debug.ethernet.swport2.get 1 +../bin/occmd debug.ethernet.swport3.get 1 +../bin/occmd debug.ethernet.swport4.get 1 +../bin/occmd debug.ethernet.swport5.get 1 +../bin/occmd debug.ethernet.swport6.get 1 +else + echo "Invalid Option" +fi +else + echo "Invalid Option" +fi + +echo "Done..." diff --git a/firmware/host/ocwarestub/ocware_stub_database.c b/firmware/host/ocwarestub/ocware_stub_database.c new file mode 100755 index 0000000000..3bfc7037de --- /dev/null +++ b/firmware/host/ocwarestub/ocware_stub_database.c @@ -0,0 +1,1117 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include + +static OCWareStubsizeflag s_typeFlag; +static OCWareStubDatabase s_ocwareGlobalData[MAX_NUMBER_PARAM]; +static OCWareStubPostData s_postGlobalArray[MAX_POST_DEVICE]; + +static int16_t s_defInt16Val = DEFAULT_INT16; +static int64_t s_defInt64Val = DEFAULT_INT64; +static int8_t s_defInt8Val = DEFAULT_INT8; +static int32_t s_defInt32Val = DEFAULT_INT32; +static int8_t s_defEnumVal = DEFAULT_ENUM; +static int8_t s_debugSubsystem = 0; + +int8_t debugGetCommand = STUB_FAILED; +int8_t debugSetCommand = STUB_FAILED; +int8_t PostResult = STUB_FAILED; +int8_t PostEnable = STUB_FAILED; +extern const Component sys_schema[]; +/****************************************************************************** + * Function Name : ocware_stub_set_gpioinfo + * Description : Modify the GPIO information in the DB for debug subsystem + * + * @param gStructIndex - Index of the database (by value) + * @param payload - payload field of the message from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_set_gpioinfo(int16_t gStructIndex, + char *payload) +{ + OCWareDebugGPIOinfo **GPIOInfo; + ocware_stub_ret ret = STUB_FAILED; + int8_t pos = 0; + int8_t index = 0; + + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return ret; + } + + GPIOInfo = (OCWareDebugGPIOinfo**)&s_ocwareGlobalData[gStructIndex].data; + for(index = 0; index< MAX_GPIO_COMP_NBR; index++) { + if (GPIOInfo[index]->pin_nbr == payload[pos]) { + ret = STUB_SUCCESS; + GPIOInfo[index]->value = payload[pos + 1]; + break; + } + } + + return ret; +} + +/****************************************************************************** + * Function Name : ocware_stub_set_i2cinfo + * Description : Modify the I2C information in the DB for debug subsystem + * + * @param gStructIndex - Index of the database (by value) + * @param payload - payload field of the message from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_set_i2cinfo(int16_t gStructIndex, + char *payload) +{ + OCWareDebugI2Cinfo **I2CInfo; + ocware_stub_ret ret = STUB_FAILED; + int8_t pos = 0; + int8_t index = 0; + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return ret; + } + I2CInfo = (OCWareDebugI2Cinfo **)&s_ocwareGlobalData[gStructIndex].data; + for(index = 0; index < MAX_I2C_COMP_NBR; index++) { + if (I2CInfo[index]->slaveAddress == payload[pos]) { + ret = STUB_SUCCESS; + break; + } + } + + if (ret !=STUB_SUCCESS) + return ret; + + I2CInfo[index]->slaveAddress = payload[pos]; + I2CInfo[index]->numOfBytes = payload[pos + 1]; + I2CInfo[index]->regAddress = payload[pos + 2]; + if (I2CInfo[index]->numOfBytes == 1) { + I2CInfo[index]->regValue = payload[pos + 3]; + } else { + I2CInfo[index]->regValue = ((uint8_t)payload[pos + 3] << 0x08) + + payload[pos + 4]; + payload[pos + 4] = + (uint8_t)(I2CInfo[index]->regValue & MASK_LSB); + payload[pos + 3] = + (uint8_t)((I2CInfo[index]->regValue & MASK_MSB) >> SHIFT_NIBBLE); + } + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_set_mdioinfo + * Description : Modify the MDIO information in the DB for debug subsystem + * + * @param gStructIndex - Index of the database (by value) + * @param payload - payload field of the message from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_set_mdioinfo(int16_t gStructIndex, + char *payload) +{ + OCWareDebugMDIOinfo **MDIOInfo; + ocware_stub_ret ret = STUB_FAILED; + int8_t pos = 0; + int8_t index = 0; + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return ret; + } + MDIOInfo = (OCWareDebugMDIOinfo **)&s_ocwareGlobalData[gStructIndex].data; + for(index = 0; index< MAX_MDIO_COMP_NBR; index++) { + if (MDIOInfo[index]->regAddress == payload[pos]) { + ret = STUB_SUCCESS; + break; + } + } + if (ret !=STUB_SUCCESS) + return ret; + + MDIOInfo[index]->regAddress = payload[pos]; + MDIOInfo[index]->regValue = ((uint8_t)payload[pos + 3] << 0x08) + + payload[pos + 2]; + payload[pos + 2] = + (uint8_t)(MDIOInfo[index]->regValue & MASK_LSB); + payload[pos + 3] = + (uint8_t)((MDIOInfo[index]->regValue & MASK_MSB) >> SHIFT_NIBBLE); + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_get_post_database + * Description : extract device number and status from the post database + * depending on the subsytem id + * + * @param msgFrameData - output pointer to the OCMPheader field of the message + * from MW (by reference) + * @param payload - output pointer to the payload field of the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_post_database(OCMPMessage *msgFrameData, + char *payload) +{ + int16_t index = 0; + uint8_t pos = 0; + + for(index = 0; index < MAX_POST_DEVICE; index++) { + if ((s_postGlobalArray[index].SubsystemId + == payload[0]) && + (s_postGlobalArray[index].DeviceNumber > 0)) { + + payload[pos] = s_postGlobalArray[index].SubsystemId; + payload[pos + 1] = + s_postGlobalArray[index].DeviceNumber; + payload[pos + 2] = + s_postGlobalArray[index].Status; + pos = pos + 3; + } + } + msgFrameData->parameters = pos/3; + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : ocware_stub_get_gpioinfo + * Description : retrieve the GPIO information in the DB for debug + * subsystem + * + * @param gStructIndex index of the database (by value) + * @param payload output pointer to the payload filed of the + * message from MW (by pointer) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_gpioinfo(int16_t gStructIndex, + char *payload) +{ + OCWareDebugGPIOinfo **GPIOInfo; + ocware_stub_ret ret = STUB_FAILED; + uint8_t pos = 0; + uint8_t index = 0; + + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return ret; + } + GPIOInfo = (OCWareDebugGPIOinfo**)&s_ocwareGlobalData[gStructIndex].data; + for(index = 0; index< MAX_GPIO_COMP_NBR; index++) { + if (GPIOInfo[index]->pin_nbr == payload[pos]) { + ret = STUB_SUCCESS; + break; + } + } + + if(ret == STUB_SUCCESS) { + payload[pos] = GPIOInfo[index]->pin_nbr; + payload[pos + 1] = GPIOInfo[index]->value; + } + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_get_i2cinfo + * Description : retrieve the I2C information in the DB for debug + * subsystem + * + * @param gStructIndex index of the database (by value) + * @param payload output pointer to the payload filed of the + * message from MW (by pointer) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_i2cinfo(int16_t gStructIndex, + char *payload) +{ + OCWareDebugI2Cinfo **I2CInfo; + ocware_stub_ret ret = STUB_FAILED; + uint8_t pos = 0; + uint8_t index = 0; + + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return ret; + } + + I2CInfo = (OCWareDebugI2Cinfo**)&s_ocwareGlobalData[gStructIndex].data; + for(index = 0; index< MAX_I2C_COMP_NBR; index++) { + if (I2CInfo[index]->slaveAddress == payload[pos]) { + ret = STUB_SUCCESS; + break; + } + } + + if(ret == STUB_SUCCESS) { + payload[pos] = I2CInfo[index]->slaveAddress; + payload[pos + 1] = I2CInfo[index]->numOfBytes; + payload[pos + 2] = I2CInfo[index]->regAddress; + if (I2CInfo[index]->numOfBytes == 1) { + payload[pos + 3] = (uint8_t)I2CInfo[index]->regValue; + } else { + payload[pos + 4] + = (uint8_t)(I2CInfo[index]->regValue & MASK_LSB); + payload[pos + 3] = (uint8_t) + ((I2CInfo[index]->regValue & MASK_MSB) >> SHIFT_NIBBLE); + } + } + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_get_mdioinfo + * Description : retrieve the MDIO information in the DB for debug + * subsystem + * + * @param gStructIndex index of the database (by value) + * @param payload output pointer to the payload filed of the + * message from MW (by pointer) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_mdioinfo(int16_t gStructIndex, + char *payload) +{ + OCWareDebugMDIOinfo **MDIOInfo; + ocware_stub_ret ret = STUB_FAILED; + uint8_t pos = 0; + uint8_t index = 0; + + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return ret; + } + + MDIOInfo = (OCWareDebugMDIOinfo**)&s_ocwareGlobalData[gStructIndex].data; + for(index = 0; index < MAX_MDIO_COMP_NBR; index++) { + if (MDIOInfo[index]->regAddress == payload[pos]) { + ret = STUB_SUCCESS; + break; + } + } + + if(ret == STUB_SUCCESS) { + payload[pos] = MDIOInfo[index]->regAddress; + payload[pos + 2] = (uint8_t) + (MDIOInfo[index]->regValue & MASK_LSB); + payload[pos + 3] = (uint8_t) + ((MDIOInfo[index]->regValue & MASK_MSB) >> SHIFT_NIBBLE); + } + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_debug_subsytem + * Description : Process the command message for debug subsytem + * + * @param gStructIndex - index to the DB (by value) + * @param payload - output pointer to the payload field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_debug_subsytem(int16_t gStructIndex, + char *payload, + int8_t flag) +{ + if (!(gStructIndex <= MAX_NUMBER_PARAM && payload)) { + return STUB_FAILED; + } + switch(s_ocwareGlobalData[gStructIndex].componentId) { + case 2: + if ( flag == OCMP_AXN_TYPE_GET) { + ocware_stub_get_i2cinfo(gStructIndex, payload); + } else { + ocware_stub_set_i2cinfo(gStructIndex, payload); + } + break; + case 8: + if ( flag == OCMP_AXN_TYPE_GET) { + ocware_stub_get_mdioinfo(gStructIndex, payload); + } else { + ocware_stub_set_mdioinfo(gStructIndex, payload); + } + break; + default: + if ( flag == OCMP_AXN_TYPE_GET) { + ocware_stub_get_gpioinfo(gStructIndex, payload); + } else { + ocware_stub_set_gpioinfo(gStructIndex, payload); + } + } + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : ocware_stub_get_database + * Description : Function to retrieve data from the DB + * + * @param msgFrameData - Pointer to the message frame field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_database(OCMPMessage *msgFrameData) +{ + char *payload = NULL; + ocware_stub_ret ret = STUB_FAILED; + int8_t subsystem = 0; + int8_t component = 0; + int8_t msgtype = 0; + int8_t parampos = 0; + int16_t paramId = 0; + int16_t gStructIndex = 0; + + if(msgFrameData == NULL) { + return ret; + } + payload = (char*)&msgFrameData->info; + subsystem = msgFrameData->subsystem; + component = msgFrameData->componentID; + msgtype = msgFrameData->msgtype; + paramId = msgFrameData->parameters; + + for(gStructIndex = 0; gStructIndex < MAX_NUMBER_PARAM; gStructIndex++) { + if((subsystem == s_ocwareGlobalData[gStructIndex].subsystemId) && + (component == s_ocwareGlobalData[gStructIndex].componentId) && + (msgtype == s_ocwareGlobalData[gStructIndex].msgtype) && + (paramId == s_ocwareGlobalData[gStructIndex].paramId)) + { + ret = STUB_SUCCESS; + parampos = s_ocwareGlobalData[gStructIndex].paramPos; + break; + } + } + + if(ret == STUB_SUCCESS) { + if(subsystem == s_debugSubsystem) { + ret = ocware_stub_debug_subsytem(gStructIndex, payload, + OCMP_AXN_TYPE_GET); + } else { + strncpy(&payload[parampos], + (char*)s_ocwareGlobalData[gStructIndex].data, + s_ocwareGlobalData[gStructIndex].paramSize); + } + } + return ret; +} + +/****************************************************************************** + * Function Name : ocware_stub_set_database + * Description : Function to modify data in the DB + * + * @param msgFrameData - Pointer to the message frame field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_set_database(OCMPMessage *msgFrameData) +{ + char *payload = NULL; + ocware_stub_ret ret = STUB_FAILED; + int8_t subsystem = 0; + int8_t component = 0; + int8_t msgtype = 0; + int8_t parampos = 0; + int16_t paramId = 0; + int16_t gStructIndex = 0; + + if(msgFrameData == NULL) { + return ret; + } + payload = (char*)&msgFrameData->info; + subsystem = msgFrameData->subsystem; + component = msgFrameData->componentID; + msgtype = msgFrameData->msgtype; + paramId = msgFrameData->parameters; + + for(gStructIndex = 0; gStructIndex < MAX_NUMBER_PARAM; gStructIndex++) { + if( (subsystem == s_ocwareGlobalData[gStructIndex].subsystemId) && + (component == s_ocwareGlobalData[gStructIndex].componentId) && + (msgtype == s_ocwareGlobalData[gStructIndex].msgtype) && + (paramId == s_ocwareGlobalData[gStructIndex].paramId)) + { + ret = STUB_SUCCESS; + parampos = s_ocwareGlobalData[gStructIndex].paramPos; + break; + } + } + + if(ret == STUB_SUCCESS) { + if(subsystem == s_debugSubsystem) { + ret = ocware_stub_debug_subsytem(gStructIndex, payload, + OCMP_AXN_TYPE_SET); + } else { + strncpy((char*)s_ocwareGlobalData[gStructIndex].data, + &payload[parampos], + s_ocwareGlobalData[gStructIndex].paramSize); + } + } + return ret; +} + +/****************************************************************************** + * Function Name : ocware_stub_fill_init_value + * Description : Function to fill default value in the DB + * + * @param param - pointer to the parameter field in a particular subsytem and + * component (by value) + * gStructIndex - index to the DB (by value) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_fill_init_value(const Parameter *param, + uint16_t gStructIndex) +{ + const char *paramtype; + int16_t def_lasterror = 0x101; + int16_t def_netOp = 0x001; + + if(param == NULL) { + return STUB_FAILED; + } + + paramtype = DATA_TYPE_MAP[param->type]; + + if (!strcmp("lasterror",param->name)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&def_lasterror); + return STUB_SUCCESS; + } else if (!strcmp("network_operatorinfo",param->name)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&def_netOp); + return STUB_SUCCESS; + } + if (!strcmp("uint16",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char *)&s_defInt16Val); + } else if (!strcmp("int16",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&s_defInt16Val); + } else if (!strcmp("uint8",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&s_defInt8Val); + } else if (!strcmp("int8",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&s_defInt8Val); + } else if (!strcmp("uint32",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&s_defInt32Val); + } else if (!strcmp("uint64",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char *)&s_defInt64Val); + } else if (!strcmp("string",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, DEFAULT_STRING); + } else if (!strcmp("enum",paramtype)) { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&s_defEnumVal); + } else { + strcpy(s_ocwareGlobalData[gStructIndex].data, (char*)&s_defInt8Val); + } + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : ocware_stub_get_paramSize + * Description : Return the size of the parameter + * + * @param paramtype - pointer to a particular parameter in the schema + * (by reference) + * msgtype - msgtype field of the message from MW (by value) + * param_name - pointer to the name of a parameter in the schema + * (by reference) + * @return Size of the parameter + * + ******************************************************************************/ +int8_t ocware_stub_get_paramSize(const char* paramtype, + int8_t msgtype, + const char* param_name) +{ + int8_t paramSize = 0; + + if (paramtype == NULL) { + printf("Invalid paramtype\n"); + return STUB_FAILED; + } + + if (!strcmp("uint16",paramtype)) { + paramSize = sizeof(uint16_t); + } else if (!strcmp("int16",paramtype)) { + paramSize = sizeof(int16_t); + } else if (!strcmp("uint8",paramtype)) { + paramSize = sizeof(uint8_t); + } else if (!strcmp("int8",paramtype)) { + paramSize = sizeof(int8_t); + } else if (!strcmp("uint32",paramtype)) { + paramSize = sizeof(uint32_t); + } else if (!strcmp("uint64",paramtype)) { + paramSize = sizeof(uint64_t); + } else if (!strcmp("string",paramtype)) { + if (s_typeFlag == OCSTUB_VALUE_TYPE_MFG) { + paramSize = SIZE_OF_TYPE_MFG; + } else if (s_typeFlag == OCSTUB_VALUE_TYPE_MODEL) { + paramSize = SIZE_OF_TYPE_MODEL; + } else if (s_typeFlag == OCSTUB_VALUE_TYPE_GETMODEL) { + paramSize = SIZE_OF_TYPE_GETMODEL; + } else if (s_typeFlag == OCSTUB_VALUE_TYPE_OCSERIAL_INFO) { + paramSize = SIZE_OF_TYPE_OCSERIAL_INFO; + } else if (s_typeFlag == OCSTUB_VALUE_TYPE_GBCBOARD_INFO) { + paramSize = SIZE_OF_TYPE_GBCBOARD_INFO; + } else { + if (msgtype == OCMP_MSG_TYPE_CONFIG) { + paramSize = EEPROM_CONFIG_MAX_SIZE; + } else if (msgtype == OCMP_MSG_TYPE_STATUS) { + paramSize = EEPROM_STATUS_MAX_SIZE; + } + } + } else if (!strcmp("enum",paramtype)) { + if (s_typeFlag == OCSTUB_VALUE_TYPE_REGISTRATION) { + paramSize = SIZE_OF_TYPE_REGISTRATION; /* TO DO */ + } else if (s_typeFlag == OCSTUB_VALUE_TYPE_NWOP_STRUCT) { + paramSize = SIZE_OF_NWOP_STRUCT; + } else if (s_typeFlag == OCSTUB_VALUE_TYPE_LAST_ERROR) { + paramSize = SIZE_OF_LAST_ERROR; + } else { + paramSize = OCMW_VALUE_TYPE_ENUM; + } + } else { + paramSize = sizeof(int8_t); + } + + return paramSize; +} +/****************************************************************************** + * Function Name : ocware_stub_fill_init_debug_value + * Description : Fill default values for debug subsytem + * + * @param gStructIndex - index to the DB (by value) + * flag - OCSTUB_VALUE_TYPE_GPIO_DEBUG -To modify GPIO parameters + * OCSTUB_VALUE_TYPE_I2C_DEBUG - To modify I2C parameters + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_fill_init_debug_value(int16_t gStructIndex, + OCWareStubsizeflag flag) +{ + OCWareDebugI2Cinfo I2CInfo[MAX_I2C_COMP_NBR]; + OCWareDebugGPIOinfo GPIOInfo[MAX_GPIO_COMP_NBR]; + OCWareDebugMDIOinfo MDIOInfo[MAX_MDIO_COMP_NBR]; + uint8_t index = 0; + + if(gStructIndex >= MAX_NUMBER_PARAM) { + return STUB_FAILED; + } + if ( flag == OCSTUB_VALUE_TYPE_GPIO_DEBUG) { + for(index = 0; index < MAX_GPIO_COMP_NBR; index++) { + GPIOInfo[index].pin_nbr = GPIO_PIN_NBR + index; + GPIOInfo[index].value = GPIO_VALUE; + } + memcpy(s_ocwareGlobalData[gStructIndex].data, + (char *)GPIOInfo, sizeof(GPIOInfo)*MAX_GPIO_COMP_NBR); + + } else if ( flag == OCSTUB_VALUE_TYPE_MDIO_DEBUG){ + for(index = 0; index < MAX_MDIO_COMP_NBR; index++) { + MDIOInfo[index].regAddress = I2C_REG_ADDRESS + index; + MDIOInfo[index].regValue = I2C_REG_VALUE; + } + memcpy(s_ocwareGlobalData[gStructIndex].data, + (char *)MDIOInfo, sizeof(MDIOInfo)*MAX_MDIO_COMP_NBR); + }else { + for(index = 0; index < MAX_I2C_COMP_NBR; index++) { + I2CInfo[index].slaveAddress = I2C_SLAVE_ADDRESS + index; + I2CInfo[index].numOfBytes = I2C_NUM_BYTES; + I2CInfo[index].regAddress = I2C_REG_ADDRESS; + I2CInfo[index].regValue = I2C_REG_VALUE; + } + memcpy(s_ocwareGlobalData[gStructIndex].data, + (char *)I2CInfo, sizeof(I2CInfo)*MAX_I2C_COMP_NBR); + } + + return STUB_SUCCESS; +} + +/****************************************************************************** + * Function Name : ocware_create_command_debug_database + * Description : Create entries into the DB for debug subsystem + * + * @param : subsystemNbr - subsytem number in the schema (by value) + * gStructIndex - output pointer to the index in the DB (by reference) + * subSystem - pointer to the debug subsytem in the schema + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_create_command_debug_database(int8_t subsystemNbr, + int16_t *gStructIndex, + const Component *subSystem) +{ + ocware_stub_ret ret = STUB_FAILED; + const Component *component = NULL; + const Component *subComponent = NULL; + const Driver *driver = NULL; + const Command *command = NULL; + int8_t componentNbr = 1; + int8_t count = 0; + int8_t commandCount = 0; + s_debugSubsystem = subsystemNbr; + + if((gStructIndex == NULL) || (subSystem == NULL)) { + return STUB_FAILED; + } + for(component = subSystem->components; component && component->name; + component++) { + /* component loop */ + subComponent = component->components; + count = 1; + while (subComponent && subComponent->name) { + driver = subComponent->driver; + if(driver !=NULL) { + /* No Need to read every command as + * current implementation is to have one entry + * for one subsystem + */ + s_ocwareGlobalData[*gStructIndex].subsystemId = subsystemNbr; + s_ocwareGlobalData[*gStructIndex].componentId = componentNbr; + s_ocwareGlobalData[*gStructIndex].msgtype = + OCMP_MSG_TYPE_COMMAND; + s_ocwareGlobalData[*gStructIndex].paramPos = 0; + + if (strncmp(component->name,"I2C", + strlen("I2C")) == 0) { + s_ocwareGlobalData[*gStructIndex].paramId = count; + s_ocwareGlobalData[*gStructIndex].paramSize + = sizeof(OCWareDebugI2Cinfo) * MAX_I2C_COMP_NBR; + s_ocwareGlobalData[*gStructIndex].data + = malloc(s_ocwareGlobalData[*gStructIndex].paramSize); + if (s_ocwareGlobalData[*gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[*gStructIndex].data, 0, + s_ocwareGlobalData[*gStructIndex].paramSize); + } + ret = ocware_stub_fill_init_debug_value(*gStructIndex, + OCSTUB_VALUE_TYPE_I2C_DEBUG); + } else if (strncmp(component->name,"ethernet", + strlen("ethernet")) == 0) { + s_ocwareGlobalData[*gStructIndex].paramId = count; + s_ocwareGlobalData[*gStructIndex].paramSize + = sizeof(OCWareDebugMDIOinfo) * MAX_MDIO_COMP_NBR; + s_ocwareGlobalData[*gStructIndex].data + = malloc(s_ocwareGlobalData[*gStructIndex].paramSize); + if (s_ocwareGlobalData[*gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[*gStructIndex].data, 0, + s_ocwareGlobalData[*gStructIndex].paramSize); + } + ret = ocware_stub_fill_init_debug_value(*gStructIndex, + OCSTUB_VALUE_TYPE_MDIO_DEBUG); + + } else { + /* Currently its all GPIO */ + s_ocwareGlobalData[*gStructIndex].paramId = count; + s_ocwareGlobalData[*gStructIndex].paramSize + = sizeof(OCWareDebugGPIOinfo) * MAX_GPIO_COMP_NBR; + s_ocwareGlobalData[*gStructIndex].data + = malloc(s_ocwareGlobalData[*gStructIndex].paramSize); + if (s_ocwareGlobalData[*gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[*gStructIndex].data, 0, + s_ocwareGlobalData[*gStructIndex].paramSize); + } + ret = ocware_stub_fill_init_debug_value(*gStructIndex, + OCSTUB_VALUE_TYPE_GPIO_DEBUG); + } + (*gStructIndex)++; + if((debugGetCommand == STUB_FAILED) || + (debugSetCommand == STUB_FAILED)) { + command = driver->commands; + commandCount = 0; + while(command && command->name) { + if ((strncmp(command->name, "get", strlen("get"))) == + 0) { + debugGetCommand = commandCount; + } else if ((strncmp(command->name, "set",strlen("set"))) + == 0) { + debugSetCommand = commandCount; + } + command += 1; + commandCount++; + } + } + } + subComponent += 1; + count ++; + } + componentNbr++; + } + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_create_post_database + * Description : Parse the schema and add post entries + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + *****************************************************************************/ +ocware_stub_ret ocware_stub_create_post_database() +{ + int8_t subsystemNbr = 0; + const Component *component = NULL; + const Component *subComponent = NULL; + const Component *subSystem = NULL; + int8_t count = 1; + int16_t PostIndex = 0; + + for (subSystem = sys_schema; subSystem && subSystem->name; subSystem++) { + /* Subsystem loop */ + count = 1; + for(component = subSystem->components; component && component->name; + component++) { + /* component loop */ + subComponent = component->components; + if ((subComponent == NULL) && + (component->postDisabled != POST_DISABLED)) { + s_postGlobalArray[PostIndex].SubsystemId = subsystemNbr; + s_postGlobalArray[PostIndex].DeviceNumber = count; + if(count < 10) { + s_postGlobalArray[PostIndex].Status = count - 1; + } else { + s_postGlobalArray[PostIndex].Status = 9; + } + PostIndex++; + count++; + } + /* If subcomponents exist */ + while (subComponent && subComponent->name) { + if (subComponent->postDisabled != POST_DISABLED) { + s_postGlobalArray[PostIndex].SubsystemId = subsystemNbr; + s_postGlobalArray[PostIndex].DeviceNumber = count; + if(count < 10) { + s_postGlobalArray[PostIndex].Status = count - 1; + } else { + s_postGlobalArray[PostIndex].Status = 9; + } + PostIndex++; + count++; + } + subComponent += 1; + } /* sub comp loop */ + } /* component loop */ + subsystemNbr++; + }/*subsystem loop */ + return STUB_SUCCESS; +} + +/****************************************************************************** + * Function Name : ocware_stub_init_post + * Description : Calculate the param id for post messages + * + * @param devDriver - pointer to the post driver + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + *****************************************************************************/ +ocware_stub_ret ocware_stub_init_post(const Driver *devDriver) +{ + ocware_stub_ret ret = STUB_FAILED; + const Post *post = NULL; + uint16_t count = 0; + + if(devDriver == NULL) + return ret; + + post = devDriver->post; + while (post && post->name) { + if (strncmp(post->name, "results", + strlen(post->name)) == 0) { + PostResult = pow(2, count); + } else if (strncmp(post->name, "enable", + strlen(post->name)) == 0) { + PostEnable = pow(2, count); + } else { + printf("Post init failed\n"); + return ret; + } + count++; + post++; + } + + if ((PostResult != STUB_FAILED) && + (PostEnable != STUB_FAILED)) { + ret = STUB_SUCCESS; + } else { + printf("Post init failed\n"); + } + return ret; +} + +/****************************************************************************** + * Function Name : ocware_stub_init_database + * Description : Parse the schema and add entries in the DB + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_init_database() +{ + + ocware_stub_ret ret = STUB_FAILED; + int8_t subsystemNbr = 0; + int8_t componentNbr = 0; + const Component *component = NULL; + const Component *subComponent = NULL; + const Component *subSystem = NULL; + const Driver *devDriver = NULL; + const Parameter *param = NULL; + int8_t count = 0; + int8_t configCount = 0; + int8_t statusCount = 0; + int16_t gStructIndex = 0; + int16_t paramPos = 0; + int16_t configParamPos = 0; + int16_t statusParamPos = 0; + + for (subSystem = sys_schema; subSystem && subSystem->name; subSystem++) { + /* Subsystem loop */ + componentNbr = 1; + if (strncmp(subSystem->name, "debug", + strlen(subSystem->name)) == 0) { + ocware_create_command_debug_database(subsystemNbr, + &gStructIndex, subSystem); + } + for(component = subSystem->components; component && component->name; + component++) { + /* component loop */ + devDriver = component->driver; + if (devDriver != NULL) { + if (devDriver->post != NULL) { + /* POST is currently designed to be existing in one driver */ + ret = ocware_stub_init_post(devDriver); + + if(ret != STUB_SUCCESS) + return ret; + } + /* This is for componenets w/o any sub component */ + count = 0; + paramPos = 0; + param = devDriver->config; + /* Config related parameters */ + while (param && param->name) { /*Parameter loop */ + s_ocwareGlobalData[gStructIndex].subsystemId = subsystemNbr; + s_ocwareGlobalData[gStructIndex].componentId = componentNbr; + s_ocwareGlobalData[gStructIndex].paramId + = pow(2,count); + s_ocwareGlobalData[gStructIndex].paramSize = + ocware_stub_get_paramSize ( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_CONFIG, param->name); + s_ocwareGlobalData[gStructIndex].msgtype = + OCMP_MSG_TYPE_CONFIG; + s_ocwareGlobalData[gStructIndex].paramPos = paramPos; + s_ocwareGlobalData[gStructIndex].data = malloc(sizeof(char)* + s_ocwareGlobalData[gStructIndex].paramSize); + if (s_ocwareGlobalData[gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[gStructIndex].data, 0, + s_ocwareGlobalData[gStructIndex].paramSize); + } + ocware_stub_fill_init_value(param, gStructIndex); + paramPos += s_ocwareGlobalData[gStructIndex].paramSize; + gStructIndex++; + param += 1; + count = count + 1; + } + count = 0; + paramPos = 0; + param = devDriver->status; + /* Status related parameters */ + while (param && param->name) { /* Parameter loop */ + if ((strncmp(subSystem->name, "obc", + strlen(subSystem->name)) == 0) || + (strncmp(subSystem->name, "testmodule", + strlen(subSystem->name)) == 0) || + (strncmp(subSystem->name, "system", + strlen(subSystem->name)) == 0)) { + if (strncmp(param->name, "mfg", + strlen(param->name))== 0) { + s_typeFlag = OCSTUB_VALUE_TYPE_MFG; + } else if (strncmp(param->name, + "model", strlen(param->name)) == 0) { + if ((strncmp(subSystem->name, "testmodule", + strlen(subSystem->name))) == 0) { + s_typeFlag = OCSTUB_VALUE_TYPE_GETMODEL; + } else { + s_typeFlag = OCSTUB_VALUE_TYPE_MODEL; + } + } else if (strncmp(param->name, + "registration", strlen(param->name)) == 0) { + s_typeFlag = OCSTUB_VALUE_TYPE_REGISTRATION; + } else if(strncmp(param->name, "network_operatorinfo", + strlen(param->name)) == 0) { + s_typeFlag = + OCSTUB_VALUE_TYPE_NWOP_STRUCT; + } else if(strncmp(param->name, "lasterror", + strlen(param->name)) == 0) { + s_typeFlag = + OCSTUB_VALUE_TYPE_LAST_ERROR; + } else if(strncmp(param->name, "ocserialinfo", + strlen(param->name)) == 0) { + s_typeFlag = + OCSTUB_VALUE_TYPE_OCSERIAL_INFO; + } else if(strncmp(param->name, "gbcboardinfo", + strlen(param->name)) == 0) { + s_typeFlag = + OCSTUB_VALUE_TYPE_GBCBOARD_INFO; + } else { + } + } + s_ocwareGlobalData[gStructIndex].subsystemId = subsystemNbr; + s_ocwareGlobalData[gStructIndex].componentId = componentNbr; + s_ocwareGlobalData[gStructIndex].paramId = pow(2,count); + s_ocwareGlobalData[gStructIndex].paramSize = + ocware_stub_get_paramSize ( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_STATUS, param->name); + s_ocwareGlobalData[gStructIndex].paramPos = paramPos; + s_ocwareGlobalData[gStructIndex].msgtype = + OCMP_MSG_TYPE_STATUS; + paramPos += s_ocwareGlobalData[gStructIndex].paramSize; + s_ocwareGlobalData[gStructIndex].data = malloc(sizeof(char)* + s_ocwareGlobalData[gStructIndex].paramSize); + if (s_ocwareGlobalData[gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[gStructIndex].data, 0, + s_ocwareGlobalData[gStructIndex].paramSize); + } + ocware_stub_fill_init_value(param, gStructIndex); + if ((strncmp(subSystem->name, "obc", + strlen(subSystem->name)) == 0) || + (strncmp(subSystem->name, "testmodule", + strlen(subSystem->name)) == 0)) { + s_ocwareGlobalData[gStructIndex].paramPos = 0; + } + gStructIndex++; + param += 1; + count = count + 1; + } + } + /* If subcomponents exist */ + configCount = 0; + configParamPos = 0; + statusCount = 0; + statusParamPos = 0; + subComponent = component->components; + + while (subComponent && subComponent->name) { + devDriver = subComponent->driver; + if(devDriver == NULL) { + subComponent += 1; + continue; + } + param = devDriver->config; + /* Config related parameters */ + while (param && param->name) { /*Parameter loop */ + s_ocwareGlobalData[gStructIndex].subsystemId = subsystemNbr; + s_ocwareGlobalData[gStructIndex].componentId = componentNbr; + s_ocwareGlobalData[gStructIndex].paramId + = pow(2,configCount); + s_ocwareGlobalData[gStructIndex].paramSize + = ocware_stub_get_paramSize ( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_CONFIG, param->name); + s_ocwareGlobalData[gStructIndex].msgtype = + OCMP_MSG_TYPE_CONFIG; + s_ocwareGlobalData[gStructIndex].paramPos = configParamPos; + configParamPos += s_ocwareGlobalData[gStructIndex].paramSize; + s_ocwareGlobalData[gStructIndex].data + = malloc(s_ocwareGlobalData[gStructIndex].paramSize); + if (s_ocwareGlobalData[gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[gStructIndex].data, 0, + s_ocwareGlobalData[gStructIndex].paramSize); + } + ocware_stub_fill_init_value(param, gStructIndex); + gStructIndex++; + param += 1; + configCount += 1; + } + param = devDriver->status; + /* Status related parameters */ + while (param && param->name) { /* Parameter loop */ + s_ocwareGlobalData[gStructIndex].subsystemId = subsystemNbr; + s_ocwareGlobalData[gStructIndex].componentId = componentNbr; + s_ocwareGlobalData[gStructIndex].paramId + = pow(2,statusCount); + s_ocwareGlobalData[gStructIndex].paramSize + = ocware_stub_get_paramSize ( + DATA_TYPE_MAP[param->type], + OCMP_MSG_TYPE_STATUS, param->name); + s_ocwareGlobalData[gStructIndex].paramPos = statusParamPos; + s_ocwareGlobalData[gStructIndex].msgtype = + OCMP_MSG_TYPE_STATUS; + statusParamPos += s_ocwareGlobalData[gStructIndex].paramSize; + s_ocwareGlobalData[gStructIndex].data + = malloc(s_ocwareGlobalData[gStructIndex].paramSize); + if (s_ocwareGlobalData[gStructIndex].data == NULL) { + printf("Malloc failed\n"); + return STUB_FAILED; + } else { + memset(s_ocwareGlobalData[gStructIndex].data, 0, + s_ocwareGlobalData[gStructIndex].paramSize); + } + ocware_stub_fill_init_value(param, gStructIndex); + gStructIndex++; + param += 1; + statusCount += 1; + } + subComponent += 1; + } + componentNbr++; + } + subsystemNbr++; + } + ret = ocware_stub_create_post_database(); + return ret; +} + +/****************************************************************************** + * Function Name : ocware_stub_parse_command_message + * Description : Parse command messages from MW + * + * @param buffer - output pointer to the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_parse_command_message(char *buffer) +{ + OCMPMessageFrame *msgFrame = (OCMPMessageFrame *)buffer; + OCMPMessage *msgFrameData = (OCMPMessage*)&msgFrame->message; + ocware_stub_ret ret = STUB_FAILED; + + if (buffer == NULL) { + return ret; + } + + /* + * The current logic is to return success for all commands other than + * the debug subsystem. For debug subsytem the commands are treated + * similar to the get/set logic used in config msg type + */ + ret = STUB_SUCCESS; + if(s_debugSubsystem == msgFrameData->subsystem) { + ocware_stub_parse_debug_actiontype(msgFrameData); + ret = ocware_stub_get_set_params(msgFrameData); + } + msgFrameData->action = OCMP_AXN_TYPE_REPLY; + return ret; +} diff --git a/firmware/host/ocwarestub/ocware_stub_eth_comm.c b/firmware/host/ocwarestub/ocware_stub_eth_comm.c new file mode 100755 index 0000000000..5ea8f5f95a --- /dev/null +++ b/firmware/host/ocwarestub/ocware_stub_eth_comm.c @@ -0,0 +1,135 @@ +#include +#include + +static int32_t s_stubSockFd; +static struct sockaddr_in s_ocmwStubServer; +/****************************************************************************** + * Function Name : ocware_stub_init_ethernet_comm + * Description : initialise the socket IPC + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_init_ethernet_comm(void) +{ + int32_t rc = 0; + int32_t inet_atom = 0; + + /* Create socket */ + s_stubSockFd = socket(OCMW_STUB_ETH_SOCK_DOMAIN, + OCMW_STUB_ETH_SOCK_TYPE, OCMW_STUB_ETH_SOCK_PROTOCOL); + if (s_stubSockFd < 0) { + printf("socket creation error [%d-%s]", errno, strerror(errno)); + return STUB_FAILED; + } + + /* Initialize socket structure */ + memset(&s_ocmwStubServer, 0, sizeof(s_ocmwStubServer)); + s_ocmwStubServer.sin_family = OCMW_STUB_ETH_SOCK_DOMAIN; + s_ocmwStubServer.sin_port = htons(OCMW_STUB_ETH_SOCK_SERVER_PORT); + s_ocmwStubServer.sin_addr.s_addr = inet_addr(OCMW_STUB_ETH_SOCK_SERVER_IP); + inet_atom = inet_aton(OCMW_STUB_ETH_SOCK_SERVER_IP, + &s_ocmwStubServer.sin_addr); + if (inet_atom == 0) { + printf("inet_aton failed"); + return STUB_FAILED; + } + memset(s_ocmwStubServer.sin_zero, '\0', sizeof(s_ocmwStubServer.sin_zero)); + + /*Bind socket with address struct*/ + rc = bind(s_stubSockFd, (struct sockaddr *) &s_ocmwStubServer, + sizeof(s_ocmwStubServer)); + if (rc != 0) { + ocware_stub_deinit_ethernet_comm(); + printf("Ehernet init failed \n"); + return STUB_FAILED; + } + + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : ocware_stub_deinit_ethernet_comm + * Description : close the IPC socket + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_deinit_ethernet_comm() +{ + close(s_stubSockFd); + s_stubSockFd = 0; /* Close the IPC socket */ + + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : ocware_stub_send_msgframe_middleware + * Description : send message to the MW + * + * @param bufferlen - length of the message (by value) + * @param buffer - pointer to the message to be sent to MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_send_msgframe_middleware(char **buffer, + int32_t bufferlen) +{ + int32_t rc = 0; + const int32_t errstr_len = OCWARE_STUB_ERR_STR_LEN; + char errstr[errstr_len]; + int8_t data[OC_EC_MSG_SIZE] = { 0 }; + int32_t dataLen = sizeof(s_ocmwStubServer); + + if (buffer == NULL) { + return STUB_FAILED; + } + + memcpy(data, *buffer, sizeof(data)); + + rc = sendto(s_stubSockFd, data, OC_EC_MSG_SIZE, 0, + (struct sockaddr *) &s_ocmwStubServer, + dataLen); + if (rc < 0) { + strerror_r(errno, errstr, errstr_len); + printf("Error: 'send' [%d-%s]", errno, errstr); + return STUB_FAILED; + } + + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : ocware_stub_recv_msgfrom_middleware + * Description : Receive message from MW + * + * @param bufferlen - length of the message (by value) + * @param buffer - pointer to the location where the message from MW is to be + * stored for further processing (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_recv_msgfrom_middleware( + char **buffer, int32_t bufferlen) +{ + int32_t rc = 0; + const int32_t errstr_len = OCWARE_STUB_ERR_STR_LEN; + char errstr[errstr_len]; + int8_t data[OC_EC_MSG_SIZE] = { 0 }; + int32_t dataLen = sizeof(s_ocmwStubServer); + + if (buffer == NULL) { + return STUB_FAILED; + } + /* Receive the CLI command execution response string from OCMW over UDP socket */ + rc = recvfrom(s_stubSockFd, data, OC_EC_MSG_SIZE, + 0, (struct sockaddr *) &s_ocmwStubServer, + (socklen_t*)&dataLen); + if (rc < 0) { + strerror_r(rc, errstr, errstr_len); + logerr("Error: 'recv' [%d-%s]", rc, errstr); + return STUB_FAILED; + } + + memcpy(*buffer, data, sizeof(data)); + return STUB_SUCCESS; +} diff --git a/firmware/host/ocwarestub/ocware_stub_main_module.c b/firmware/host/ocwarestub/ocware_stub_main_module.c new file mode 100755 index 0000000000..bed773035d --- /dev/null +++ b/firmware/host/ocwarestub/ocware_stub_main_module.c @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include + +/****************************************************************************** + * Function Name : ocware_stub_frame_newmsgframe + * Description : Frame the response packet from stub function + * + * @param buf - pointer to complete message from MW (by reference) + * @param option - success or failure (by value) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_frame_newmsgframe(char *buffer, int32_t option) +{ + int32_t ret = 0, index = 0; + OCMPMessageFrame *msgFrame = (OCMPMessageFrame *)buffer; + OCMPMessage *msgFrameData = (OCMPMessage*)&msgFrame->message; + + /* Frame the header packet for sending data to ec */ + msgFrame->header.ocmpFrameLen = 0; + msgFrame->header.ocmpInterface = OCMP_COMM_IFACE_ETHERNET; + msgFrame->header.ocmpSeqNumber = 0; + msgFrame->header.ocmpSof = OCMP_MSG_SOF; + msgFrame->header.ocmpTimestamp = 0; + + switch(msgFrameData->msgtype) { + + case OCMP_MSG_TYPE_COMMAND: + ret = ocware_stub_parse_command_message(buffer); + break; + + case OCMP_MSG_TYPE_POST: + ret = ocware_stub_parse_post_get_message(buffer); + break; + + default: + ret = ocware_stub_get_set_params(msgFrameData); + } + + if (ret == STUB_SUCCESS) { + /* Setting the action type as REPLY */ + msgFrame->message.action = OCMP_AXN_TYPE_REPLY; + printf(" \n Sending Data :\n"); + for (index = 0; index < OC_EC_MSG_SIZE; index++) { + printf("0x%x ", buffer[index] & 0xff); + } + } + return ret; +} +/****************************************************************************** + * Function Name : ocware_stub_validate_msgframe_header + * Description : validate the msgframe header + * + * @param buf - pointer to complete message from MW (by reference) + * @param msgFrameData - pointer to ocmpgeader field of the message from + * MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_validate_msgframe_header(char *buf, + OCMPMessage *msgFrameData) +{ + OCMPMessageFrame *MsgFrame = (OCMPMessageFrame *)buf; + OCMPHeader *header = (OCMPHeader *)&MsgFrame->header; + + if (header->ocmpFrameLen == 0) { + if (header->ocmpSeqNumber == 0) { + if (header->ocmpSof == OCMP_MSG_SOF) { + if (header->ocmpTimestamp == 0) { + memcpy(msgFrameData, &MsgFrame->message, + sizeof(OCMPMessage)); + return STUB_SUCCESS; + } + } + } + } + return STUB_FAILED; +} +/****************************************************************************** + * Function Name : host_ocstubmain_func + * Description : Handle all the functionality for stub + * + * @param argc - number of argunents passed (by value) + * @param argv - arguments passed when invoking stub (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +int32_t host_ocstubmain_func(int32_t argc, char *argv[]) +{ + int32_t rc = 0; + char *buffer = NULL; + int32_t loopCount = 0; + char *rootpath = NULL; + + OCMPMessageFrame *msgFrame = NULL; + rc = ocware_stub_init_ethernet_comm(); + if ( rc != STUB_SUCCESS) { + printf("\n ERROR: Init Failed - %d", __LINE__); + ocware_stub_deinit_ethernet_comm(); + return STUB_FAILED; + } + + msgFrame = (OCMPMessageFrame *) malloc(sizeof(OCMPMessageFrame)); + if (msgFrame == NULL) { + printf("\n ERROR: malloc"); + ocware_stub_deinit_ethernet_comm(); + return STUB_FAILED; + } + + buffer = (char *) malloc(OC_EC_MSG_SIZE); + if (buffer == NULL) { + printf("\n ERROR: malloc"); + ocware_stub_deinit_ethernet_comm(); + return STUB_FAILED; + } + + rootpath = (char *)malloc(100); + if (rootpath == NULL) { + printf("\n ERROR: malloc"); + ocware_stub_deinit_ethernet_comm(); + return STUB_FAILED; + } + + ocware_stub_init_database(); + + printf("\n\n OCWARE STUB APllication Started...\n"); + + while (1) { + + memset(buffer, 0, sizeof(OCMPMessageFrame)); + rc = ocware_stub_recv_msgfrom_middleware(&buffer, + sizeof(OCMPMessageFrame)); + if (rc != STUB_SUCCESS) { + printf("ocware_stub_recv_msgfrom_middleware failed: error value :" + " %d\n", rc); + return STUB_FAILED; + } + +//#ifndef OCWARE_STUB_DEBUG + printf(" \n Received Data :\n"); + for (loopCount = 0; loopCount < OC_EC_MSG_SIZE; loopCount++) { + printf("0x%x ", buffer[loopCount] & 0xff); + } +//#endif + rc = ocware_stub_validate_msgframe_header(buffer, &msgFrame->message); + if (rc != STUB_SUCCESS) { + printf("ocware_stub_validate_msgframe_header failed: error value :" + "%d\n", rc); + return STUB_FAILED; + } + rc = ocware_stub_frame_newmsgframe(buffer, rc); + if (rc != STUB_SUCCESS) { + printf("ocware_stub_frame_newmsgframe failed: error value :" + "%d\n", rc); + return STUB_FAILED; + } + + rc = ocware_stub_send_msgframe_middleware(&buffer, + sizeof(OCMPMessageFrame)); + if (rc != STUB_SUCCESS) { + printf("ocware_stub_send_msgframe_middleware failed: error value :" + "%d\n", rc); + return STUB_FAILED; + } + } + free(msgFrame); + free(buffer); + return STUB_SUCCESS; +} +/****************************************************************************** + * Function Name : main + * Description : start the stub process + * + * @param argc - number of argunents passed (by value) + * @param argv - arguments passed when invoking stub (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +#ifndef OCWARE_UNITY_TEST +int32_t main(int32_t argc, char *argv[]) +{ + int32_t ret = 0; + ret = host_ocstubmain_func(argc, argv); + return ret; +} +#else +int32_t host_ocwaremain(int32_t argc, char *argv[]) +{ + int32_t ret = 0; + ret = host_ocstubmain_func(argc, argv); + return ret; +} +#endif diff --git a/firmware/host/ocwarestub/ocware_stub_parse_message.c b/firmware/host/ocwarestub/ocware_stub_parse_message.c new file mode 100755 index 0000000000..c2efd0a3f9 --- /dev/null +++ b/firmware/host/ocwarestub/ocware_stub_parse_message.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include +#include + +/****************************************************************************** + * Function Name : ocware_stub_parse_debug_actiontype + * Description : Convert debug actiontype into the SET/GET + * + * @param msgFrameData - output pointer to the OCMPheader field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + *******************************************************************************/ +ocware_stub_ret ocware_stub_parse_debug_actiontype(OCMPMessage *msgFrameData) +{ + ocware_stub_ret ret = STUB_SUCCESS; + + if ((debugSetCommand != STUB_FAILED) || + (debugGetCommand != STUB_FAILED)) { + + if ((msgFrameData->action) == debugGetCommand) { + msgFrameData->action = OCMP_AXN_TYPE_GET; + } else if ((msgFrameData->action) == debugSetCommand) { + msgFrameData->action = OCMP_AXN_TYPE_SET; + } else { + ret = STUB_FAILED; + } + } else { + ret = STUB_FAILED; + } + return ret; +} + +/****************************************************************************** + * Function Name : ocware_stub_handle_post_enable + * Description : Process the post enable message + * + * @param msgFrameData - output pointer to the OCMPheader field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_handle_post_enable(OCMPMessage *msgFrameData) +{ + return STUB_SUCCESS; +} + +/****************************************************************************** + * Function Name : ocware_stub_get_set_params + * Description : Function to check if GET/SET operation is to be performed + * + * @param msgFrameData - Pointer to the message frame field of the message + * from MW (by reference) + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_get_set_params(OCMPMessage *msgFrameData) +{ + ocware_stub_ret ret = STUB_FAILED; + + if (msgFrameData == NULL) { + return ret; + } + + switch (msgFrameData->action) { + case OCMP_AXN_TYPE_GET: + ret = ocware_stub_get_database(msgFrameData); + break; + + case OCMP_AXN_TYPE_SET: + ret = ocware_stub_set_database(msgFrameData); + break; + + default: + ret = STUB_FAILED; + } + return ret; + +} +/****************************************************************************** + * Function Name : ocware_stub_parse_post_get_message + * Description : Parse post messages from MW + * + * @param buffer - output pointer to the message from MW + * + * @return STUB_SUCCESS - for success + * STUB_FAILED - for failure + ******************************************************************************/ +ocware_stub_ret ocware_stub_parse_post_get_message(char *buffer) +{ + ocware_stub_ret ret = STUB_FAILED; + OCMPMessageFrame *msgFrame = NULL; + OCMPMessage *msgFrameData = NULL; + uint16_t paramId; + char *payload = NULL; + + if(buffer == NULL) { + return ret; + } + msgFrame = (OCMPMessageFrame *)buffer; + msgFrameData = (OCMPMessage*)&msgFrame->message; + payload = (char *)&msgFrameData->info; + msgFrameData->action = OCMP_AXN_TYPE_REPLY; + paramId = msgFrameData->parameters; + + if(paramId == PostResult) { + ret = ocware_stub_get_post_database(msgFrameData, payload); + } else if (paramId == PostEnable) { + ret = ocware_stub_handle_post_enable(msgFrameData); + } + return ret; +} diff --git a/firmware/host/ocwarestub/test_all_stub.sh b/firmware/host/ocwarestub/test_all_stub.sh new file mode 100755 index 0000000000..810f86fcff --- /dev/null +++ b/firmware/host/ocwarestub/test_all_stub.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +echo "##############################" +echo " GET CONFIG PARAMS - 1 " +echo "##############################" +./get_params_stub.sh bms config +./get_params_stub.sh gpp config +./get_params_stub.sh sdr config +./get_params_stub.sh rf config +./get_params_stub.sh power config +./get_params_stub.sh ethernet config +./get_params_stub.sh sync config + +echo "##############################" +echo " SET CONFIG PARAMS " +echo "##############################" +../scripts/set_config_params.sh bms +../scripts/set_config_params.sh gpp +../scripts/set_config_params.sh sdr +../scripts/set_config_params.sh rf +../scripts/set_config_params.sh power +../scripts/set_config_params.sh ethernet +../scripts/set_config_params.sh sync + +echo "##############################" +echo " GET CONFIG PARAMS - 2 " +echo "##############################" +./get_params_stub.sh bms config +./get_params_stub.sh gpp config +./get_params_stub.sh sdr config +./get_params_stub.sh rf config +./get_params_stub.sh power config +./get_params_stub.sh ethernet config +./get_params_stub.sh sync config + +echo "##############################" +echo " GET STATUS PARAMS " +echo "##############################" +./get_params_stub.sh bms status +./get_params_stub.sh gpp status +./get_params_stub.sh sdr status +./get_params_stub.sh rf status +./get_params_stub.sh power status +./get_params_stub.sh ethernet status +./get_params_stub.sh sync status +./get_params_stub.sh testmodule status +./get_params_stub.sh obc status +./get_params_stub.sh hci status +./get_params_stub.sh system status + +echo "##############################" +echo " GET DEBUG COMMANDS - 1 " +echo "##############################" +./get_params_stub.sh debug I2C +./get_params_stub.sh debug GPIO +./get_params_stub.sh debug MDIO + + +echo "##############################" +echo " SET DEBUG COMMANDS " +echo "##############################" +../scripts/set_config_params.sh debug I2C +../scripts/set_config_params.sh debug GPIO +../scripts/set_config_params.sh debug MDIO + + +echo "##############################" +echo " GET DEBUG COMMANDS - 2 " +echo "##############################" +./get_params_stub.sh debug I2C +./get_params_stub.sh debug GPIO +./get_params_stub.sh debug MDIO +echo " >>> TESTING DONE <<< " diff --git a/firmware/host/ocwdg/ocwdg_daemon.c b/firmware/host/ocwdg/ocwdg_daemon.c new file mode 100644 index 0000000000..21a256d237 --- /dev/null +++ b/firmware/host/ocwdg/ocwdg_daemon.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* OC includes */ +#include +#include + +#define OCWDG_NUMBER_ZERO 0 +#define OCWDG_NUMBER_ONE 1 + +extern int32_t ocmw_sem_wait_nointr(sem_t *sem); + +/****************************************************************************** + * Function Name : ocwdg_init + * Description : This Function used to initialize the watchdog semaphore + * and thread. + * Input(s) : + * Output(s) : + ******************************************************************************/ +int32_t ocwdg_init(void) +{ + pthread_t ocWdgThreadid; + int32_t ret = OCWDG_NUMBER_ZERO; + + printf("inside ocwdg_init() \n"); + ret = sem_init(&semEcWdgMsg, OCWDG_NUMBER_ZERO, OCWDG_NUMBER_ZERO); + if (ret != OCWDG_NUMBER_ZERO) { + return ret; + } else { + /* Create the msg parser thread to parse + * the msg coming from UART ec to ap + */ + ret = pthread_create(&ocWdgThreadid, NULL, ocwdg_thread_comm_with_ec, + NULL); + if (ret != OCWDG_NUMBER_ZERO) { + return ret; + } + } + return ret; +} + +/****************************************************************************** + * Function Name : ocwdg_thread_comm_with_ec + * Description : Thread to send watchdog response to ec + * through uart or ethernet communication + * Input(s) : pthreadData + * Output(s) : + ******************************************************************************/ +void * ocwdg_thread_comm_with_ec(void *pthreadData) +{ + OCMPMessageFrame ecMsgFrame; + OCMPHeader ecMsgHeader; + OCMPMessage ecCoreMsg; + int32_t ret = OCWDG_NUMBER_ZERO; + + while (OCWDG_NUMBER_ONE) { + /* Waiting on the semEcWdgMsg to be released by + * msg receiving thread from ec + */ + ret = ocmw_sem_wait_nointr(&semEcWdgMsg); + if (ret != OCWDG_NUMBER_ZERO) { + perror("ocwdg_thread_comm_with_ec: ocmw_sem_wait_nointr"); + continue; + } + + /* Frame the header packet for sending data to ec */ + ecMsgHeader.ocmpFrameLen = OCWDG_NUMBER_ZERO; +#ifdef INTERFACE_ETHERNET + ecMsgHeader.ocmpInterface = OCMP_COMM_IFACE_ETHERNET; +#else + ecMsgHeader.ocmpInterface = OCMP_COMM_IFACE_UART; +#endif /* INTERFACE_ETHERNET */ + ecMsgHeader.ocmpSeqNumber = OCWDG_NUMBER_ZERO; + ecMsgHeader.ocmpSof = OCMP_MSG_SOF; + ecMsgHeader.ocmpTimestamp = OCWDG_NUMBER_ZERO; + + /* Frame the Core packet for sending data to ec */ + /*ecCoreMsg.action = OCMP_AXN_TYPE_REPLY; + ecCoreMsg.msgtype = WATCHDOG; + ecCoreMsg.componentID = WD; + ecCoreMsg.parameters = OCWDG_NUMBER_ZERO; + ecCoreMsg.subsystem = WD; +*/ + /* Construct the final packet */ + ecMsgFrame.header = ecMsgHeader; + ecMsgFrame.message = ecCoreMsg; + + /* Populate the Core packet payload */ + ecMsgFrame.message.info = (int8_t *) malloc( + sizeof(char) * MAX_PARM_COUNT); + if (ecMsgFrame.message.info == NULL) { + printf("\n Memory allocation failed \n"); + } + memset(ecMsgFrame.message.info, OCWDG_NUMBER_ZERO, MAX_PARM_COUNT); + +#ifdef INTERFACE_ETHERNET + /* Send the packetize data to ec through ethernet*/ + ret = ocmw_send_eth_msgto_ec((int8_t *)&ecMsgFrame, (int32_t)32, + OCMW_EC_DEV); + if (ret != OCWDG_NUMBER_ZERO) { + logerr ("ocmw_send_eth_msgto_ec() failed"); + } + +#else + /* Send the packetize data to ec through uart*/ + ret = ocmw_send_uart_msg_to_ec((uint8_t *) &ecMsgFrame, + sizeof(ecMsgFrame)); + if (ret != OCWDG_NUMBER_ZERO) { + logerr("ocmw_send_uart_msg_to_ec() failed"); + } + +#endif /* INTERFACE_ETHERNET */ + printf("Watchdog reply message sent to ec \n"); + } +} diff --git a/firmware/host/ocwdg/ocwdg_daemon.conf b/firmware/host/ocwdg/ocwdg_daemon.conf new file mode 100644 index 0000000000..ebd3da86c2 --- /dev/null +++ b/firmware/host/ocwdg/ocwdg_daemon.conf @@ -0,0 +1,20 @@ +#This config is used to start the watchdog-daemon at boot time and if daemon got +#killed anyway. This file should be put in /etc/init folder after that +# run the command sudo service ocwdg_daemon restart +# Command used to check the syntax of config script : init-checkconf /etc/init/ocwdg_daemon.conf + +description "Watchdog Daemon" + +start on filesystem or runlevel [2345] +stop on runlevel [06] + + +#Replace the path with the location of watchdog-daemon +exec /home/oc/Desktop/Fb_code/ocmw --daemon + +# Restart the process if it dies with a signal +# or exit code not given by the 'normal exit' stanza. +respawn + +# Give up if restart occurs 10 times in 90 seconds. +respawn limit 10 90 diff --git a/firmware/host/scripts/autoTest/oc_pmic_i2c0_read.sh b/firmware/host/scripts/autoTest/oc_pmic_i2c0_read.sh new file mode 100755 index 0000000000..eb8569df49 --- /dev/null +++ b/firmware/host/scripts/autoTest/oc_pmic_i2c0_read.sh @@ -0,0 +1,29 @@ +modprobe i2c-i801 +#i2cdetect -l +#i2cdetect -r -y 9 +#i2cdetect -r -y 0 + +#Valid only for ubuntu-14.04.4 : Kernel-> 4.2.0-42 +bus=`i2cdetect -l | awk -F ' |-|\t' '/DesignWare/ {print $2}' | head -1` + +i2cdetect -r -y $bus + + + +# Read ‘Chip revision register’ from PMIC (0x5E) on i2c-0 +# Sleep for a second + +#PMIC(0X5E) o/p- chip revision: 0x05 +x=1 +while [ $x -le 100 ] +do + + +#i2cget -f -y 0 0x5e 0x01 b + +i2cget -f -y $bus 0x5e 0x01 b +echo "Reading Chip revision register’ from PMIC (0x5E) on i2c-0 and sleeping for 1 sec" + +sleep 1 + x=$(( $x + 1 )) +done diff --git a/firmware/host/scripts/autoTest/oc_pmic_tsensor_read.sh b/firmware/host/scripts/autoTest/oc_pmic_tsensor_read.sh new file mode 100755 index 0000000000..68445c2500 --- /dev/null +++ b/firmware/host/scripts/autoTest/oc_pmic_tsensor_read.sh @@ -0,0 +1,18 @@ +modprobe i2c-i801 +i2cdetect -l + + +x=1 +while [ $x -le 10 ] +do + +#Temperature sensor(0X4C) : o/p-> ( Device id: 0x3d : 0x81) (manufacture id: 0x3e : 0x41) + +i2cdetect -y 9 + +echo "Checking presence of ADT7481 temperature sensor and DDR3 DIMM-0 SPD memory" + +sleep 1 + + x=$(( $x + 1 )) +done diff --git a/firmware/host/scripts/autoTest/oc_smb_ddr3_read.sh b/firmware/host/scripts/autoTest/oc_smb_ddr3_read.sh new file mode 100755 index 0000000000..4b4260573f --- /dev/null +++ b/firmware/host/scripts/autoTest/oc_smb_ddr3_read.sh @@ -0,0 +1,27 @@ +modprobe i2c-i801 +i2cdetect -l +i2cdetect -r -y 9 +#i2cdetect -r -y 0 + + + +x=1 +while [ $x -le 100 ] +do + +#Read device register address from 128 to 145 from device DDR3 SPD (0x50) on i2c-9 + +y=128 + +while [ $y -le 145 ] +do +i2cget -f -y 9 0x50 $y b +y=$(( $y + 1 )) +done + +echo "Reading device register address from 128 to 145 from device DDR3 SPD (0x50) on i2c-9 and sleeping for 1 sec " + +sleep 1 + + x=$(( $x + 1 )) +done diff --git a/firmware/host/scripts/autoTest/oc_smb_tsensor_read.sh b/firmware/host/scripts/autoTest/oc_smb_tsensor_read.sh new file mode 100755 index 0000000000..c3537c07f0 --- /dev/null +++ b/firmware/host/scripts/autoTest/oc_smb_tsensor_read.sh @@ -0,0 +1,25 @@ +modprobe i2c-i801 +i2cdetect -l +i2cdetect -r -y 9 +#i2cdetect -r -y 0 + + +x=1 +while [ $x -le 100 ] +do + +#Temperature sensor(0X4C) : o/p-> ( Device id: 0x3d : 0x81) (manufacture id: 0x3e : 0x41) + +i2cget -f -y 9 0x1f 0x3d b + +echo "Reading -> Device id: 0x3d : 0x81 from temperature sensor and sleeping for 1 sec" + +sleep 1 + +i2cget -f -y 9 0x1f 0x3e b + +echo "Reading -> Manufacture id: 0x3e : 0x41 from temperature sensor and sleeping for 1 sec" + +sleep 1 + x=$(( $x + 1 )) +done diff --git a/firmware/host/scripts/get_params.sh b/firmware/host/scripts/get_params.sh new file mode 100755 index 0000000000..d50fd75410 --- /dev/null +++ b/firmware/host/scripts/get_params.sh @@ -0,0 +1,849 @@ +#!/bin/bash + +bmsParam=("bms.ec.config.temp_sensor1.lowlimit.get" + "bms.ec.config.temp_sensor1.highlimit.get" + "bms.ec.config.temp_sensor1.critlimit.get" + "bms.ec.config.current_sensor1.currlimit.get" + "bms.ec.config.current_sensor2.currlimit.get") + +defaultBms=("bms.ec.config.temp_sensor1.lowlimit.get=-20" + "bms.ec.config.temp_sensor1.highlimit.get=75" + "bms.ec.config.temp_sensor1.critlimit.get=80" + "bms.ec.config.current_sensor1.currlimit.get=1000" + "bms.ec.config.current_sensor2.currlimit.get=1000") + +setBmsVal=("bms.ec.config.temp_sensor1.lowlimit.get=-19" + "bms.ec.config.temp_sensor1.highlimit.get=76" + "bms.ec.config.temp_sensor1.critlimit.get=85" + "bms.ec.config.current_sensor1.currlimit.get=1498" + "bms.ec.config.current_sensor2.currlimit.get=1498") + +bmsStatusParam=("bms.ec.status.temp_sensor1.temperature.get" + "bms.ec.status.current_sensor1.busvoltage.get" + "bms.ec.status.current_sensor1.shuntvoltage.get" + "bms.ec.status.current_sensor1.current.get" + "bms.ec.status.current_sensor1.power.get" + "bms.ec.status.current_sensor2.busvoltage.get" + "bms.ec.status.current_sensor2.shuntvoltage.get" + "bms.ec.status.current_sensor2.current.get" + "bms.ec.status.current_sensor2.power.get") + +bmsStatusMinVal=(-20 11400 250 100 1100 2970 800 400 1200) + +bmsStatusMaxVal=(75 12600 1400 600 7500 3630 2000 800 2900) + +gppParam=("gpp.ap.config.temp_sensor1.lowlimit.get" + "gpp.ap.config.temp_sensor1.highlimit.get" + "gpp.ap.config.temp_sensor1.critlimit.get" + "gpp.ap.config.temp_sensor2.lowlimit.get" + "gpp.ap.config.temp_sensor2.highlimit.get" + "gpp.ap.config.temp_sensor2.critlimit.get" + "gpp.ap.config.temp_sensor3.lowlimit.get" + "gpp.ap.config.temp_sensor3.highlimit.get" + "gpp.ap.config.temp_sensor3.critlimit.get" + "gpp.ap.config.current_sensor1.currlimit.get" + "gpp.msata.config.current_sensor1.currlimit.get") + +defaultGpp=("gpp.ap.config.temp_sensor1.lowlimit.get=-20" + "gpp.ap.config.temp_sensor1.highlimit.get=75" + "gpp.ap.config.temp_sensor1.critlimit.get=80" + "gpp.ap.config.temp_sensor2.lowlimit.get=-20" + "gpp.ap.config.temp_sensor2.highlimit.get=75" + "gpp.ap.config.temp_sensor2.critlimit.get=80" + "gpp.ap.config.temp_sensor3.lowlimit.get=-20" + "gpp.ap.config.temp_sensor3.highlimit.get=75" + "gpp.ap.config.temp_sensor3.critlimit.get=80" + "gpp.ap.config.current_sensor1.currlimit.get=1498" + "gpp.msata.config.current_sensor1.currlimit.get=1498") + +setGppVal=("gpp.ap.config.temp_sensor1.lowlimit.get=-19" + "gpp.ap.config.temp_sensor1.highlimit.get=81" + "gpp.ap.config.temp_sensor1.critlimit.get=86" + "gpp.ap.config.temp_sensor2.lowlimit.get=-19" + "gpp.ap.config.temp_sensor2.highlimit.get=81" + "gpp.ap.config.temp_sensor2.critlimit.get=86" + "gpp.ap.config.temp_sensor3.lowlimit.get=-19" + "gpp.ap.config.temp_sensor3.highlimit.get=81" + "gpp.ap.config.temp_sensor3.critlimit.get=86" + "gpp.ap.config.current_sensor1.currlimit.get=2010" + "gpp.msata.config.current_sensor1.currlimit.get=2010") + + +gppStatusParam=("gpp.ap.status.temp_sensor1.temperature.get" + "gpp.ap.status.temp_sensor2.temperature.get" + "gpp.ap.status.temp_sensor3.temperature.get" + "gpp.ap.status.current_sensor1.busvoltage.get" + "gpp.ap.status.current_sensor1.shuntvoltage.get" + "gpp.ap.status.current_sensor1.current.get" + "gpp.ap.status.current_sensor1.power.get" + "gpp.msata.status.current_sensor1.busvoltage.get" + "gpp.msata.status.current_sensor1.shuntvoltage.get" + "gpp.msata.status.current_sensor1.current.get" + "gpp.msata.status.current_sensor1.power.get") + +gppStatusMinVal=(-20 -20 -20 11400 700 400 5000 3135 140 50 250) + +gppStatusMaxVal=(80 80 80 12600 1400 1200 8300 3465 500 300 800) + +hciParam=("hci.led.config.temp_sensor1.lowlimit.get" + "hci.led.config.temp_sensor1.highlimit.get" + "hci.led.config.temp_sensor1.critlimit.get") + +defaultHci=("hci.led.config.temp_sensor1.lowlimit.get=-20" + "hci.led.config.temp_sensor1.highlimit.get=80" + "hci.led.config.temp_sensor1.critlimit.get=85") + +setHciVal=("hci.led.config.temp_sensor1.lowlimit.get=-19" + "hci.led.config.temp_sensor1.highlimit.get=76" + "hci.led.config.temp_sensor1.critlimit.get=85") + +hciStatusParam=("hci.led.status.temp_sensor1.temperature.get") + +hciStatusMinVal=(-20) + +hciStatusMaxVal=(80) + +sdrParam=("sdr.comp_all.config.current_sensor1.currlimit.get" + "sdr.fpga.config.temp_sensor1.lowlimit.get" + "sdr.fpga.config.temp_sensor1.highlimit.get" + "sdr.fpga.config.temp_sensor1.critlimit.get" + "sdr.fpga.config.current_sensor1.currlimit.get") + +defaultSdr=("sdr.comp_all.config.current_sensor1.currlimit.get=2998" + "sdr.fpga.config.temp_sensor1.lowlimit.get=-20" + "sdr.fpga.config.temp_sensor1.highlimit.get=75" + "sdr.fpga.config.temp_sensor1.critlimit.get=85" + "sdr.fpga.config.current_sensor1.currlimit.get=500") + +setSdrVal=("sdr.comp_all.config.current_sensor1.currlimit.get=2010" + "sdr.fpga.config.temp_sensor1.lowlimit.get=-19" + "sdr.fpga.config.temp_sensor1.highlimit.get=76" + "sdr.fpga.config.temp_sensor1.critlimit.get=81" + "sdr.fpga.config.current_sensor1.currlimit.get=510") + +sdrStatusParam=("sdr.comp_all.status.current_sensor1.busvoltage.get" + "sdr.comp_all.status.current_sensor1.shuntvoltage.get" + "sdr.comp_all.status.current_sensor1.current.get" + "sdr.comp_all.status.current_sensor1.power.get" + "sdr.fpga.status.temp_sensor1.temperature.get" + "sdr.fpga.status.current_sensor1.busvoltage.get" + "sdr.fpga.status.current_sensor1.shuntvoltage.get" + "sdr.fpga.status.current_sensor1.current.get" + "sdr.fpga.status.current_sensor1.power.get") + +sdrStatusMinVal=(11400 2762 1381 15742 0 11400 60 30 342) + +sdrStatusMaxVal=(12600 4173 2087 26292 80 12600 240 120 1512) + +rfParam=("rffe.ch1_sensor.config.temp_sensor1.lowlimit.get" + "rffe.ch1_sensor.config.temp_sensor1.highlimit.get" + "rffe.ch1_sensor.config.temp_sensor1.critlimit.get" + "rffe.ch1_sensor.config.current_sensor1.currlimit.get" + "rffe.ch2_sensor.config.temp_sensor1.lowlimit.get" + "rffe.ch2_sensor.config.temp_sensor1.highlimit.get" + "rffe.ch2_sensor.config.temp_sensor1.critlimit.get" + "rffe.ch2_sensor.config.current_sensor1.currlimit.get" + "rffe.ch1_fe.config.ch1_band.band.get" + "rffe.ch1_fe.config.tx.atten.get" + "rffe.ch1_fe.config.rx.atten.get" + "rffe.ch2_fe.config.ch2_band.band.get" + "rffe.ch2_fe.config.tx.atten.get" + "rffe.ch2_fe.config.rx.atten.get") + +defaultRf=("rffe.ch1_sensor.config.temp_sensor1.lowlimit.get=-20" + "rffe.ch1_sensor.config.temp_sensor1.highlimit.get=80" + "rffe.ch1_sensor.config.temp_sensor1.critlimit.get=85" + "rffe.ch1_sensor.config.current_sensor1.currlimit.get=2000" + "rffe.ch2_sensor.config.temp_sensor1.lowlimit.get=-20" + "rffe.ch2_sensor.config.temp_sensor1.highlimit.get=80" + "rffe.ch2_sensor.config.temp_sensor1.critlimit.get=85" + "rffe.ch2_sensor.config.current_sensor1.currlimit.get=2000" + "rffe.ch1_fe.config.ch1_band.band.get=3" + "rffe.ch1_fe.config.tx.atten.get=63" + "rffe.ch1_fe.config.rx.atten.get=31" + "rffe.ch2_fe.config.ch2_band.band.get=3" + "rffe.ch2_fe.config.tx.atten.get=63" + "rffe.ch2_fe.config.rx.atten.get=31") + +setRfVal=("rffe.ch1_sensor.config.temp_sensor1.lowlimit.get=-19" + "rffe.ch1_sensor.config.temp_sensor1.highlimit.get=76" + "rffe.ch1_sensor.config.temp_sensor1.critlimit.get=81" + "rffe.ch1_sensor.config.current_sensor1.currlimiti.get=1467" + "rffe.ch2_sensor.config.temp_sensor1.lowlimit.get=-19" + "rffe.ch2_sensor.config.temp_sensor1.highlimit.get=76" + "rffe.ch2_sensor.config.temp_sensor1.critlimit.get=81" + "rffe.ch2_sensor.config.current_sensor1.currlimit.get=510" + "rffe.ch1_fe.config.ch1_band.band.get=3" + "rffe.ch1_fe.config.tx.atten.get=60" + "rffe.ch1_fe.config.rx.atten.get=20" + "rffe.ch2_fe.config.ch2_band.band.get=3" + "rffe.ch2_fe.config.tx.atten.get=60" + "rffe.ch2_fe.config.rx.atten.get=20") + +rfStatusParam=("rffe.ch1_sensor.status.temp_sensor1.temperature.get" + "rffe.ch1_sensor.status.current_sensor1.busvoltage.get" + "rffe.ch1_sensor.status.current_sensor1.shuntvoltage.get" + "rffe.ch1_sensor.status.current_sensor1.current.get" + "rffe.ch1_sensor.status.current_sensor1.power.get" + "rffe.ch2_sensor.status.temp_sensor1.temperature.get" + "rffe.ch2_sensor.status.current_sensor1.busvoltage.get" + "rffe.ch2_sensor.status.current_sensor1.shuntvoltage.get" + "rffe.ch2_sensor.status.current_sensor1.current.get" + "rffe.ch2_sensor.status.current_sensor1.power.get" + "rffe.ch1_fe.status.power.forward.get" + "rffe.ch1_fe.status.power.reverse.get" + "rffe.ch2_fe.status.power.forward.get" + "rffe.ch2_fe.status.power.reverse.get") + +rfStatusMinVal=(10 5500 2800 1400 7700 10 5500 2800 1400 7700 0 0 0 0) + +rfStatusMaxVal=(80 5900 4200 2100 12390 80 5900 4200 2100 12390 10 10 10 10) + +powerParam=("power.leadacid_sensor.config.temp_sensor1.lowlimit.get" + "power.leadacid_sensor.config.temp_sensor1.highlimit.get" + "power.leadacid_sensor.config.temp_sensor1.critlimit.get" + "power.leadacid.config.battery.batteryVoltageLow.get" + "power.leadacid.config.battery.batteryVoltageHigh.get" + "power.leadacid.config.battery.batteryCurrentLow.get" + "power.leadacid.config.battery.inputVoltageLow.get" + "power.leadacid.config.battery.inputCurrentHigh.get" + "power.leadacid.config.battery.inputCurrentLimit.get" + "power.lion.config.battery.batteryVoltageLow.get" + "power.lion.config.battery.batteryVoltageHigh.get" + "power.lion.config.battery.batteryCurrentLow.get" + "power.lion.config.battery.inputVoltageLow.get" + "power.lion.config.battery.inputCurrentHigh.get" + "power.lion.config.battery.inputCurrentLimit.get" + "power.pse.config.operatingMode.get" + "power.pse.config.detectEnable.get" + "power.pse.config.interruptMask.get" + "power.pse.config.interruptEnable.get" + "power.pse.config.enableHighpower.get") + +defaultPower=("power.leadacid_sensor.config.temp_sensor1.lowlimit.get=-20" + "power.leadacid_sensor.config.temp_sensor1.highlimit.get=75" + "power.leadacid_sensor.config.temp_sensor1.critlimit.get=80" + "power.leadacid.config.battery.batteryVoltageLow.get=12666" + "power.leadacid.config.battery.batteryVoltageHigh.get=16799" + "power.leadacid.config.battery.batteryCurrentLow.get=999" + "power.leadacid.config.battery.inputVoltageLow.get=16199" + "power.leadacid.config.battery.inputCurrentHigh.get=17499" + "power.leadacid.config.battery.inputCurrentLimit.get=16000" + "power.lion.config.battery.batteryVoltageLow.get=9499" + "power.lion.config.battery.batteryVoltageHigh.get=12599" + "power.lion.config.battery.batteryCurrentLow.get=99" + "power.lion.config.battery.inputVoltageLow.get=16199" + "power.lion.config.battery.inputCurrentHigh.get=4999" + "power.lion.config.battery.inputCurrentLimit.get=4571" + "power.pse.config.operatingMode.get=17" + "power.pse.config.detectEnable.get=17" + "power.pse.config.interruptMask.get=17" + "power.pse.config.interruptEnable.get=17" + "power.pse.config.enableHighpower.get=17") + +setPowerVal=("power.leadacid_sensor.config.temp_sensor1.lowlimit.get=-19" + "power.leadacid_sensor.config.temp_sensor1.highlimit.get=76" + "power.leadacid_sensor.config.temp_sensor1.critlimit.get=81" + "power.leadacid.config.battery.batteryVoltageLow.get=12499" + "power.leadacid.config.battery.batteryVoltageHigh.get=16499" + "power.leadacid.config.battery.batteryCurrentLow.get=899" + "power.leadacid.config.battery.inputVoltageLow.get=16209" + "power.leadacid.config.battery.inputCurrentHigh.get=17399" + "power.leadacid.config.battery.inputCurrentLimit.get=15000" + "power.lion.config.battery.batteryVoltageLow.get=9009" + "power.lion.config.battery.batteryVoltageHigh.get=12699" + "power.lion.config.battery.batteryCurrentLow.get=109" + "power.lion.config.battery.inputVoltageLow.get=16209" + "power.lion.config.battery.inputCurrentHigh.get=5009" + "power.lion.config.battery.inputCurrentLimit.get=3571" + "power.pse.config.operatingMode.get=3" + "power.pse.config.detectEnable.get=64" + "power.pse.config.interruptMask.get=195" + "power.pse.config.interruptEnable.get=128" + "power.pse.config.enableHighpower.get=17") + +ethParam=("ethernet.port0.config.speed.get" + "ethernet.port0.config.duplex.get" + "ethernet.port0.config.powerDown.get" + "ethernet.port0.config.enable_sleepMode.get" + "ethernet.port0.config.enable_interrupt.get" + "ethernet.port1.config.speed.get" + "ethernet.port1.config.duplex.get" + "ethernet.port1.config.powerDown.get" + "ethernet.port1.config.enable_sleepMode.get" + "ethernet.port1.config.enable_interrupt.get" + "ethernet.port2.config.speed.get" + "ethernet.port2.config.duplex.get" + "ethernet.port2.config.powerDown.get" + "ethernet.port2.config.enable_sleepMode.get" + "ethernet.port2.config.enable_interrupt.get" + "ethernet.port3.config.speed.get" + "ethernet.port3.config.duplex.get" + "ethernet.port3.config.powerDown.get" + "ethernet.port3.config.enable_sleepMode.get" + "ethernet.port3.config.enable_interrupt.get" + "ethernet.port4.config.speed.get" + "ethernet.port4.config.duplex.get" + "ethernet.port4.config.powerDown.get" + "ethernet.port4.config.enable_sleepMode.get" + "ethernet.port4.config.enable_interrupt.get") + +defaultEth=("ethernet.port0.config.speed.get=2" + "ethernet.port0.config.duplex.get=2" + "ethernet.port0.config.powerDown.get=0" + "ethernet.port0.config.enable_sleepMode.get=0" + "ethernet.port0.config.enable_interrupt.get=0" + "ethernet.port1.config.speed.get=2" + "ethernet.port1.config.duplex.get=2" + "ethernet.port1.config.powerDown.get=0" + "ethernet.port1.config.enable_sleepMode.get=0" + "ethernet.port1.config.enable_interrupt.get=0" + "ethernet.port2.config.speed.get=2" + "ethernet.port2.config.duplex.get=2" + "ethernet.port2.config.powerDown.get=0" + "ethernet.port2.config.enable_sleepMode.get=0" + "ethernet.port2.config.enable_interrupt.get=0" + "ethernet.port3.config.speed.get=2" + "ethernet.port3.config.duplex.get=2" + "ethernet.port3.config.powerDown.get=0" + "ethernet.port3.config.enable_sleepMode.get=0" + "ethernet.port3.config.enable_interrupt.get=0" + "ethernet.port4.config.speed.get=2" + "ethernet.port4.config.duplex.get=2" + "ethernet.port4.config.powerDown.get=0" + "ethernet.port4.config.enable_sleepMode.get=0" + "ethernet.port4.config.enable_interrupt.get=0") + +setEthVal=("ethernet.port0.config.speed.get=2" + "ethernet.port0.config.duplex.get=2" + "ethernet.port0.config.powerDown.get=0" + "ethernet.port0.config.enable_sleepMode.get=1" + "ethernet.port0.config.enable_interrupt.get=0" + "ethernet.port1.config.speed.get=1" + "ethernet.port1.config.duplex.get=0" + "ethernet.port1.config.powerDown.get=1" + "ethernet.port1.config.enable_sleepMode.get=0" + "ethernet.port1.config.enable_interrupt.get=0" + "ethernet.port2.config.speed.get=1" + "ethernet.port2.config.duplex.get=1" + "ethernet.port2.config.powerDown.get=1" + "ethernet.port2.config.enable_sleepMode.get=1" + "ethernet.port2.config.enable_interrupt.get=0" + "ethernet.port3.config.speed.get=1" + "ethernet.port3.config.duplex.get=0" + "ethernet.port3.config.powerDown.get=0" + "ethernet.port3.config.enable_sleepMode.get=1" + "ethernet.port3.config.enable_interrupt.get=0" + "ethernet.port4.config.speed.get=1" + "ethernet.port4.config.duplex.get=1" + "ethernet.port4.config.powerDown.get=1" + "ethernet.port4.config.enable_sleepMode.get=1" + "ethernet.port4.config.enable_interrupt.get=0") + +ethernetStatusParam=("ethernet.port0.status.speed.get" + "ethernet.port0.status.duplex.get" + "ethernet.port1.status.speed.get" + "ethernet.port1.status.duplex.get" + "ethernet.port2.status.speed.get" + "ethernet.port2.status.duplex.get" + "ethernet.port3.status.speed.get" + "ethernet.port3.status.duplex.get" + "ethernet.port4.status.speed.get" + "ethernet.port4.status.duplex.get") + +ethernetStatusMinVal=(1 1 1 1 1 1 1 1 1 1) + +ethernetStatusMaxVal=(1 1 1 1 1 1 1 1 1 1) + +syncParam=("sync.sensor.config.temp_sensor1.lowlimit.get" + "sync.sensor.config.temp_sensor1.highlimit.get" + "sync.sensor.config.temp_sensor1.critlimit.get") + +defaultSync=("sync.sensor.config.temp_sensor1.lowlimit.get=-20" + "sync.sensor.config.temp_sensor1.highlimit.get=80" + "sync.sensor.config.temp_sensor1.critlimit.get=85") + +setSyncVal=("sync.sensor.config.temp_sensor1.lowlimit.get=-19" + "sync.sensor.config.temp_sensor1.highlimit.get=81" + "sync.sensor.config.temp_sensor1.critlimit.get=86") + +syncStatusParam=("sync.sensor.status.temp_sensor1.temperature.get") + +syncStatusMinVal=(-20) + +syncStatusMaxVal=(80) + +debugI2CParam=("debug.I2C.bus0.get 104 2 58" + "debug.I2C.bus1.get 24 2 2" + "debug.I2C.bus2.get 29 1 0" + "debug.I2C.bus3.get 68 2 255" + "debug.I2C.bus4.get 65 2 254" + "debug.I2C.bus6.get 64 2 5" + "debug.I2C.bus7.get 69 2 5" + "debug.I2C.bus8.get 26 2 6") + + +defaultDebugI2C=("debug.I2C.bus0(slaveaddress:104noOfBytes:2RegisterAddress:58)get=9984" + "debug.I2C.bus1(slaveaddress:24noOfBytes:2RegisterAddress:2)get=1216" + "debug.I2C.bus2(slaveaddress:29noOfBytes:1RegisterAddress:0)get=115" + "debug.I2C.bus3(slaveaddress:68noOfBytes:2RegisterAddress:255)get=8800" + "debug.I2C.bus4(slaveaddress:65noOfBytes:2RegisterAddress:254)get=21577" + "debug.I2C.bus6(slaveaddress:64noOfBytes:2RegisterAddress:5)get=25600" + "debug.I2C.bus7(slaveaddress:69noOfBytes:2RegisterAddress:5)get=25600" + "debug.I2C.bus8(slaveaddress:26noOfBytes:2RegisterAddress:6)get=0") + +setDebugI2CVal=("debug.I2C.bus0(slaveaddress:104noOfBytes:2RegisterAddress:58)get=7000" + "debug.I2C.bus1(slaveaddress:24noOfBytes:2RegisterAddress:2)get=1024" + "debug.I2C.bus2(slaveaddress:29noOfBytes:1RegisterAddress:0)get=100" + "debug.I2C.bus3(slaveaddress:68noOfBytes:2RegisterAddress:255)get=8000" + "debug.I2C.bus4(slaveaddress:65noOfBytes:2RegisterAddress:254)get=21500" + "debug.I2C.bus6(slaveaddress:64noOfBytes:2RegisterAddress:5)get=25500" + "debug.I2C.bus7(slaveaddress:69noOfBytes:2RegisterAddress:5)get=25500" + "debug.I2C.bus8(slaveaddress:26noOfBytes:2RegisterAddress:6)get=4000") + +debugGpioParam=("debug.ec.PA.get 1" + "debug.ec.PB.get 1" + "debug.ec.PC.get 1" + "debug.ec.PD.get 7" + "debug.ec.PE.get 1" + "debug.ec.PF.get 1" + "debug.ec.PG.get 1" + "debug.ec.PH.get 1" + "debug.ec.PJ.get 1" + "debug.ec.PK.get 1" + "debug.ec.PL.get 5" + "debug.ec.PM.get 1" + "debug.ec.PN.get 1" + "debug.ec.PP.get 3" + "debug.ec.PQ.get 1" + "debug.gbc.ioexpanderx70.get 1" + "debug.gbc.ioexpanderx71.get 0" + "debug.sdr.ioexpanderx1E.get 1" + "debug.fe.ioexpanderx18.get 1" + "debug.fe.ioexpanderx1A.get 0" + "debug.fe.ioexpanderx1B.get 1" + "debug.fe.ioexpanderx1C.get 1" + "debug.fe.ioexpanderx1D.get 1" + "debug.sync.ioexpanderx71.get 1") + +defaultDebugGpio=("debug.ec.PA(PinNo:1)get=0" + "debug.ec.PB(PinNo:1)get=0" + "debug.ec.PC(PinNo:1)get=0" + "debug.ec.PD(PinNo:7)get=1" + "debug.ec.PE(PinNo:1)get=1" + "debug.ec.PF(PinNo:1)get=0" + "debug.ec.PG(PinNo:1)get=0" + "debug.ec.PH(PinNo:1)get=0" + "debug.ec.PJ(PinNo:1)get=0" + "debug.ec.PK(PinNo:1)get=0" + "debug.ec.PL(PinNo:5)get=0" + "debug.ec.PM(PinNo:1)get=0" + "debug.ec.PN(PinNo:1)get=0" + "debug.ec.PP(PinNo:3)get=0" + "debug.ec.PQ(PinNo:1)get=1" + "debug.gbc.ioexpanderx70(PinNo:1)get=1" + "debug.gbc.ioexpanderx71(PinNo:0)get=1" + "debug.sdr.ioexpanderx1E(PinNo:1)get=1" + "debug.fe.ioexpanderx18(PinNo:1)get=1" + "debug.fe.ioexpanderx1A(PinNo:0)get=1" + "debug.fe.ioexpanderx1B(PinNo:1)get=1" + "debug.fe.ioexpanderx1C(PinNo:1)get=1" + "debug.fe.ioexpanderx1D(PinNo:1)get=0" + "debug.sync.ioexpanderx71(PinNo:1)get=0") + +setDebugGpioVal=("debug.ec.PA(PinNo:1)get=1" + "debug.ec.PB(PinNo:1)get=1" + "debug.ec.PC(Pin No:1)get=1" + "debug.ec.PD(Pin No:7)get=0" + "debug.ec.PE(Pin No:1)get=0" + "debug.ec.PF(PinNo:1)get=1" + "debug.ec.PG(Pin No:1)get=1" + "debug.ec.PH(PinNo:1)get=1" + "debug.ec.PJ(PinNo:1)get=1" + "debug.ec.PK(PinNo:1)get=1" + "debug.ec.PL(PinNo:5)get=1" + "debug.ec.PM(PinNo:1)get=0" + "debug.ec.PN(PinNo:1)get=0" + "debug.ec.PP(PinNo:3)get=0" + "debug.ec.PQ(PinNo:1)get=0" + "debug.gbc.ioexpanderx70(PinNo:1)get=0" + "debug.gbc.ioexpanderx71(PinNo:0)get=0" + "debug.sdr.ioexpanderx1E(PinNo:1)get=0" + "debug.fe.ioexpanderx18(PinNo:1)get=0" + "debug.fe.ioexpanderx1A(PinNo:0)get=0" + "debug.fe.ioexpanderx1B(PinNo:1)get=0" + "debug.fe.ioexpanderx1C(PinNo:1)get=0" + "debug.fe.ioexpanderx1D(PinNo:1)get=1" + "debug.sync.ioexpanderx71(PinNo:1)get=1") + +debugMdioParam=("debug.ethernet.port0.get 18" + "debug.ethernet.global1.get 4" + "debug.ethernet.global2.get 1" + "debug.ethernet.swport0.get 1") + +defaultDebugMdio=("debug.ethernet.port0(RegisterAddress:18)get=9216" + "debug.ethernet.global1(RegisterAddress:4)get=1" + "debug.ethernet.global2(RegisterAddress:1)get=0" + "debug.ethernet.swport0(RegisterAddress:1)get=3") + +setDebugMdioVal=("debug.ethernet.port0(RegisterAddress:18)get=1024" + "debug.ethernet.global1(RegisterAddress:4)get=128" + "debug.ethernet.global2(RegisterAddress:1)get=31" + "debug.ethernet.swport0(RegisterAddress:1)get=1") + +function compareValue() { + local -n paramArray=$1 + local -n valueArray=$2 + i=0 + for index in "${paramArray[@]}" + do + val=${valueArray[$i]} + value=$(../bin/occmd $index) + valueStr=$value + printf -v value '%s' $value + if [ "$value" = "$val" ]; then + echo "${paramArray[$i]} Passed" + echo "$valueStr" + else + echo "${paramArray[$i]} FAILED" + if [[ "$value" =~ "Failed" ]]; then + echo "Failed from TIVA" + else + echo "Value Mismatch" + echo "$valueStr" + fi + fi + ((i++)) + done +} + +function errorPrint() { + + if [[ "$1" =~ "Failed" ]]; then + echo "Failed from TIVA" + else + echo "Value not in range: Max=$2 Min=$3 value=$4" + fi +} + +function compareStatusValue() { + local -n paramStatusArray=$1 + local -n minArray=$2 + local -n maxArray=$3 + i=0 + for index in "${paramStatusArray[@]}" + do + minVal=${minArray[$i]} + maxVal=${maxArray[$i]} + value=$(../bin/occmd $index) + valueStr=$value + printf -v value '%s' $value + IFS='=' read -ra token <<< "$value" + statusVal=${token[1]} + if [[ ("$value" =~ "ethernet") ]]; then + if [[ ($statusVal -eq $maxVal) ]]; then + echo "$valueStr Passed" + else + echo "$valueStr Failed" + errorPrint $value $maxVal $minVal $statusVal + fi + elif [[ ($statusVal -le $maxVal) ]]; then + if [[ ($statusVal -ge $minVal) ]]; then + echo "$valueStr Passed" + else + echo "$valueStr Failed" + errorPrint $value $maxVal $minVal $statusVal + fi + else + echo "$valueStr Failed" + errorPrint $value $maxVal $minVal $statusVal + fi + ((i++)) + done +} + +if [ -z "$1" ]; then + echo "Invalid Option" + echo "Usage : ./get_params " + exit +elif [ $1 = "bms" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue bmsParam defaultBms +elif [ $3 = "verify" ]; then + compareValue bmsParam setBmsVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue bmsStatusParam bmsStatusMinVal bmsStatusMaxVal +else + echo "Invalid Option" +fi +elif [ $1 = "gpp" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue gppParam defaultGpp +elif [ $3 = "verify" ]; then + compareValue gppParam setGppVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue gppStatusParam gppStatusMinVal gppStatusMaxVal +else + echo "Invalid Option" +fi +elif [ $1 = "sdr" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue sdrParam defaultSdr +elif [ $3 = "verify" ]; then + compareValue sdrParam setSdrVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue sdrStatusParam sdrStatusMinVal sdrStatusMaxVal +../bin/occmd sdr.comp_all.status.eeprom.dev_id.get +else + echo "Invalid Option" +fi +elif [ $1 = "rf" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue rfParam defaultRf +elif [ $3 = "verify" ]; then + compareValue rfParam setRfVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue rfStatusParam rfStatusMinVal rfStatusMaxVal +../bin/occmd rffe.comp_all.status.eeprom.dev_id.get +else + echo "Invalid Option" +fi +elif [ $1 = "power" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue powerParam defaultPower +elif [ $3 = "verify" ]; then + compareValue powerParam setPowerVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then +../bin/occmd power.leadacid_sensor.status.temp_sensor1.temperature.get +../bin/occmd power.leadacid.status.battery.batteryVoltage.get +../bin/occmd power.leadacid.status.battery.batteryCurrent.get +../bin/occmd power.leadacid.status.battery.systemVoltage.get +../bin/occmd power.leadacid.status.battery.inputVoltage.get +../bin/occmd power.leadacid.status.battery.inputCurrent.get +../bin/occmd power.leadacid.status.battery.dieTemperature.get +../bin/occmd power.lion.status.battery.batteryVoltage.get +../bin/occmd power.lion.status.battery.batteryCurrent.get +../bin/occmd power.lion.status.battery.systemVoltage.get +../bin/occmd power.lion.status.battery.inputVoltage.get +../bin/occmd power.lion.status.battery.inputCurrent.get +../bin/occmd power.lion.status.battery.dieTemperature.get +../bin/occmd power.pse.status.detection.get +../bin/occmd power.pse.status.class.get +../bin/occmd power.pse.status.powerGood.get +# Commented as of now as PD Driver doesnt have enum values defined +#../bin/occmd power.pd.status.class.get +#../bin/occmd power.pd.status.powerGoodState.get +../bin/occmd power.comp_all.status.powerSource.extBattAccessebility.get +../bin/occmd power.comp_all.status.powerSource.extBattAvailability.get +../bin/occmd power.comp_all.status.powerSource.intBattAccessebility.get +../bin/occmd power.comp_all.status.powerSource.intBattAvailability.get +../bin/occmd power.comp_all.status.powerSource.poeAccessebility.get +../bin/occmd power.comp_all.status.powerSource.poeAvailability.get +../bin/occmd power.comp_all.status.powerSource.solarAccessebility.get +../bin/occmd power.comp_all.status.powerSource.solarAvailability.get +else + echo "Invalid Option" +fi +elif [ $1 = "ethernet" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue ethParam defaultEth +elif [ $3 = "verify" ]; then + compareValue ethParam setEthVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue ethernetStatusParam ethernetStatusMinVal ethernetStatusMaxVal + +../bin/occmd ethernet.port0.status.sleep_mode_en.get +../bin/occmd ethernet.port0.status.autoneg_on.get +../bin/occmd ethernet.port0.status.autoneg_complete.get +../bin/occmd ethernet.port0.status.link_up.get +../bin/occmd ethernet.port1.status.sleep_mode_en.get +../bin/occmd ethernet.port1.status.autoneg_on.get +../bin/occmd ethernet.port1.status.autoneg_complete.get +../bin/occmd ethernet.port1.status.link_up.get +../bin/occmd ethernet.port2.status.sleep_mode_en.get +../bin/occmd ethernet.port2.status.autoneg_on.get +../bin/occmd ethernet.port2.status.autoneg_complete.get +../bin/occmd ethernet.port2.status.link_up.get +../bin/occmd ethernet.port3.status.sleep_mode_en.get +../bin/occmd ethernet.port3.status.autoneg_on.get +../bin/occmd ethernet.port3.status.autoneg_complete.get +../bin/occmd ethernet.port3.status.link_up.get +../bin/occmd ethernet.port4.status.sleep_mode_en.get +../bin/occmd ethernet.port4.status.autoneg_on.get +../bin/occmd ethernet.port4.status.autoneg_complete.get +../bin/occmd ethernet.port4.status.link_up.get +else + echo "Invalid Option" +fi +elif [ $1 = "sync" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue syncParam defaultSync +elif [ $3 = "verify" ]; then + compareValue syncParam setSyncVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue syncStatusParam syncStatusMinVal syncStatusMaxVal +../bin/occmd sync.gps.status.gps_lock.get +else + echo "Invalid Option" +fi +elif [ $1 = "testmodule" ]; then +if [ $2 = "status" ]; then +../bin/occmd testmodule.2gsim.status.imei.get +../bin/occmd testmodule.2gsim.status.imsi.get +../bin/occmd testmodule.2gsim.status.mfg.get +../bin/occmd testmodule.2gsim.status.model.get +../bin/occmd testmodule.2gsim.status.rssi.get +../bin/occmd testmodule.2gsim.status.ber.get +../bin/occmd testmodule.2gsim.status.registration.get +../bin/occmd testmodule.2gsim.status.network_operatorinfo.get +../bin/occmd testmodule.2gsim.status.cellid.get +../bin/occmd testmodule.2gsim.status.bsic.get +../bin/occmd testmodule.2gsim.status.lasterror.get +else + echo "Invalid Option" +fi +elif [ $1 = "obc" ]; then +if [ $2 = "status" ]; then +../bin/occmd obc.iridium.status.imei.get +../bin/occmd obc.iridium.status.mfg.get +../bin/occmd obc.iridium.status.model.get +../bin/occmd obc.iridium.status.signal_quality.get +../bin/occmd obc.iridium.status.registration.get +../bin/occmd obc.iridium.status.numberofoutgoingmessage.get +../bin/occmd obc.iridium.status.lasterror.get +else + echo "Invalid Option" +fi +elif [ $1 = "hci" ]; then +if [ $2 = "config" ]; then +if [ $3 = "default" ]; then + compareValue hciParam defaultHci +elif [ $3 = "verify" ]; then + compareValue hciParam setHciVal +else + echo "Invalid Option" +fi +elif [ $2 = "status" ]; then + compareStatusValue hciStatusParam hciStatusMinVal hciStatusMaxVal +else + echo "Invalid Option" +fi +elif [ $1 = "system" ]; then +if [ $2 = "status" ]; then +../bin/occmd system.comp_all.status.eeprom_sid.gbcboardinfo.get +../bin/occmd system.comp_all.status.eeprom_sid.ocserialinfo.get +../bin/occmd system.comp_all.config.eeprom_mac.address.get +elif [ $2 = "post" ]; then +../bin/occmd system.comp_all.post.results.get +../bin/occmd system.comp_all.post.enable.set +else + echo "Invalid Option" +fi +elif [ $1 = "debug" ]; then +if [ $2 = "I2C" ]; then +if [ $3 = "default" ]; then + compareValue debugI2CParam defaultDebugI2C +elif [ $3 = "verify" ]; then + compareValue debugI2CParam setDebugI2CVal +else + echo "Invalid Option" +fi +elif [ $2 = "GPIO" ]; then +if [ $3 = "default" ]; then + compareValue debugGpioParam defaultDebugGpio +elif [ $3 = "verify" ]; then + compareValue debugGpioParam setDebugGpioVal +else + echo "Invalid Option" +fi +elif [ $2 = "MDIO" ]; then +if [ $3 = "default" ]; then + compareValue debugMdioParam defaultDebugMdio +elif [ $3 = "verify" ]; then + compareValue debugMdioParam setDebugMdioVal +else + echo "Invalid Option" +fi +else + echo "Invalid Option" +fi +elif [ $1 = "command" ]; then +../bin/occmd system.comp_all.echo +../bin/occmd ethernet.port0.reset +../bin/occmd ethernet.port1.reset +../bin/occmd ethernet.port2.reset +../bin/occmd ethernet.port3.reset +../bin/occmd ethernet.port4.reset +#../bin/occmd power.pse.reset +../bin/occmd rffe.comp_all.reset +../bin/occmd hci.led.fw.set 1 +../bin/occmd rffe.ch1_fe.enable +../bin/occmd rffe.ch1_fe.disable +../bin/occmd rffe.ch2_fe.disable +../bin/occmd rffe.ch2_fe.enable +../bin/occmd testmodule.2gsim.enable +../bin/occmd testmodule.2gsim.disable +../bin/occmd testmodule.2gsim.disconnect_nw +../bin/occmd testmodule.2gsim.connect_nw +../bin/occmd testmodule.2gsim.send 9789799425 hi +../bin/occmd testmodule.2gsim.dial 9789799425 +../bin/occmd testmodule.2gsim.answer +../bin/occmd testmodule.2gsim.hangup +../bin/occmd testmodule.comp_all.reset +../bin/occmd sdr.comp_all.reset +../bin/occmd sdr.fx3.reset +../bin/occmd obc.iridium.reset +../bin/occmd sync.comp_all.reset +../bin/occmd ethernet.port0.en_loopBk 0 +../bin/occmd ethernet.port0.en_pktGen 8374 +../bin/occmd ethernet.port0.dis_pktGen +../bin/occmd ethernet.port0.dis_loopBk 0 +../bin/occmd ethernet.port1.en_loopBk 0 +../bin/occmd ethernet.port1.en_pktGen 8374 +../bin/occmd ethernet.port1.dis_pktGen +../bin/occmd ethernet.port1.dis_loopBk 0 +../bin/occmd ethernet.port2.en_loopBk 0 +../bin/occmd ethernet.port2.en_pktGen 8374 +../bin/occmd ethernet.port2.dis_pktGen +../bin/occmd ethernet.port2.dis_loopBk 0 +../bin/occmd ethernet.port3.en_loopBk 0 +../bin/occmd ethernet.port3.en_pktGen 8374 +../bin/occmd ethernet.port3.dis_pktGen +../bin/occmd ethernet.port3.dis_loopBk 0 +../bin/occmd ethernet.port4.en_loopBk 0 +../bin/occmd ethernet.port4.en_pktGen 8374 +../bin/occmd ethernet.port4.dis_pktGen +../bin/occmd ethernet.port4.dis_loopBk 0 +else + echo "Invalid Option" +fi +echo "Done..." + diff --git a/firmware/host/scripts/set_config_params.sh b/firmware/host/scripts/set_config_params.sh new file mode 100755 index 0000000000..b68d62ab01 --- /dev/null +++ b/firmware/host/scripts/set_config_params.sh @@ -0,0 +1,198 @@ +#!/bin/sh +if [ -z "$1" ]; then + echo "Invalid Option" + echo "Usage : ./set_config_params " + exit +elif [ $1 = "post" ]; then +../bin/occmd system.comp_all.post.test.enable.set +elif [ $1 = "bms" ]; then +../bin/occmd bms.ec.config.temp_sensor1.lowlimit.set -19 +../bin/occmd bms.ec.config.temp_sensor1.highlimit.set 76 +../bin/occmd bms.ec.config.temp_sensor1.critlimit.set 85 +../bin/occmd bms.ec.config.current_sensor1.currlimit.set 1500 +../bin/occmd bms.ec.config.current_sensor2.currlimit.set 1500 +elif [ $1 = "gpp" ]; then +../bin/occmd gpp.ap.config.temp_sensor1.lowlimit.set -19 +../bin/occmd gpp.ap.config.temp_sensor1.highlimit.set 81 +../bin/occmd gpp.ap.config.temp_sensor1.critlimit.set 86 +../bin/occmd gpp.ap.config.temp_sensor2.lowlimit.set -19 +../bin/occmd gpp.ap.config.temp_sensor2.highlimit.set 81 +../bin/occmd gpp.ap.config.temp_sensor2.critlimit.set 86 +../bin/occmd gpp.ap.config.current_sensor1.currlimit.set 2010 +../bin/occmd gpp.ap.config.temp_sensor3.lowlimit.set -19 +../bin/occmd gpp.ap.config.temp_sensor3.highlimit.set 81 +../bin/occmd gpp.ap.config.temp_sensor3.critlimit.set 86 +../bin/occmd gpp.msata.config.current_sensor1.currlimit.set 2010 +elif [ $1 = "sdr" ]; then +../bin/occmd sdr.comp_all.config.current_sensor1.currlimit.set 2010 +../bin/occmd sdr.fpga.config.temp_sensor1.lowlimit.set -19 +../bin/occmd sdr.fpga.config.temp_sensor1.highlimit.set 76 +../bin/occmd sdr.fpga.config.temp_sensor1.critlimit.set 81 +../bin/occmd sdr.fpga.config.current_sensor1.currlimit.set 510 +elif [ $1 = "rf" ]; then +../bin/occmd rffe.ch1_sensor.config.temp_sensor1.lowlimit.set -19 +../bin/occmd rffe.ch1_sensor.config.temp_sensor1.highlimit.set 76 +../bin/occmd rffe.ch1_sensor.config.temp_sensor1.critlimit.set 81 +../bin/occmd rffe.ch1_sensor.config.current_sensor1.currlimit.set 1500 +../bin/occmd rffe.ch2_sensor.config.temp_sensor1.lowlimit.set -19 +../bin/occmd rffe.ch2_sensor.config.temp_sensor1.highlimit.set 76 +../bin/occmd rffe.ch2_sensor.config.temp_sensor1.critlimit.set 81 +../bin/occmd rffe.ch2_sensor.config.current_sensor1.currlimit.set 510 +../bin/occmd rffe.ch1_fe.config.ch1_band.band.set 3 +../bin/occmd rffe.ch1_fe.config.tx.atten.set 60 +../bin/occmd rffe.ch1_fe.config.rx.atten.set 20 +../bin/occmd rffe.ch2_fe.config.tx.atten.set 60 +../bin/occmd rffe.ch2_fe.config.rx.atten.set 20 +../bin/occmd rffe.ch2_fe.config.ch2_band.band.set 3 + +elif [ $1 = "power" ]; then +../bin/occmd power.leadacid_sensor.config.temp_sensor1.lowlimit.set -19 +../bin/occmd power.leadacid_sensor.config.temp_sensor1.highlimit.set 76 +../bin/occmd power.leadacid_sensor.config.temp_sensor1.critlimit.set 81 +../bin/occmd power.leadacid.config.battery.batteryVoltageLow.set 12500 +../bin/occmd power.leadacid.config.battery.batteryVoltageHigh.set 16500 +../bin/occmd power.leadacid.config.battery.batteryCurrentLow.set 900 +../bin/occmd power.leadacid.config.battery.inputVoltageLow.set 16210 +../bin/occmd power.leadacid.config.battery.inputCurrentHigh.set 17400 +../bin/occmd power.leadacid.config.battery.inputCurrentLimit.set 15000 +#../bin/occmd power.leadacid.config.battery.maxcurr_chargesetting.set 10000 +../bin/occmd power.leadacid.config.battery.vcharge.set 10660 +../bin/occmd power.leadacid.config.battery.icharge.set 12000 +../bin/occmd power.lion.config.battery.batteryVoltageLow.set 9010 +../bin/occmd power.lion.config.battery.batteryVoltageHigh.set 12700 +../bin/occmd power.lion.config.battery.batteryCurrentLow.set 110 +../bin/occmd power.lion.config.battery.inputVoltageLow.set 16210 +../bin/occmd power.lion.config.battery.inputCurrentHigh.set 5010 +../bin/occmd power.lion.config.battery.inputCurrentLimit.set 3580 +../bin/occmd power.lion.config.battery.vcharge.set 10660 +../bin/occmd power.lion.config.battery.icharge.set 12000 +../bin/occmd power.pse.config.operatingMode.set 3 +../bin/occmd power.pse.config.detectEnable.set 64 +../bin/occmd power.pse.config.interruptMask.set 195 +../bin/occmd power.pse.config.interruptEnable.set 128 +../bin/occmd power.pse.config.enableHighpower.set 17 +elif [ $1 = "ethernet" ]; then +../bin/occmd ethernet.port0.config.speed.set 0 +../bin/occmd ethernet.port0.config.duplex.set 2 +../bin/occmd ethernet.port0.config.powerDown.set 0 +../bin/occmd ethernet.port0.config.enable_sleepMode.set 1 +../bin/occmd ethernet.port0.config.enable_interrupt.set 10 +../bin/occmd ethernet.port1.config.speed.set 1 +../bin/occmd ethernet.port1.config.duplex.set 0 +../bin/occmd ethernet.port1.config.powerDown.set 1 +../bin/occmd ethernet.port1.config.enable_sleepMode.set 0 +../bin/occmd ethernet.port1.config.enable_interrupt.set 1 +../bin/occmd ethernet.port2.config.speed.set 1 +../bin/occmd ethernet.port2.config.duplex.set 1 +../bin/occmd ethernet.port2.config.powerDown.set 1 +../bin/occmd ethernet.port2.config.enable_sleepMode.set 1 +../bin/occmd ethernet.port2.config.enable_interrupt.set 0 +../bin/occmd ethernet.port3.config.speed.set 1 +../bin/occmd ethernet.port3.config.duplex.set 0 +../bin/occmd ethernet.port3.config.powerDown.set 0 +../bin/occmd ethernet.port3.config.enable_sleepMode.set 1 +../bin/occmd ethernet.port3.config.enable_interrupt.set 1 +../bin/occmd ethernet.port4.config.speed.set 1 +../bin/occmd ethernet.port4.config.duplex.set 1 +../bin/occmd ethernet.port4.config.powerDown.set 1 +../bin/occmd ethernet.port4.config.enable_sleepMode.set 1 +../bin/occmd ethernet.port4.config.enable_interrupt.set 1 +elif [ $1 = "sync" ]; then +../bin/occmd sync.sensor.config.temp_sensor1.lowlimit.set -19 +../bin/occmd sync.sensor.config.temp_sensor1.highlimit.set 81 +../bin/occmd sync.sensor.config.temp_sensor1.critlimit.set 86 +elif [ $1 = "hci" ]; then +../bin/occmd hci.led.config.temp_sensor1.lowlimit.set -19 +../bin/occmd hci.led.config.temp_sensor1.highlimit.set 76 +../bin/occmd hci.led.config.temp_sensor1.critlimit.set 85 +elif [ $1 = "debug" ]; then +if [ $2 = "I2C" ]; then +if [ $3 = "stub" ]; then +../bin/occmd debug.I2C.bus0.set 1 1 1 1 +../bin/occmd debug.I2C.bus1.set 1 1 1 1024 +../bin/occmd debug.I2C.bus2.set 1 1 1 2 +../bin/occmd debug.I2C.bus3.set 1 1 1 1025 +../bin/occmd debug.I2C.bus4.set 1 1 1 3 +../bin/occmd debug.I2C.bus6.set 1 1 1 4 +../bin/occmd debug.I2C.bus7.set 1 1 1 1027 +../bin/occmd debug.I2C.bus8.set 1 1 1 5 +elif [ $3 = "FW" ]; then +../bin/occmd debug.I2C.bus0.set 104 2 58 7000 +../bin/occmd debug.I2C.bus1.set 24 2 2 1024 +../bin/occmd debug.I2C.bus2.set 29 1 0 100 +../bin/occmd debug.I2C.bus3.set 68 2 255 8000 +../bin/occmd debug.I2C.bus4.set 65 2 254 21500 +../bin/occmd debug.I2C.bus6.set 64 2 5 25500 +../bin/occmd debug.I2C.bus7.set 69 2 5 25500 +../bin/occmd debug.I2C.bus8.set 26 2 6 4000 +else +echo "Invalid Option" +fi +elif [ $2 = "GPIO" ]; then +if [ $3 = "stub" ]; then +../bin/occmd debug.ec.PA.set 1 1 +../bin/occmd debug.ec.PB.set 1 1 +../bin/occmd debug.ec.PC.set 1 1 +../bin/occmd debug.ec.PD.set 1 0 +../bin/occmd debug.ec.PE.set 1 0 +../bin/occmd debug.ec.PF.set 1 1 +../bin/occmd debug.ec.PG.set 1 1 +../bin/occmd debug.ec.PJ.set 1 1 +../bin/occmd debug.ec.PK.set 1 1 +../bin/occmd debug.ec.PL.set 1 1 +../bin/occmd debug.ec.PM.set 1 0 +../bin/occmd debug.ec.PN.set 1 0 +../bin/occmd debug.ec.PP.set 1 0 +../bin/occmd debug.ec.PQ.set 1 0 + +../bin/occmd debug.gbc.ioexpanderx70.set 1 0 +../bin/occmd debug.gbc.ioexpanderx71.set 1 0 +../bin/occmd debug.sdr.ioexpanderx1E.set 1 0 +../bin/occmd debug.fe.ioexpanderx18.set 1 0 +../bin/occmd debug.fe.ioexpanderx1A.set 1 1 +../bin/occmd debug.fe.ioexpanderx1B.set 1 0 +../bin/occmd debug.fe.ioexpanderx1C.set 1 0 +../bin/occmd debug.fe.ioexpanderx1D.set 1 1 +../bin/occmd debug.sync.ioexpanderx71.set 1 1 +elif [ $3 = "FW" ]; then +../bin/occmd debug.ec.PA.set 1 1 +../bin/occmd debug.ec.PB.set 1 1 +../bin/occmd debug.ec.PC.set 1 1 +../bin/occmd debug.ec.PD.set 7 0 +../bin/occmd debug.ec.PE.set 1 0 +../bin/occmd debug.ec.PF.set 1 1 +../bin/occmd debug.ec.PG.set 1 1 +../bin/occmd debug.ec.PH.set 1 1 +../bin/occmd debug.ec.PJ.set 1 1 +../bin/occmd debug.ec.PK.set 1 1 +../bin/occmd debug.ec.PL.set 5 1 +../bin/occmd debug.ec.PM.set 1 0 +../bin/occmd debug.ec.PN.set 1 0 +../bin/occmd debug.ec.PP.set 3 0 +../bin/occmd debug.ec.PQ.set 1 0 + +../bin/occmd debug.gbc.ioexpanderx70.set 1 0 +../bin/occmd debug.gbc.ioexpanderx71.set 0 0 +../bin/occmd debug.sdr.ioexpanderx1E.set 1 0 +../bin/occmd debug.fe.ioexpanderx18.set 1 0 +../bin/occmd debug.fe.ioexpanderx1A.set 0 1 +../bin/occmd debug.fe.ioexpanderx1B.set 1 0 +../bin/occmd debug.fe.ioexpanderx1C.set 1 0 +../bin/occmd debug.fe.ioexpanderx1D.set 1 1 +../bin/occmd debug.sync.ioexpanderx71.set 1 1 +else +echo "Invalid Option" +fi +elif [ $2 = "MDIO" ]; then +../bin/occmd debug.ethernet.port0.set 18 1024 +../bin/occmd debug.ethernet.global1.set 4 128 +../bin/occmd debug.ethernet.global2.set 1 31 +../bin/occmd debug.ethernet.swport0.set 1 1 +else +echo "Invalid Option" +fi + +else + echo "Invalid Option" +fi +echo "Done..." diff --git a/firmware/host/scripts/test_all.sh b/firmware/host/scripts/test_all.sh new file mode 100755 index 0000000000..4bf5f76791 --- /dev/null +++ b/firmware/host/scripts/test_all.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +echo "##############################" +echo " GET CONFIG PARAMS - 1 " +echo "##############################" +./get_params.sh bms config default +./get_params.sh gpp config default +./get_params.sh sdr config default +./get_params.sh rf config default +./get_params.sh power config default +./get_params.sh ethernet config default +./get_params.sh sync config default +./get_params.sh hci config default + +echo "##############################" +echo " SET CONFIG PARAMS " +echo "##############################" +./set_config_params.sh bms +./set_config_params.sh gpp +./set_config_params.sh sdr +./set_config_params.sh rf +./set_config_params.sh power +./set_config_params.sh ethernet +./set_config_params.sh sync +./set_config_params.sh hci + +echo "##############################" +echo " GET CONFIG PARAMS - 2 " +echo "##############################" +./get_params.sh bms config verify +./get_params.sh gpp config verify +./get_params.sh sdr config verify +./get_params.sh rf config verify +./get_params.sh power config verify +./get_params.sh ethernet config verify +./get_params.sh sync config verify +./get_params.sh hci config verify + +echo "##############################" +echo " POST COMMANDS " +echo "##############################" +./get_params.sh system post + +echo "##############################" +echo " GET STATUS PARAMS " +echo "##############################" +./get_params.sh bms status +./get_params.sh gpp status +./get_params.sh sdr status +./get_params.sh rf status +./get_params.sh power status +./get_params.sh ethernet status +./get_params.sh sync status +./get_params.sh testmodule status +./get_params.sh obc status +./get_params.sh hci status +./get_params.sh system status + +echo "##############################" +echo " GET COMMANDS - 1 " +echo "##############################" +./get_params.sh command + +echo "##############################" +echo " GET DEBUG COMMANDS - 1 " +echo "##############################" +./get_params.sh debug I2C default +./get_params.sh debug GPIO default +./get_params.sh debug MDIO default + +echo "##############################" +echo " SET DEBUG COMMANDS " +echo "##############################" +./set_config_params.sh debug I2C FW +./set_config_params.sh debug GPIO FW +./set_config_params.sh debug MDIO + +echo "##############################" +echo " GET DEBUG COMMANDS - 2 " +echo "##############################" +./get_params.sh debug I2C verify +./get_params.sh debug GPIO verify +./get_params.sh debug MDIO verify + +echo " >>> TESTING DONE <<< " diff --git a/firmware/host/util/logger.c b/firmware/host/util/logger.c new file mode 100644 index 0000000000..b7f63ac94f --- /dev/null +++ b/firmware/host/util/logger.c @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* OC includes */ +#include + +/************************************************************************** + * Function Name : initlog + * Description : This Function used to initialize the logging + * functionality + * Input(s) : ident + * Output(s) : + ***************************************************************************/ +void initlog(const char* ident) +{ + openlog(ident, LOG_CONS | LOG_PID, LOG_USER); +} + +/************************************************************************** + * Function Name : deinitlog + * Description : This Function used to uninitialize logging + * functionality + * Input(s) : + * Output(s) : + ***************************************************************************/ +void deinitlog(void) +{ + closelog(); +} diff --git a/firmware/host/util/util.c b/firmware/host/util/util.c new file mode 100644 index 0000000000..819932c6fa --- /dev/null +++ b/firmware/host/util/util.c @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* stdlib includes */ +#include +#include + +#define UTIL_NUMBER_ZERO 0 + +void hexdisp(const unsigned char* buf, int buflen) +{ + int c=UTIL_NUMBER_ZERO, i=UTIL_NUMBER_ZERO; + for (c=UTIL_NUMBER_ZERO; c0x20 && buf[i]<0x7F) ? buf[i] : '.'); + printf("\n"); + } + } + printf("\n"); +} From 4f74e7a1d938c102a0f110ed2f1e5721c33bd5cb Mon Sep 17 00:00:00 2001 From: mdlewisfb Date: Mon, 22 Oct 2018 20:42:38 -0700 Subject: [PATCH 2/3] Removing bin directory. --- firmware/host/bin/occli | Bin 92248 -> 0 bytes firmware/host/bin/occmd | 1 - firmware/host/bin/ocmw_eth | Bin 160296 -> 0 bytes firmware/host/bin/ocmw_eth_stub | Bin 160376 -> 0 bytes firmware/host/bin/ocmw_uart | Bin 160168 -> 0 bytes firmware/host/bin/ocmw_usb | Bin 160168 -> 0 bytes firmware/host/bin/ocware_stub | Bin 87632 -> 0 bytes firmware/host/log.txt | 67 -------------------------------- 8 files changed, 68 deletions(-) delete mode 100755 firmware/host/bin/occli delete mode 120000 firmware/host/bin/occmd delete mode 100755 firmware/host/bin/ocmw_eth delete mode 100755 firmware/host/bin/ocmw_eth_stub delete mode 100755 firmware/host/bin/ocmw_uart delete mode 100755 firmware/host/bin/ocmw_usb delete mode 100755 firmware/host/bin/ocware_stub delete mode 100644 firmware/host/log.txt diff --git a/firmware/host/bin/occli b/firmware/host/bin/occli deleted file mode 100755 index d3e6b012265a4a3c6d6a0d628c54392609b4e8f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92248 zcmeFa31C#!**AV?CX=}tLNe?L2#oA5?1;GGutWxBNm&%vBqWm%&1N#gqJqH~HAa-! zYEe;8t5UaO-4JRLQ3+bLw6%)wXWP8KE|X%FYHMk$=KuRW=iJH6kO73WZ~x!dQSN!3 z=RD`x&U4N^=giHWYqRE@W4GB1>ti>j8pNu5`GlmdhOr^1gU4q~F;WblG1M4hB!epn z|13VAhOF{{Zf2Dxc=>VQAKOi_6JzOP5h;%o%rLCd($3PU>r~;>m?~EW6>61+;S~bg z(bn*4K~d%kV3nKaDY~yxl~y~N$9BdVO<$9%0A23ahFPWMAARG$McThbb{{a}J{HDI zxptJ~j_{zL-$_ylqOeFFZZ1pLzz@aKcyV`LaN zy^$N!Wy^)0X^h$*OaD2zdKj6;X3cNS=YQ4oW=*&5D>rC*YaG2;)5CFcF4ubF?Ri1- ze;UW14|-3do3X*;1Jv;uA^xTrugvpx5DDQvP!U{K8OST(bm*rFi^D2Wm zIYv%#S#i*)EXm0W1_PxP!9YPyetBs{Nq|yw%9jT!S&7?FAZKZ)uu!2<9Hn`|{AGbE zBUDvfR+O`>xGGp)xr$9H%8Sb&7^br^DN(KRDk@-LPX4mI%Dns_g@P}-b*I)8hRX8A z*%g(=!9avPrw~3Ec?BH;;BY>@oorN<=U)*BB3vsgigK3bAuM^Nh)%FFzhafKELdJv zWmHvE!qP$#%koPr3|JdPG!RpvfUhDHtbz!HEdL7Fd__)SUU3Pjw4bJzpc}|t5UOAi zEWg62T2)n2US#A)>PiA-MmfADwKPy#1*^b{|Ba=^Wd-Q4AZ;zL2pXl4Ht1XE%@3}s zK=j$yMo}ObC|j=mL1Sb=d1X!|MbUPP0tUuF_i|}oahXa5Dz7Tj4i{Di0!B`tATO8) z{-sq_iX9}_Gi%Q5=`(UBjF~Xzln6XA0!@lQ6UR(qqT1y@2d?~Q{ijxGYHi|-P`UcB zxKvAZwP;prmdW^MlXVKUs1-{GP6$H>bAn-b@h{ZBIEAvW#<=9ihSks%Fj(ucUd6@T zx#GD|#;sxW7TjqxXgrw7_DRM)8dvh{5qbNs%@w&^GjWY!eGWv?2UOBB7A#f)-m z6rF2&>$5G2-p3-MY>uM$jiT?4qW6oU?}?&kMA7#~(KDmytx@y=QS@*W-P%*KdVdss zP!#`xDEiBL3{fif6XiA%SQVt3qWcgz6jU!!9GC5m$7AAYdb!}&n3<&rEQPk z(}~-OHw%6`aR>3Of=?jMsiSSP;3pF2l+m_c@FB!GRkT$L-k&(TzpX;>p2RsdwB-u! zCeA6LEn9FqaZUwoKEeN92Aoqs+c?3$AkLxR<`w)8#5v^KJc55fJdL;^_kC%*q% z5QhJXIEQvytKhE_=a6pOBlu3@9LjCYf^R3zA>6iA@ShUr&~4i+_@l%*WZTvY{s3_f z)wXKE??Zi1W+j0fJnK*}JTejfW5$CO_%_sO(#5pwE#tB|YoI|qBEBNKa zd5dcE2)>j!hi020_(jAyB-{3XL;n{L_Y!Xv{9NK3f^B;QpH6%T@n*qKC(a?)wpH*6 z#5vU3HVb|taSpMz^@0x}&Y{&-EqH(898zr+g7+lOq12WuxSKeKP+PX(cH$g5Z9c*O zUJ9H;rfnSX@qe6M_sh%tbszX^KHQ(ZXm(3;^E{v7Z+R(Oik4Ypk>h>NDe)SAP9Hqe zFur`ba7_B(>(Shh{NHxl8@a|}|7fo7{WS;D{B<9#uwVM}Hr8|C{Q1%*R<*aL53VL{ z8!?Ojr2`J|`|Ec4U;4w@e%l`ZFAs#!csm*WwZB4Rf88$C{sY~<`m7hWd9jS?u^27G zYtR9g?s7g1lI_cvIUfBrXKgM9LvT>Ugx-sr4&by6{Ox-#ZMzyx(gz!DRVXQAAx8SB zmaM(h*^>1>3x7*iD+dJ1F!Alo=0*92b^JVFTmy7%gKHii+{CXRnGF#H%gp+0MG+aEAxZ09g)#6P3S z^JcCQ{v6E;Tbv(1@5LIg=_U-C@Z%)aIo}1Tu{U^{y3O|);mHtEm-T+l>i3P%(8fL> zMQNCgN;n9AMbTO)s&`%w0seK1Tc>TKPJi7mw{r+Ka^8a7yZ+JM4zGqbo)jzUTWF6G zHJLWY1?L``;yeN3>zzY!mEeqkJS#Z;1%{Go;AC)8gwSblZe`pMoHt=sRB*fu&aco6 z!FlgF2~GuOgz#-7)j3}Wsc~2&IGGS)1;-m7oRecb+E-NXEJJIhi)vu!Y0`dg&Fa0z zs_Eg2|K8!se1XBT94vHYst}Yb(_=&TGQG^&yU(fevgVah7hn1^6R_TS;8`#Aj0Z=H z^AjNa2%F+q=wJIO*XaJb7k4xDo_z(^0)Ktda1MKaT~>H}b4%@B5ZSP$_I*I?)%sd8 z`t$er>ucGNgUQFxJ@Pl$vW{#KmU?F;6#MI+CF8WZ*N_+Be1QV#AN;Bl4K*){o>fc2 z3n&CRw5}B`wsR5fuX_u;kAfaPMOWUzN@N%E{-W4;JPnbJw5DkVD%4o`JzI$yfBmK5 z0{_J0#KWL7{19sVYhPg$bl8q8DD;s&sPM!DrQTWn3_M=9jt*(ZXU97}P#mX}nioaZ zstdvw9_ZZhr$G0w6OZeq50u{B$43Xr_}fSXKBDYSBk&ld$3y@Vw%1>`I=n0EubiR} zuz&qEtHVZUK;wbfV9$fnZJhY_UGA^X3j2|sXF%RfS%3AXH{!A`8$Ay?ZasBb2lhGr zHKhk^pd9d@krl2S5pJZ>^&V2vpEJ;=*>A)Dd(xjb(w}dxX|>fhhkh>nHO;nNdeFWm z!x~n4c4d9j9=^(w;oSce){F_n1P3-{WMd{j^Q-purffnJ0Hr^d^-bH|@UPz4gvNz+ zS>L8NWqk`}GOC@+-$qZ?y+glh7^gaC0V(y)OIg6U9!){WQlo1v1n!#zo8U;(;&1)+ z-E$xl%;QALTa>cyFLb!iAX2CazQV2Q)!!JQp5ROt&X#Zp1LCHvZ)l$KR_>zcl)ctH zvnA_8_DdmdrE>kiU?1%@LWAP_=uwy@ebhDqqgyrDHxbHP{TndHy_);ST=>`$e&ElD zhoZJ9Dix$ZpVf+RATq6SO|bZI71pe7J$KF1=%Kw7aW=fG%lc63II}+MLkZ*Duwsx1 z+ygZTTyF^eKneZ;Qa(6$jeXy+PL+AzqJ2mrNx{do@Qc!$E^TcrfQ3!)$_N)Quys5A z`7itHdW%m7nTzzTMQ26bxo<S`vf3LIqYj!4KsZgD;a#!uQ z&|~bXZD--H5#>f`RD4f2!<822XHR0W2JIrQ?GCJ{YF?zBMku?*`Qu-DX_?XDd{9HU zchMJiU-g&p$$2{}qKIp-inzWx*t^AfM~vVzA-JtOF50Ym=l9SMJzD4V1E_bNOF6tZ zI>(8`bqot`VbpZz7fgcm+BX@@`a7g%T`eP|M_Vlz>YXk&+<>`HYHWKNe~A8L`@Znh zUnkM^ugj|5&ODHH9V;{8MvHUP6J9#Xa7ibGhCq>ciUy5$DM1pW@BuVvyPdo$7MMe> zZw_UEpDn3CTlM*$kSZnh&hkC5OK$sOIp(Y9Jlkj+T29#+8sV>BCoQ8C-W#p(Mkw4j ztP`#Wqq*|HrMrILS?P_E1W`j48KccwDbWn2sGhLxJ3jq6VMb@%BtUxO9n7G5=TCp( zHBQ@k%}>F=T&me`L)V^H@4OrIPDOvSpUtjDwe)NyfO=;M(XcJ50iymgjM#T#z4N?? zC^c|pG@uh?P^8zsg>;gr$FD$!BDS~>ad_z!h;<*T3w>C(xYfE7;jYxKrh?%IY)u>q~6J~Bh zwA$PFB^iWn^JATdIq|aktXKRSWRJi+ZV(f83PT<5krv;e_<5`aoHCEKEsc^05l?@8E+grkQ3g2sK0BN~yM}zWNv0LpK|N13v={7ObpZ=4b2v933 zA!+em-s9K#d2`ri@IzZem7~a0KWex4l_Au-jbLA^W&L7!D!1*g6~Bb8elh$N>cgG|9N}^masobr3Wr>xfYd`hjuz*{Ky|MR#1LK?h>uOs; z-R=QLWO};lGh}J)`=CQG*2kT&TmTkb(a5&!rCi=yr5RR?Y`iKH3pxN;=Xt(otwFv) zNcKIZ+p^gl67E(T@wK0BpvJlvmm&G$Zd9yGF8+Ii|(Nx!EW?F<}})6?395FVfUc9M|@Zl9i-nq3L~? zXG)6ea|%pB`=!r17R5+94)bOX^K;>E)G(jG?1cXIwy`*ku;jMA&Mt@&-gd7dv_jh` zXxqQ93f0ZHlbmS_^&(jBOTwTdRF|E!FB`!AIT$t^MDQ(aw)%IM$iLo8~t_GiF{{YH>t_N&P#UG+{4l%TFv)j=UA zs`T19jB5=vqi(ONgB7Z7Fza*_+x|P=+h;nw^}yQ$5OBaqzg`lP`-1<4AiVd7qYJ_* zhX{hY{i{@J>!l`TL`daR+s7S2V1k9)xGhA?uuk?xM@6SbM^sj_pA)9WV%2>(SI-L1 zsb|ru5(Szg8L|=?5^Ann6O|$Uy3}FJk7DKrmr{}ZXlzRynk$w2Vdg+sB~Rls<2 z*dG~7`!SZ<+N`kGG@l73tc8|K?AG}iXoOvba-Hu?MP71|DzgXSP6cNv&s--F-5(Rt zIdyY}p(E!EGw0ML4Vzo{-dx-Z5#i85Bk+CU+NDbl?@>9tyOSLL zigGbd+S~5zm^-G(-C-4SWw*bk`Jxu1qP!}&%a_ENLuPH|yLn>%j3;2jsxy`nh|gwc4n0xqegD=e$RF)aauO%9i^;1;?_w znIYY=S}xTRVO@TCSz%#|FR8d_moJ$%Mrn@HguyLa!c-jbQd5L4&LWHNL!9C&iw^Lv zg^3^)Z7^18QK%a5UOmqq*q5cH!5Ta{6Qnhvs#t3hXjyYeEn9Ff^Lb>7VwdlhwS)ee z1Kr+=nML`G>D@|$U0LrMO?RRqoGjg>?|zaDhge9oeP|^^5XsOsOJ&4??UWQ*RSp9a zyv3x%4nnYGojdh^EUMgj_O^Yd%))KA`ONKuq6PeqVny(n2VmGa2PS1 z3u7B6u63fL=0(vI9Mt$zD2iIfUI78yWGZ?X8slZWh=Z8J%NQAvu@o{o+}k&!iOY@f zUlC}`TJ_>LR<1a~=}eTE>{{zUm|kGJ!C$eP33 zc`Z9!eBF)*1mb1<66Z08mvKf!#&XDz!E=}hr$k!Jq}KXc<`stsChjL%8JS&8d)WKy zfpGPGGiCr4L;%LV#gRCz>-{PS5fRvtV+FHLQf#~0jmcDdI`*+x>-24WC$_7rA%9<= zNLZPKXVfy+ueldiF;QvKRvcd(6o!crhFwjcL#o

eTNL|XcO2Q(_xL8}e_sA^#HRjNFiWfJAM`e-SIc8S;7W6NPF59LQ<0v(fiw+M+5VTWlw1 zWksW-J;>5w{dK>^?f6?5(licMguf*EIqiz+u&>z&9VWx|_dwWTyUDh$HW%K>7eL!D z8H$y*bQSc>hNRdO=~gdevTYJJj^WoKr0Hy`-2Xmh?}ViFkTh-EOc1%MT!^x90wZYc z>ykzBDm_^KsMNC&{rWNV`CFX#ZSWe;d#$eeM0vs~h&+EGPo2zVIJ>I=)d)G;{v@{^ zMXi(BZJ+6{5x^Gyf}Zp4BRH1RoqwJ43(Y_+w=&=new?{F+v=1G&YX=GihnKP4KM~n zzc*NEiP-ml5PfynCF&Y4)4Z3^3T9L_F;hs#Nd)>On7Z~w&MTiFv)42yl4X4*mEO55sfMhS8j*GG znwP`9Fm;6s`WmV);*We-$Nz zbJZs6>FZqz$L66W{Kb1P8aG8q#8)7xdS=J!#)d^YrW1dzzaB@gT%-LWd@2y|_ zb)6^b7=T}XPKnu9)y-`N<8H?LQwZ79NxYwiaVp+}cvs~)Rr>X5a)ad#LB;#qBz*M? z5eRT3LVF?+%H<}ew3HFbD?@||+MWbIEo6HHU_PCx<8F(T`njLR1^|*I05vaF=x)08 zUFoJ~E-#G6ZMv^+0+qK3k2)u8Zfw*Qw=uw+%ubQnS+q3n)RoskIa~1%13uu0ux@bz zPr}vy9SckHmIu7k3jB2${v8FCfvT!eGXws*C1#7ylV4n#2QPb!rSfO|Ns$igMlomFA>;#DEeI#NQ1d8z28i7g?1KY$bit#tWI9gTWuUqMXX&EON zZTyqH@95|Y9gg~s#?i(ON5}b_Ivia|VMpoc3muO7O@CvDqZQiGgb9gmZ0ZQv6#owI zO#I^us8*-k|ydC4hXxydq{-U?Vg@t<5HNLLtmA?`C8Haam z$Na*=u?qqP(3JsIv+zeKP?=h04eiFaw8+6qWZ>{3Uzoda_QIL-yz>w(h~)5~$Vw(` z=d%ksvvDp)VO~)HbIG`Ub1i>HPKi;=tuLn7PdUZLAJCui51E8^ z*DwB5PqTQ$VM@n$A>aAd=7*(fs+Eae-P$&w&)`zz)^?L5j@-*4Q*Fo12vaRjv-Zul znqYSQ)32=Al|mBUUOHyiacqEli>LE@%a0i0_>2< zU_|DA-j4Ph;L(^R4tGo*i^Z@VAX}erg$-vXpTwMDh4Do@S2HbHU&DAA42{3n7W6@A zvEs_4sgaRr2r<2ue>2_m2XKaew?|TIZ=~ICe<_2~+jM}{O{i}2E&}u{p=pF31GLZG zbQ$4Iq*f5R1CYN3$J(bX_TeNYY1r8)r@inF>ZWb`Z(Lt!!)5zdxHKB5YVzQs*5QAT z2+0PdooV}BC+R28rQuG#Zd>)CYPT}0FK#wGw{TEo#I$0vkw%4KUkwxo}`TD;Vtqzwigd+z--gauvu(Xn!z0}#-7(kIy}0EI zbWPo}n^DA_>9*AJX&vMz4&8pHA#A->gW6`cYpLCBRkYOZ=>S_hz;Fk+w*%bY0Un5e zSxk4#dRe?@vRu!yC5yLIKESzAh?|L_lD*AxE6bKFnFPV~Ga)vUh|1l%+{03TO#!C& z`S{-RP>eI;XHeL7)jmrzcGW(|0!Ke|&j`8!F*2R(v(7`Gshj_UIFoHMAwN74G@KsM zBQzAp4&D&=j5NHQ2g~($Pyym9t<;&uwXX|>6^+X#^ zd@>;?@V%{;x2vflGN$%IY}0z6;W0{qQrQyT^qS?%yRuPKLR+-Z`;kQOYOk1ihZO6w zHtTO%-bT~5b#T6s>`e@FxFV_np6f?DBV^yV3eTl5*79^7f$A4|wXf;i*pq1N9vZtA zDkA>id|&ShRurYD=P)u$}56hn_)LS0fy@wJ%aN$7TAh%V1{PHrWTO zk%a@rjv(KLM!a?11_nftsVY$#9G zLFcK2+WKmYc?H;BMEF|5m9JRy&!ZUF&@00adRZ#HLcwUEaVLFEy>fR6O^t}bDk`FG zTCBRiVAB)fYY96nb^E63zFxO@vksmb!s9t`I->b(Z2OmAhPf~li4^;%Pme+{4u`o6 z=-30JukqLsz6ajU8(Jd|AUIwcVWL_&gdc>w$Z4>bYZYvt^n-zsRm%Y?Y)V*RE(vL96gUXdyZ5!pZW!xm@BzOF7fK{DgyO zYgY7$r$HP3Fm4Pa!im>*VrG&J1J#|8_4Vp4O>QdNDisH?lQb{v>_tl&eKEj^b^uP3tBis+o{I!1! zddL4C>u*};)ct)<-B&Z~KA+a!`+a}S%QpXMzYYC?fBSv$rPD5%cImXsrscf6zTjiJb z@meqH@w(Bc?&&3YWmk9?R^;Ueyv0@CvhtvpFMU}NDDdW0d4tOW-oj$M8^+u5f*dhD zyCi^D*mx^=fb7i=R+gMJ#~Up7=7U`6twQJnWro|EwP3;g1*dzh_tMZ=^%@!#1h+AU z4&vXK;Z?ZeLY8@p=gjfSOM7s(ES;x1MT@aW<@xy~#bf1~!}rRJ$!Gr;OhxpoP9I)y zvUhmZs1q(d-Fsp|pel&h(PRfJ&l)+rY9uq+P|X;yoV=1iWw5lWD2HLqDbFumq5J%F zrOAuvg#zfm;YbdzSZGCbu8JrEDK024a8>_Dh>0i$-T}0CkTWT9U{Dk zC{S6JSE2+O{`qsWj4?`;^=75vRb$a%SBCJ?re%SW3S;zWDI`6jER$FK_`xtYP!@_f zpsX+uqNo8fyDY!F5`7Xx##|XfuepuIJQxK_RcI;RV}$oYd6gRP`~@AfF^En@d0C(= zsB3li>Y(5?MtJLx`ndgBbF#f6^>la2ka)2}D7S-pkl-PPJ8Q}8MQlpPfzB+hswl}@ zMM|~|hMDCd^r?5zwCO{j(mg{)#6lSn9ZWM8Etumy$vek8M5VUXMI8yn$L5NQjDo<@ zP?0fv!VG>%XDrJvmM8W&&lm;8c_s2ZTd2yw_b$QG@`4bO$(^+_k8jQLo=%TDD#lDG zswyt^vZ?p9Q>UDE>S?DAU;Zu;yYLn3@k%e<&>>()2=a?J0To%ymam8 zf5pd`CNJSygqKnobE}G^To_t9!^#Gu0|Hs)k9do`8$EtPm329V&^TTQP0*0rm{wU7 zDn(XR8QFL{SSen3RcW|q!N-meOaF{P|BP80sv74-Cwa$@o8+C~J!Oh$QuRf630QG? zU}Z&KSwWz3<*Ay{Z7e*LFo~uX<{hsLPb5!xz2gk`zas9`(Gf?9UMCmC(Tz#rU-QxC z{ImU!Ilg^D8rEPFpm3$&v-9OdFk@t=?*scA+n(_2%y=*J@nFuh(<%20-2m47?Vxyf9}e zzZS>K`HCWR!m_HUl4%`-*O)&ehqHX5&;4=s#q+gldvj}Yb4{+G-s@ENZ$%ovtUX=xcSaC&g7EC8m zgCGWrm*>qWDMm^fbMq>f2TF3LOv#!&?o_>6=m^*cm-+AHv1} zUP=cU#MJF#K0<8O&7L=H!i344Yx+>zw^`fey;<3ptIN(?9Za1Wz^hl6A;sn)vkdDg z9N-GX9gZgsGXrJCpkcdSY?Kz_EvrZ%tksK)u%pVkGKA?Xh&R*9Q%|aeQ6^7Pl^0@r zUxa;JQK^0;q$H0IM&We9m|a<1P#h}to;G>q%7g9Nnd4K$`rLynqbSV@>TR0GKVx>z zoUEBqEfhE^*LM)DQ^GB|osuo$Qr>_oSDml>Sfev^@2VxbRasny7u&`l7GFVeU{Tb9 zqL_yhMS+>qW*D*Z=ajFAqxiAput-`OnW9xia9uA=gu!Ycix;ibSgw>C)6buSe|}^7 zj5)?^z_VxgjhT!5#+*enCXE|^iWPta)Q zsZ!%*R(W{=4;h$iWkoWZDZVUq{t%hd=H^vhfmkr(FvICuHI*|8YVge~pT-jtBb#%j z<`G!b%q-R$L&b#gqU=%V3>u}tMKcyJB4jLD$eB|S7ltY-N>(X2dtp|GyH79m3DT_N z;k_+a;kpzAm*(|~ZsGBzxIjap6!ZS{G z^xG0vSYC-E(E?1axG~^`1$_5-0bXgH z=yOrP*J+ja`?;Oc6A>3?oi=4!CzZRk{Aw+)S(n})d^h>CDyqEma0WbwXVrN3Hc$-~ zRd6+u&-aO!<>$z0MwA`r75W5g{*L;hLIQQ_f$8nJemkd$QMGUK;Su z3j|k`S6+d;acr}WCLHIXD(~X5E6TX6iibY8pyfuImJuMA;&xGl=0)@0~LoqTjUc;^&Pn}HLZ8X;=Uio;uf=Y z|Hmqsr{Gm^R)fWO$-4$i^YV>A{xXCE>t>vrm&mq02X0iASB|%Cs|HRy3-a=d3v@*U z$10mY4}eiwQ6Nh=Ea)PQ^VJeS;}f9AC|rT22zuzMs}P%t^2*>ixsI3X1i4O>>m;LC zt&XA%nh=dlH1aBp(ki}SUO8hFRuttKg)1i-`OC)Ref;Rh71kgQt~4rFf<8gf$)J1` zS_B-QQy35m3XBe%%rXv!oU_8}s&Tv^ETO6iyiDX}5-*c^IhB_wM)ou#d%BT5!^oa# zWM>)K=NQ?ujBLM=eXfyxo{>Gr$ewFt&oi>KjqL9kF=vP|*!XB{d{zuLB?g-jgH4aY zro~`0jiQqBrFkXebvXfB9@Pt~9ItVUK2hV7ba{#{C#&=8rTAfjf=UCy;tXO0@ZC}+ z1{;5$0H;I7($Xq9-!2DVQALGOiJy2t4@S9;pb5;$9U+-*LMI{c-1fH(2p`tn>PKIjxU(&i7L-r}gR1>*M9Df3|bJbz08m=Q^*Cm$Ny6oaeP1 zW80C*iI;2PJ1se{ADbLY-m#Xp0gf|<;bt=wf<`@nM?nA|_)&Yi59O$b+S^M|{srY0 zl*_lYx4(gM1IkZPKJjC`Z`W=Z4?Wu6J_+R`kF~ciK{@yF_V$%1&v>G}eFMsuo@{Ub z8OpIgZEtTy`8rDe2-(}uw6_mKx#n5uL%HEOJmZOS{C4~uG|IXi?d?B8`QJZlZ+`{l z+l}q*AEIn(Zf{RY!m}HAerXiS*HHRVPQhbu%TWFZPcq+v@&|aL`f-#S@UZ(EC{My4 z*?fxfc9f}3!`Om9I~|Ae4V2j^-$hx0a`*4?7lkON;ExygqU5KyDh%6I3k=&zk8MDz z%Uo}Bc|4#WhksiiY;RX5*NJ%5Z;g=m8So+u@)?FJ*AkmIx3}*hG0k&MTE@BQ-By^@ z#@YSPIC0{zA!PL8-xB=GLf@<<-?TK(4fYw`le20Zjum!TqwKf_RS!Je-Y$(So=c@# zWNbwJk5JzS{TGqphYZsuOkR+i@$ZgD+S?DHjOMZL>yYyys)~^Z_Bc8AzbGF1X`*fx za^&G?IrjU7f%T(M|0e1`i>Ysm*x^V0J;<#aqIJ;UYdUOYetv_zD??sH+v>=3MD(l& z&#a%cx8D<^=gx?pt*GCLdUt$W4Hef6w0j#oTb^ofe>7SKU@!jhHwY&qr~9Lfv7x)N zlfL$b?315vZ@(+rPR9?#NY-=wJcRsT5-r2APz11k5$b>YeB$~b>ifLV-u`7w`_Cfn ze}MWh#ua~uE@GqOW2yIo^bG2s#yES!6;;o?XmUm3xEDMZ<9Vp5V2Q|BCDk$p4xoM& z>dRwvTprPp0pEAyNv#r&DJwVGpG%z)9cO~agXeSiN9)ju$2eSq`c~8@MeDG)N7`S5 z`d9Fj@%J&#BRU+nCXs>dH=_Pj%m+m=@|Q|`FK9nQ{TkHw#dwOeXB<+@h>lk9RNzlQ zId&sFIZ`b;4CoG`zFTztIUV(0)aRi7kJ0t^urSO7&4>DN|JB|eVEyzo&u#YUX&JXV zveLZklBTDPy2a^F8+SvpKW$2lYi^paGHuGVv~knYMomxif)D)D(@gnYqnjXS3FM$# z{`2`y1pX6&|3u(F5%^C8{u6=!MBqOW_!mVWySGm?jnk#2mdjUu;>%fz9HH}Z?OAV7<$`l_)LW- z3l)0^yTaWXe?%`XWvvSu_e%WqQAOm6CA0ce=Spd3*;*}X;crRdVq|1Gv5B;{&;{K`X-D($K{x|{u6A9=~C7{R4wQy5E-xwLU zR>cvP%XItr_$^OBzb*m&R!!H_#1U#YjJtHZ_y+eTpvUta4!7)$x9e!_jo0_jwtv}0 zK2aIpKP3t1@%9}K|7Y93Tia>P`_}#DHwozR_HNP7hg$7>#WNfRk8j`eF#Pe=%k=Y= z7QG@4x9Ew=u;!2Nzt0lT|B`@i=;sjQ<)kH`4^BW&WM?A!ceQ_H0=?rC(5EM$FHAts zO+fD|`xC{pB7xpD3FvhR=yxTcC$j%Xnm@k&(FF8o6409x&|gbHe>(v^-j2iJ{>yyA z5Jvd^5Xdt;d_ssaciBBr*W%&qB5lUtaZG_ca^4F^Rl(iSQAIL;(5KMTlQFTzOU)lzGU;wxl*+` z0spo*y5)~0FTPAPe&YEO;m5iTxhdBtqT}uSVFLQY3Fyxxpud!W{#F9|ZxhfH`5#We z|Mvv+?s=X2J2(M-Yy!GZ)2;lm>|2n4eo+E?qBvOc4p%NsU|(SZ`sE4eWeMn&3Fylc z&<|&Ce0^BUiI3wK3FrqB(BtJ=xP7TlztUR&iXG^V_?-MYdZq*-Y*)M^dVF~DC z6VMasyGip~_o=iv#;~rB&yNEM=qUw0kr2;6AOU?$0{Zj>^a~QuuSh_TbLSv5tlPzp z&;1GL2MIU~!5{E-%JIDf^iG)%LHvLHe8&pSs6wBBHcdEH<5qp5a=PZT#%c9YK4-oq zPX8{ATjSvO8h2@IxzgmsIDRV*XKQ-0C0Li|#PM6z-*tU!wL4GCv+`r1#;y89^M7*)}nb@j(0<@h}f*p&*J6z?o##f^nW&P{e70D zXS2TVT6m(;8pnz1yNZ56TtBpS(S5tC>???~Z?oQ?bd~&LmGkdzpEW*wcjq3Ht0lT0 zT8~lAHCj&fJ;!EGt(N26cx-ZRj?1s+r9R_mKDWln@%=B)yOs}KHNG3-{4?}9oTcYT z%lo@X&XMXn9G^8l4#yW?A3r}orTuEYFE^g`-x@#K{D}AenYe!S<@)|D{O+p$eO~+5 zx;gil{Mr#0ry~^>AMYb=cR0STiqFn?zx4MShtnTlzq^a%ywyc=-tHnf|J6lu;^Xzt z#=9y%TI2k0J<9t>SNnUk^IyCj;duX!avlAbE|Sw#_v?5+yBbflKRi-B|L%Tv)%dX& z`y?c-59J;*G`Wu)y56bfY(5O%A(i|KE4!+HyJ^2I)0>a-e8p*%z(Dgm7adQ~HLn=XKzqmY1#9#ebtUdp%^uiZ|Mv0of4hGJ;>J_%QSLj2#mT8Y%JrM|99d)>9HpGmarStR z@_FcST_h*sPZtAS{e4Wlc@yLO|4)9zM(F?b{IJ#s#uK@*fr-O5AEy3HooB6w;foV{ z5IRfCX?`;Ipt|ouSfJ%>{>h=`ZR;g&%2IV97bc_c$G?+@s|?*8V@@_&%Q-V`6-Kudw2x zxmu6%d4m`wU4R^^fAOl~{kt;Gzvd%cuf)q)-bHe*?jkwWT_mTri{#wgMRIQIA~`?k zB02H-)m3;`<@a52epc(hUpt(g@%g>6i{xzTA~_Fqk(`IRNY0inlJi&>$$7GiMv~uE~PdQpSljFw8(aM?HMRLyRB02NANY43P zB}|$&hjpjW6dAOT6Wd^vqt;Xx-IvZOnOSs8_he8P0n@Np3Tk2CMWV9 z`InAO&druRJC99H}U4#j_8UyHxjsfvFfD4l(j zeA^I?_yK>M8po#r#-v?ceTMu3L>Rkn4SZ{V8D zO2?b5%9u@X09YLTO98t0s%%e^nF9ktcfUiV$7srDF- zVJMT2V<22_qRQj^$vrgZ9l*|~DBCa(5dJC2cB32Jc?@7`1Ay*^<9W8sT#BpXZi4-< zCAb((%t6nA&&BtpCz*pkLSZh2GV}PC0HUqkJb~{_ch4v0ZpOvtE=N1NyAk9hH(vst z?4C?X?qbxYx(DIf!_Ak~_jR8Lc%VB4@bT_R@b3iogP@FYUjWKj_orwz!95N1iSE9j zyl=QKLiO(q_p_+^z;N?d4L&j4C!y|B!)*icdYd~0mYZzue}GtLbMwWE?KbzDAXeKA z$IIX`SI~7=J{o(>KfX_I`1(lma}_B5l!CdRPT9>bNdMCtxF(s?$@phsH@Z!NyiY-p z0J;pj*YPJ%?4G1Fw6-TD%|H{onZ)pdcnb=N`C!yalXRq-eLgTDGdw~bXr$!;wvBop zEv#`OzheO0wy_>{>6Q5H8QY0uus8TUcSDiwB!$iKyhpZ^KaslZ9^+sjn;6OIxb{qC zW#un%{kE?USHl=0S4vKsgJ{^QDaYH-CuI5Q13Y+K#CmNmlf zXn1C|rx>bi*OAfDuxGWhv4+wd4ZBx+{)!pScD+L1SS@zV0IPC-A|P?TUE!<|ysweW zy0lfe*fy~BDH%Ro@yi=>1$AR1>UwVlYTNK6u43Bl42ke}n09xpY4=#RDAP7tmWpYV zX(W$8$kN`XTTiiebfyni#2mu;v28pJ^P5urRIF;@?@;}8tm#Xv<&vWQR9$U&QMO>uZEV&5pDR}&@I9)Jo7Z;Rpi5Hf9pZwDpC z;nPgU2Oea*kqPyB-nP5cyd8godJQa{PS|=fKX~4Dc%jNZd^FTLuI~nL#FYSJXLF7$ zJ)7SOP|xPEQ@GPiHXmb4HC?;x=GZjan+=)Oc5{atMUwdzlvSJN`z$=>{UmzL6Nxn& z<{!vfZ8LWwqSa{gI8)SI3nshS2M#BhwaJiZB%8ehf+>u#Gs=5`_5F7&G zNf{Rt$@`Jx8>n!;Jssc?OcVMRp>G(DVJXOm0c@LW-U~zAj?ZDD>!cq8?zR&b z{!69vsf?Cf!1@s2?zDL?YSK0W=x4ZWDZK|GE6htF!7yLJ)nV;hUX6q}xsa(pf1c@7{@DML;N3HL$7C1ogKnccJ#Rr?%5cIC&mzc68Ic7z$#XKSNEt~u*)yE*DDs$wqmhD67zOz~oa`F+uzj?B z5Xgo(2GVTix1ih2t8jIg_rZoF^G--`n(2U(%|*DnOa~~Y`3|+4pMl~wE5P5)EQg#_ z!$HyR3F{%b=RSZQ_ayeF=jU+JeF_6=cs8P~d$OdL;UJUy)UUwb%XFWa1>WAzl601U zkCJt2HXML{3hLP%A;@r_wwyvm(CHLpcxpj#pCKOg;Y5R5I9c7k^ME*3Q_l2T04AHa z>7s_eMAgp@!M&NJmDvFKH9j&n;FHmMTjqFI5Ts2P2ciZs^$!_s&u7 zyi4f%APOj0M3J7;XkmbUn4U*zcwrr2kLOmxMKm?TvzqX--vRa-4hnJ?_kx_BRPJ|Q z(Mp+;8zm}^90u-E)pI_|FO$yo3?y7mIKxwf^mSJd_Imcw%quBol;@+~fGhU_9_QK6 z9dOlGfTwuMDKp3v@*xf%gO>6ckYw{u1nE|?`8C1WFv>y8+{=rA_k15pJ?@p`;e%%k z4Oqoc8J;I`bzemoW0g$qt5d<#^ITl~?rWbRzc^K`oEpmxT1&F&2`~oNHIc>hAm!9N z2$30{98lb~jJ~t+#}KwDnPUmtmCSMcMY1HrF$JxWZU>E?JA-8 z5R(O~+RVG@#tLm^{}TLuylv%Jsauq}71?Q9r6gx(UPZxIDQtn*OmWKQfuqq=wudQZ z_CO!5hEayh;m5Y|arC&-`Y^RR8uqTvSRwpW<-2w1v$b4f|JTj-sj`EA+tX z%pa2ZQHpUiRIkbWnCN2)-M=RDCboT?qEZ~qpXXAik$E%2{e&XEVi6yPy|yP6akoW$ zjGRAVyc`Xmt%6#`iQi|jA1g>K6_iWL&m?na6S@UYV;`+OUxpG$@+_D2EpW7~K&IEKul zHpP+DuiJ)c#Sda_l)_?BEUP`M@@$O8XHR6#yc^04;g?9I0!SYL!M$R>TUN6zV+I{w^PD8 zsmEX*%sJ9_t46a2&tfOtrqLyXuf%Q2w%*36-rkTqm^TMogN=6wB$#B>^B`eb--sgR zH=rk*oW7-7SS8)k+emo?@UUNUa`;?~e_@ml?eNoHk$Clisv&E^1`ggkp+MQbUu=i^ zA-s3k{$wL35=_*e1Q9{5+QE_3 z@c7nihn%ShoV=16HpBSea2z~h=TJ;)Xa!*tW4lEY_JSZ&z>n=}3TVcha3y>5Q9BhR zHB^Jpk1`(9O?IQnSIp?g?VJ*m8p0sRfPO+O#k{grPa{ui!q32QAr1S9{T6Am2ZS*s zY_)TBk<`!(!dp!9r|cX@Ne%nAUMrK|C>W9A_{N(2B>gf#lQ@l6T}~dslZ+JBb*Hma z0mzK?iNnaOrOzjh1}VkieJdB$nk(OGdajWiV2Weg=ZZLD z8ccT;kvQU2G;%Gwl^}k(&u~>diT26neQD^(5|Qss~#RSp?a<&Ys&4jEGAkReqL8B*ntAyp0;Qss~#RSp?a z<&YsY>X5-TAsv!Ea>(GCbT>WXA%p7_CIUtjEO$*lnQ>Hy46ai{;OSwy&U^)BPaZP3 z&JvJ^46doaX0v3If;@7_;5zLu6e@yFrywJZhYYSW=#km$Au_5%2AA)3Aacmyn%)gO z$z~5+dk@Ej|N3k|W4Ty|3?4aTaLv3FwMs*l(!fIo*EuAcX*^_b%~}SShYa~B-L%Nf zFH_`@!R0@hAP*T_=hgsBHtTQ|y&C}Z;RQsh_sAiGYYva=mBzVBBM%u|^W+rYaIZwI z95T4(-$#.a4Ib*WPh5&aEN(FX(hHrDZ1R{x8chHY)o3{5 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 diff --git a/firmware/host/bin/occmd b/firmware/host/bin/occmd deleted file mode 120000 index 4aeebb9d64..0000000000 --- a/firmware/host/bin/occmd +++ /dev/null @@ -1 +0,0 @@ -occli \ No newline at end of file diff --git a/firmware/host/bin/ocmw_eth b/firmware/host/bin/ocmw_eth deleted file mode 100755 index 0f4cbc8d5727d4ed2ab98d2b190a5bff9a38badf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160296 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%0DrL~OGTdM8a{zlUE)~b9TwlYLt zz8po-@8Yu(?3zu}%x*eMWQk5AFDHUv?B?`}{)p})%`l6p9ZprZ8>{*`NX80c$HI2W z3uAtpPl58IpeH;k+Yx44escM8;<6EhLe(TPH6gl?Wwds<@W_v|G+UWqD~}bDnk+vA z`MjY?u6HX|Rslcxf8P!s1w7};DHyqbnm<28)zQQ@QQeNeg85mBMYyJ*pOA|?Xm&+K zewtR~ZWJ+1hpDdA`H%%j7!YX$G|q>_fVhU)d9o2f`heIDXa}05WgZX@F<^%Mn^2yL zhyC{?Vr_}o{W5l_NfxmvhEC#=hR(hWL+5YMN}(u=7&^IS(qXV}ZkG;Y%s$~*{w7?z z#8c)UMlLq{t*cf;{xT1}kW43uNe(bczeuH6XT+o)7=bkmIc3t@mNdP+$}A|$S`5D@ zSicf6MJ(APOL)=a`TvrkViQBVAuqwuQ-~!Qf*i)C@gp+kvEo?vmzk()+?3Mw;-HIdmYG&B1AEQ9|WxUd?Azs6L3FGfvK{qM#2$z~noy#W#*`%>z?Qk;rG(y60a z?iGB{hkV&1j6DT%A=Q%`$?9aoe>Q4=9y8HOHS4V#si35r$;n=glh=Ts+=!|?)BIox zn8Qdn--M$U#MD_2v3&goGiVKLhJ6T0J!Z0$q(vzQv*%C3qFT6bu$xQU4`DI;cA-bn z4v0(@lmv5=DG;W;63*k@5#d?p(p+_f81>n`*q)XniRcikxV_fE0BRTf%6WjOgth}x zdca8L*W2LRF(|L-5($2MyFezvxq&<5-pybi7vE_%TEhGJTG}YnlryI<) zZxghWD??!w=8b`a@4-^AGKBgJ10k<`0y_rCi~>*gBS;?z2VWT;V(~ZV!qLYSi{Xvx zrs2)j35BL?>h++3LYoUkKV^QCV?-OY9^gq&kiUHcxwjrGqO_;uCx;vK%R*!Vp&Ce# zocT{sl1{V9!z784gG*wgfJm`}BR&Una0mWq?9x9<^cxa<+RThAF?o}X?{bG08Ht(? zZ_2jTRP}k>QB$UDL^qQ+$s41lY^t%+o6uQR=qWi`MBZUh*82 zHPY6sFbCsiFPYpS#wd;av-)bi>Oh*$w8T!~PMlV)RrjHfV`P zu|q8^NMvTu+m^wau7Qk%HPMKwByI9oAH4bR+eosWfR;3(-Ih<2)f*g{RdZ4c?i;2$=RVl^$n!kNyx5TuNyVShD%Xe89MG7(#r zh}Fp$_DP9|&<@d|adArq?R0=yp`Fk3N#p)TAmbG9C_Onno%;sy?`N)rPv>K1c=X6H zZmZS*BFWu|LgNk>IP?tG0#PJ;xr^Cor6wh3utZ6YIkfwlI5)d@G-;4T;@iQ3NztI1 z0`DLZ;8dR$P~SFt^SjVE8sR^|Js}~8j}TMbC!0$yBXTOUYW1&5MLB}zp2QWZ%~`?=`N0CV|CIMFA}C_y@k9 z%6Z1FZ9f`c=Jo79UN^E^K~!5?sW6nn#Kr2D@7|0>)4&_&K0Qu;^uQ?HkXVv$N)?z= zW=xwYuh5h#GNq=OQuah@xE@%dciYPb;n|D!C3|ml8CKKX{$}{nVK{OmWmI8?{=D8g zgq#`lzDp1E=sWv{=wo~Iv3vE__5FIzfIhAazQVfIer${XHk5@Bhy+bY7uzyu@C=3E z>&o3u0t}rF!4vxBuTtqJ$qWvw{+#|4_h4atd9M18i1fX}SE9fKH5#Yj6tjLOm&UCl zW6sxgR83g39Z@k_2T;4#!0jEmB!uK!^;~I*^8(LdLz((wx^a(!w3E*6cG|MYYTPBj zjn1Iu%D=%>Vsqinp2JjZ>rxn2uRg9>7}inb1;UXPC?4oOEXz=qNd)XIjsKo3xhq3- zXQcUsKZ28_=&oS7Wb+Hh!JLjzYX7_Krtf8A<9SamtKE!*pm1XlJt)V=9wjHZksJ%| z-Qj!sF6-@d)AfIa+w7Ds8*X#WA>8JrkU)%fp_20u9>a;92KcU47Am(FYo%D{4LZ z)5FW^oOm+b#zTISv&PwETj|6QoUe!K8g2E?2JZ|#(1;;__}R1E-sSGK$Qz}H+#YBB zrM7Y7kZ037S2}^~Y66ip81e-kwsQhYiu9-IFC9Ot%2nT}2lQ!r$kpI%@Sq^d*~4}` z+2E|J3EN8=&+fL*7dNbMbGy(up{M4E+t!&cui->>D^S3d&^x-k@+e^j!CN;He>6p>JvtqA9CD?-{(lmRc0KR=wTKCL(!RX$0;*l<(bH(T_>kcYTHzPyb z!txE|SiiH-fG4&l<~>g}pkv7!Vc4gpfsp5lOP^yVn5vrBha(SzIOf5=fdcDYAL7~| z774*2&vxvm65N7{cFEdX^ zW?GFGphlti>rjJY1)JKmv`SoTxoj_K#Oi+%K*hyTSsL~xHoMZQ+4E(#hP{7ulB6YT z!?6k&~56%V1naz)%{OUkoTN#~5nJv-;m7n~~Qn z(bcx28^DIRzrD+IFmY!VSAK?~OGVxa^Z1sze+Yd` z-esrGB1fYFRBfIP+}CaNH&+`dp-T-bcQ-|lqxV#(65HE(99#))b&H_V4>Rl|m4Ra(wq4ciCeX$|`fH|#se zK}XLr)R4{D?@kPkO1-eGEg+GZ>EC0ULouD*+0zq0S+#LdCZ;bECXqKZEEm6ZUq;v*e#-e>+mAapNwd(>R@Kk(8j?KO~+S$U}xwW%iDB8`#gPN@`nL zgWZW59>tbXo2nw4JIIM-pm7msWH!K3&{QO|bNvF!XXX0W$V}sUN8;{&44WOQhHOm# z@a+sF)`3K3rZ*W#W@q}O!I=Ihh^H}~pI~~5p@wWTi71X-(nvh}Nj9cGF!=K9Gl@#D zkX6!iGcmmgH46W9o3Vy0eQI(hrVFw%J>EbvyMOv6%4cQzUSy_;>4*J_=@;RUlzHTN zuTou0&U(c|PAz}J*vOmHnw%}%7-qWzi&@6 z_ddsgvNj}`dxZglxeLt9O_9v)M72c9b4+9hqQvj75vD#qe=R5mEEAZc3-ArW%#Jh} z>aJ0Be+|MUm~uniDT3LK_MxH}_Ign9&`1p`j7>9$NW<0H$o-HkMD)VvLPXCZq)%rf z-fR;20@NX*-vJ0p*!~zLwHvhD2pD9r5yiunt7Iu&+lq%rgO-~FhMO_2OUIz+&Za?W z*h1Nh(~ZEBd+?ohB-#rgF%-M;b<8wTqqiAZtax#EsK^_VjF z`vY1K@DmZ=4*HIJ=SI$Yij;|kO&FsP-)ByMUfJcVN%#Dftqq5 ztW)Tk$NmcV9^m&k6@id$GG2!9xkfbcPg;+)kTP4tfEE<{24k zHtXP@q$S6}#5OVSQpaqO%B|E`-@p*>F_Ch_!&I#nlm7Zd)WEc_M{#U7_i(2)6T#Ec z{U9{TKxjl7q0_PL+b@XmL&(=d6rlHV=Y7#j*d^Q1&)r$ zhv4{A>xI2|a{c>Xd?kE!jyE?pCWtch6t$oD0M#DsCI__~N5tpYhX;}O`3A@MXFLgV(wetAsV|y^PUpw zBjs+v7dI#J;*(fwzDd3Z50c|eEkkMoj&6zv?fH053B~Z@j1g#VpN!8!9FJu0r7EKL zp(MQ$!1%QI7QOZK+_~0HXE%1xgXMd3dLX~9H1TaF@okR$0t`TWU31Us3*@DfB9Wmu zNE}zbc~E-oM6W$^1Jf%g2l;RIKvTPjIC=+Z-aAZ+CU%OdNhyaOArGPtycl%6h<#tr z41C=>42KCLqtxNCLE>2iQ}?Wi{v1hF`dJbJ!V=jp-c8F5w+)bXFuCnSA;mDeMZus0Ro$`aZsh zRXqO>517*h1#smEkg)XOc+9$$`cVYZp0>;C|JC6XD5F;(poBeV+Ai+~io^JGw~so=E}?>^u~9Ya?!yi>l~S1`3|^Ta2NJ*A-arIUa+bK|+B~0`T_h z_qUWrS{(Zla$>(9ZR3U>Jj4wTOAaIt(adn{_b!EZKNLDCiqRw9@rOolZJWXPj(sh7 zxx>L6+y(m6aJ~zKw=Y=lU8}kL_SynuZMzTSoo}2?iVo@E#A%b9zYIX_|5` zV@({0?n0T!RSRecQ<#Nj%qbFc6EF=`XjH{ILlvilbaTP4p@^X4Ky108l$}b=HI-^K zmkP^L7wWB!0iG{x|ICZ+VQL(ycj#}Dt+Eh#IKBhI_<1OU^<#kXb_IG`9M7mXf>G~_ zECprqzdVAeGqk07?1UoX&W);M_7>{RrQ~!(j@&Z;kl~K5?GFGm!O};<57{(g|pQ) zgn(^7oVZ4=`Zd;rOZbf|G-c?*Xpbx&>5C}q3}oecPv)%FveAZ;$03{9?W870&Xx@O z9Pj1`rgQmCE#Ur9ra@)9&^1TvPt$2@1>UZWBi(L$z7~BA1fsvEFA_>dW`6uDFmnSF zIwb=$cTn~$WaoKRHXaj9w9-l0)D$hz6r&I>N4B9U*OD?Y;u@QBG`Gp>uRz}+F0B4? zp#ssQr;<&|=O#@>ZgiqTNecCyUt++&Pqk9q&EPOnCfHjCAZ~dW9`gBb$^S)+;5jP|p+h1ZD=3h*BK#^a+=`H| z|Kj7YW68{DNatM6N%ZiELTt?4ouFgjZU=GqyPvc0$Sf6ip>A34H_+ASeu=qaG#9Rd zE8Ym=u}cg^`JgxSk}Q9XppB`#fp7Q{Rs0$hSN`v|{cA{$ay8zg2UgVgQTi?ivN(n1`dLSNG+BqMHyfxF>T11Gg@@7bP z=d$-8Lhq@VE-=-YTND}Qovo1A*We{*v@!LIpVCq3V5H7JGeN3waLnV!D@@-GHqo_5 z%a&E*ptRdhuXI2I{bbWE{!j58_J2k&e7gBf59MM17ZL!xNoZJ$KM&tXOyoqaNKD{F z4kfnvCnKm4Pr3t-q|qWCy$`ClM-&Le0gwjbC`xVhe~DC!|5PL(WsQP>|1<V*(Mp}nd9qqNp*}Y8^2KWyY!|MdmeIzsd6cRSsI?T*`4LoTT{C=0ve&mxo zxP!@A{ru32v@J|6#LHbil}Ht$&e@sxQq!ZE0>>KWeIN26(VyT;Byq~8MZbryq-BoY z4pY%W1RT`>?4jG=|rRCh3UHD&ZDm z1+bZ^WD|6FLf$qLU8Rn>OxNna1nfxtS?{3Nh=9lxMT8u+dKnKrKc#%(70^n6UAx>Z zqqo4dlBEUxR0i7-IXfXTa{fHcd^vIeVvhEZ#bs00?|#f4+y6S+2=8d7whJqmjsLW1 zEm*0sNe4G_MOCljg=u){DCMupmY*x~ujPComLf7M$2%qisXRj6W*Nt*Q5*4_Uf&Rb zl%K6WNhE?Jjhda2{FdD4o75&l!%Zgi)Q?2NX)7c{!?#&Bfl&5_Z?mjPRFr{PZu~aO zHQ8uLW~U@*#Ky^O-i%6BM!;`7JrhQRD%1MBGW7#sMF{1L&Q)+Z(W9Q7m>pcsjCp2(8}jv#I(c9{FcPIUlKa&I zi}46~aHCDe(YH1hBHpt2+)=3LvZIo{#?RybAX0d%UFeslr=fN%Ud0IbJGyLUIfw(1 zfaUo=+9b3AJHbKAhYaliG-!E`<4X{a(zasom`4$nism;Aim~@KH0j@MP9ywW&@vBn zeO);LiyaYuZ(1iWwf}}(F;vS@6K{w9d>6)W8&ncJ@pxbdEgkRLwCTG%<3ieQ%wI^@ z9r)8CvtZnkS#p<4ACV`A(T|ZEJn;`G7PP#;g{}9Hw1bw9aE=qOtl*qKbNn}m8;Fbo z5y2mCAY75cU)(!c3^HvHi5yPS5}X+t}3s6f+gxx0+jO#!WLL=8PKoZ^lm z43bYxm9+PoX}<@IP8;oqco2*H7nqBEEZ-=-41_itXXXR+`bO^-)(a0}df*G3Y~lTx zqPj}1u8gX?QdZY*uFeGvz12bQYJn-^kB7kPs2K!BJMdyP30;Y4LpgvwzLzQ=P%M*n#GLfZ&X9T@rfS9A2f7I$hOC1Wp4l> zx*4@$_n5XMTe1H^ugE2nTZcRXV~f0nVIX2$vt5sT9MF8!;@FAc?=21t0FIAo8@_q{ z&OGmNTq)@M=wZ|`7j<-2pz_F^AH?IteCz_0!s}YCTbqfxc++kZFogZ@2O1%uW3@QC zn%8$-wo1O)xe4@wmKWb5oAaE4(`m%$)7jSmeZCY$ZErxLU}BiJn74Vvgm~Q#*{P0i zUcW2PYYkdvpd5GG35bZoZ7AHyed8k_NAHzntp1rC+m+{;AP`p&B6spVKnytc^1+N% zbnjvk>LQeg&c|0<@Wj`9sk4qoHF&TrC}~oxW~QUtdi%OK$#OFIV@X_q zh-lVF5Wi}c^jbHerNI;Pxh)IvJ$=_LV}h0gZ_2VUM1*jzj3_Do6jWj*u`6L$J>sqZ zq$u`hP@;}E#ZwOLGw|Bx?QzHyrpnKed_tI24=QTcfm(8>JuuMX*q_{EhooUcxNv|2 zj|=Dp6+`JXv5$$=MN;gw+QZ zL|8d(^nPZXFs?OspYM?=ItCI<6~T4%2E4D!!#nJ+;B~|2guZ7kRf$r-fap;1w z*|q`%s{L5%<0&G9v`2y#LG%$=&i0`P5o+a_3=` zqA{V1nw14)&DWodnxJ_<>n^KT_DS)j3o0mptJ z+T;dtC%vyMawcp7$}X6d>%B-1T8ciiLHBlgD382VX#u(eT0BB}t8P)~=O`2#&Bb!O zC&BPe-%h_~L)OPc??!$H09xASez)T@Jb)q&a8g;hAAC|C?Q(-A=%WLFM%1m_H0!o5 zZ0)1U&&U|BR7Z28qFaGYmb#3elW0aN`eS^d=YAF}KR{Y44(!FlAYG8RVvu=@9N2_b ztV=^2NJD&q5U)-{Eb30B_#;9rOha6mhPW1pZOlc&;0xsO$6yj_La~H|f)?K=24&Gp z{ZAM28l5Ju$t0mAaPqm-;PTIcr3T5gr?L0;_e6tJ5PQ=Qe@lpHa0+66I8`z&Kul>c z_3#M2d9Az`Cs^H%xQ0%Sx0H|UoQmR+ng`T0Z8(e>dc;0!cjtGYoXA%oh9UR_l*tWS z9{ocNF1~#VEYn3GWw4yqvJ59C*}yqTey#ttUL6z$-w# zz#9iVo?PJNjDop`2OJ_kzo!*$h&`(71Ub!XtR$l6_obz0UpK+ zIx@xjOP-wKvG1}W=s-nh-rSdh*ZK!esffluX5T>1TUfO!xH zF^~?c)`OZ62UU9FX9b+Lp$pI*tWl)t0KbISIBVpWuhYg9H7x8uC}Vh#O#=;XZSrj* z-C}nP50ue*iYv(cTEs!#;ofbT^miL9U^b@pqCPSRU2ZhuS_HPisOsqZLl{hP?8Or} zpQ64U6lhjIy`LY&C?8&Rny)|S4xEqunxN|Kci6xAFOu&r2}#Up{g9t5D_@B7nnaXa zad?HBBElQ+`@T!H@JkBdzM;4ifZrlsTA)~Gg$9{UIMJRW`C6L6UkG5~^Lswl{*uhX zi|P^#gdpnzOpwqp7|0>0aJ{y zqKyl1HxME@BT+yAjn7I>0Jh0wmjNJ57QU`om~jcgz@n;A3(e#4B^>z_q%jc8IYL>r zmgVaFye6MMzjQCgFz1nySOXGxSHI|h^XLZN&g~1qR)~}!<`?&a@8pXF$hZC9vFeo= zM`-P5si26kYTYM1m2y>{6Qp%3?`-`Vdi04se;~1=WhCM2gbUC43UgDsk`pQX4x@8V zfI{hjf~w>QiW6Mp;;OIE2=M5a(m|*0N_1*qZvcD<6kr`$|(aKVfTf> z2X#_MuZTr?E8<%KM9^jPu`0%l7SG&j7Fv|csl*m2AJd|5WX0l%#NCYL9YNzSI$DbZ zvvU#0iW&y&_!l+S@h=+cMiD6?MX%2qD*qSK7;_OrM{@KA3KBEEWf;Ia(4Z}Rf3v;C z@k`9@dSoMzfi(qw_>I%*?qb-{Pw7sY$3zx`D_VhI?*jK0y0LfB?RXA<&*Sd}{Jn_3 zmoVG5toWOaN@4q`JP~vK*+w7|AQo05JD1R$>(hJGoaU-nB1%(Zssd)0BY6OAd9svc0j)sB#Pcs zgi2r-&$l?9L$H_aV{hzi0&)C#VJkG_Y4PT}o^blzTI-d;EaZ?nJ~%#1F|5q~7+zGxpA6Uj+jsOU?I zxkRdo&bNVq9ML3hj`a?o04JJ6EsfpCq@>8-0q0qp^{)Uo>+~9H$niY3%zh6Mr?!mS zLvYo+RH@$=n`zJt){Jxw7RY3E=wN{|{HzZc2gi72MS*C9aDl^UzDEUcVK7mE49ExB z03Uaa2_JG2_)YMuvGJk=?-X$jFj*f=7Wnw#L&9e(C)@nuAk)VhEq4gu?O1C)*HV@z zqc64K4Qd44R{neDQeeE;QZ^J|VY6^=iwH-|&cl&b2n;u@+V$2ep}AeM|GgYJk)*5& z!O)!o4+?F9l_&7&C+60*5UM5b0~-`t+Rpu0&id~aR0gQ4e0CSkLSWA7*SN$B2TcBN zFZ>@i?Qn%=3+}nW-}S;8$V!j_fv5OAbgMVW^j^c?>-hVF^n_QkfzX{5>@BH_YIkw3 zwtVw_Fq!mCXELfqCuq=8EHkBVT1-X4mZ^Z!Cu|v$h+T&LfBLWqD1W&N4eWpc#G|K5 z7h-mgyI4-brJ=Uh{+#Ob9tA>lt?24qB(i=`6uzztLg-8Sx|5MX_HeO4mcDKa`#PX; zC+v;>i#QZlrs$pyTann83Zo_}zgu9SJUh89!q)*&_DL83Ol=s<>=_V1Hkn#KvZp~I zkyry$_jTb0csMdgF-v!}beumMU180g+%LzYTfR2fW$e<8Je_xJfeij2`qvipuQz1>BJk_n zzbtuuWJIM~O!iMQ0ds8scgXpTFnPMyxddZA+dL*Q9f7?qjwe#b_-@BruvqL6|b5}<{nXb2g_{=<65Xfd5)sgtZLU~^G^ zE51qB4N}*q_=HM!I4OVDR!gT{jiKBcJ7Vrn1-6eS`oh$I zdmG3l9nCSK1Z0Z=qa$p&@(r;A7rWTVehK�_BzlCHr2`Lb2gt%LyokGjxp$!KzP7 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

<4P-H>Ipp}Z5fI2^t46yC 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 diff --git a/firmware/host/log.txt b/firmware/host/log.txt deleted file mode 100644 index 92ead9277f..0000000000 --- a/firmware/host/log.txt +++ /dev/null @@ -1,67 +0,0 @@ -In file included from ./include/ocmw_schema.h:2:0, - from ocmw/ocmw_schema.c:1: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: -ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] - ecMsgFrame.message = ecCoreMsg; - ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ -In file included from ./include/ocmw_schema.h:2:0, - from ocmw/ocmw_schema.c:1: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: -ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] - ecMsgFrame.message = ecCoreMsg; - ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ -In file included from ./include/ocmw_schema.h:2:0, - from ocmw/ocmw_schema.c:1: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: -ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] - ecMsgFrame.message = ecCoreMsg; - ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ -In file included from occli/occli_ocmw_comm.c:26:0: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -In file included from occli/occli_main.c:24:0: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -In file included from occli/occli_helpMenu.c:4:0: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -In file included from ./include/ocmw_schema.h:2:0, - from ocmw/ocmw_schema.c:1: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -ocwdg/ocwdg_daemon.c: In function ‘ocwdg_thread_comm_with_ec’: -ocwdg/ocwdg_daemon.c:92:28: warning: ‘ecCoreMsg’ may be used uninitialized in this function [-Wmaybe-uninitialized] - ecMsgFrame.message = ecCoreMsg; - ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ -In file included from ./include/ocware_stub_main_module.h:16:0, - from ocwarestub/ocware_stub_database.c:10: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -In file included from ocwarestub/ocware_stub_parse_message.c:10:0: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -In file included from ./include/ocware_stub_main_module.h:16:0, - from ocwarestub/ocware_stub_main_module.c:9: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ -In file included from ./include/ocware_stub_main_module.h:16:0, - from ocwarestub/ocware_stub_eth_comm.c:2: -./include/occli_common.h:178:20: warning: inline function ‘ocmw_free_global_pointer’ declared but never defined - extern inline void ocmw_free_global_pointer(void **ptr); - ^~~~~~~~~~~~~~~~~~~~~~~~ From 696d41f1156e152abfed92b83d1ca390993731d6 Mon Sep 17 00:00:00 2001 From: mdlewisfb Date: Wed, 24 Oct 2018 08:00:11 -0700 Subject: [PATCH 3/3] Copying host file updates from OCWare repo --- firmware/host/include/occli_common.h | 3 +-- firmware/host/ocwdg/ocwdg_daemon.c | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/firmware/host/include/occli_common.h b/firmware/host/include/occli_common.h index e6532403d6..b6527d5526 100644 --- a/firmware/host/include/occli_common.h +++ b/firmware/host/include/occli_common.h @@ -175,8 +175,7 @@ int32_t ocmw_frame_postTable_from_schema(const Component *root); * * @return NONE */ -inline void ocmw_free_global_pointer(void **ptr); - +extern inline void ocmw_free_global_pointer(void **ptr); /* * @param root an output value (by pointer) * @param systemInfo an output value (by pointer) diff --git a/firmware/host/ocwdg/ocwdg_daemon.c b/firmware/host/ocwdg/ocwdg_daemon.c index 21a256d237..50d2050eac 100644 --- a/firmware/host/ocwdg/ocwdg_daemon.c +++ b/firmware/host/ocwdg/ocwdg_daemon.c @@ -81,12 +81,10 @@ void * ocwdg_thread_comm_with_ec(void *pthreadData) ecMsgHeader.ocmpTimestamp = OCWDG_NUMBER_ZERO; /* Frame the Core packet for sending data to ec */ - /*ecCoreMsg.action = OCMP_AXN_TYPE_REPLY; - ecCoreMsg.msgtype = WATCHDOG; - ecCoreMsg.componentID = WD; - ecCoreMsg.parameters = OCWDG_NUMBER_ZERO; - ecCoreMsg.subsystem = WD; -*/ + ecCoreMsg.action = OCMP_AXN_TYPE_REPLY; + ecCoreMsg.msgtype = OCMP_MSG_TYPE_WATCHDOG; + ecCoreMsg.parameters = 0; + /* Construct the final packet */ ecMsgFrame.header = ecMsgHeader; ecMsgFrame.message = ecCoreMsg;

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 diff --git a/firmware/host/bin/ocmw_uart b/firmware/host/bin/ocmw_uart deleted file mode 100755 index 60ff52323f081bb4dee190da922247b8b8e172a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160168 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 z z11rlKk>3(EVzdpG6iS24yc!TtD1KO!~Z z#Q>Bh&k@TdAS^W7(Tmdnfd&R)VI;a3ItmJO7QW?_Dp)b&PT!^4ZQ+#w^)e!?q0Xpv zgsEBVZjrk&)acZM<196?oXLYJPE93l)F?0mbb|{NE96!sbSMXu60^_y0kWBaG>P~a zeo~Eb@urp#cr2zYVy4{t<|V4U*ee@DYaFeIBWgkZ_i*BI=;fYQ;Hn z8V;dog*A?B*(#z*c2d@Bc;QQ!Cuh#%LNzoV7fO_K?!_hIUpNsW^5K;mVNASe7-QzK z?~6c?$#N&{0=*JLtdk_|FwbUO?}+HBRlFOjlN;#+4IwrNr{gTlq;*8kQfj4>+wdC| zsv#|-w;XIa@Wva}ng(+Y_IcufBxlCKjjcp(bhc26GNBPFsT%xuG;kiB^nQd_XgsDK zI9aEW!QH690!a)^1kNV8WP+Ahv1amd5rtM;`h3|}8TH^jXf^`@rJMWh!BpX;n58lZP2Dddr%q_Dql zErJZ(@rJ7+vaW$4{`7G!!V&Jt^wD6F;?4ER<2N+J>Ixor>Lo>Qw7&~WOAW+s)jJ%Q zQ-4EW`mFW;=L?T%4Lw4(`$on$CUJ%H@d~_}ulzsyxY+})#xEQJ^U^PDOybHQ-Uok~ zUitF=+WkZp7{HHU`qsuI-)d?4ZG7ebiKd^#t)D;te9g*#@5Uq(-y4zN?$5IOQ<(^V zX7P{qO4;4Yvgs^(UnISaWN z9BKxZoOR`0;Kw@tk^ENwcHiAGO~2c2+yV`Kdik&a=YISQrnhlnzI;|_-e(zWl88FY zUq;d|K9OX~#U~`eS)2n4eysgl>@g7YJpCf+DKGkbAOFbqY@J7bE45(q7sn{SW7b z@=!gWNGL!4*lr KJCY!BY5p(uDy>NX diff --git a/firmware/host/bin/ocmw_usb b/firmware/host/bin/ocmw_usb deleted file mode 100755 index 158dbffa20671a009f658e5b4a2ed2d8cc80fe54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160168 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 NE0TV9BthiT{9nA-o{j(j diff --git a/firmware/host/bin/ocware_stub b/firmware/host/bin/ocware_stub deleted file mode 100755 index 05aae2a6681f6d8caa30a1ab80203f069bb14d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87632 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�rLOv`#YLxCdhN(+WKym%xmR(=^RO?jnj%X6?&v6 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 literal 0 HcmV?d00001 diff --git a/firmware/host/bin/ocmw_uart b/firmware/host/bin/ocmw_uart new file mode 100755 index 0000000000000000000000000000000000000000..60ff52323f081bb4dee190da922247b8b8e172a5 GIT binary patch literal 160168 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 z z11rlKk>3(EVzdpG6iS24yc!TtD1KO!~Z z#Q>Bh&k@TdAS^W7(Tmdnfd&R)VI;a3ItmJO7QW?_Dp)b&PT!^4ZQ+#w^)e!?q0Xpv zgsEBVZjrk&)acZM<196?oXLYJPE93l)F?0mbb|{NE96!sbSMXu60^_y0kWBaG>P~a zeo~Eb@urp#cr2zYVy4{t<|V4U*ee@DYaFeIBWgkZ_i*BI=;fYQ;Hn z8V;dog*A?B*(#z*c2d@Bc;QQ!Cuh#%LNzoV7fO_K?!_hIUpNsW^5K;mVNASe7-QzK z?~6c?$#N&{0=*JLtdk_|FwbUO?}+HBRlFOjlN;#+4IwrNr{gTlq;*8kQfj4>+wdC| zsv#|-w;XIa@Wva}ng(+Y_IcufBxlCKjjcp(bhc26GNBPFsT%xuG;kiB^nQd_XgsDK zI9aEW!QH690!a)^1kNV8WP+Ahv1amd5rtM;`h3|}8TH^jXf^`@rJMWh!BpX;n58lZP2Dddr%q_Dql zErJZ(@rJ7+vaW$4{`7G!!V&Jt^wD6F;?4ER<2N+J>Ixor>Lo>Qw7&~WOAW+s)jJ%Q zQ-4EW`mFW;=L?T%4Lw4(`$on$CUJ%H@d~_}ulzsyxY+})#xEQJ^U^PDOybHQ-Uok~ zUitF=+WkZp7{HHU`qsuI-)d?4ZG7ebiKd^#t)D;te9g*#@5Uq(-y4zN?$5IOQ<(^V zX7P{qO4;4Yvgs^(UnISaWN z9BKxZoOR`0;Kw@tk^ENwcHiAGO~2c2+yV`Kdik&a=YISQrnhlnzI;|_-e(zWl88FY zUq;d|K9OX~#U~`eS)2n4eysgl>@g7YJpCf+DKGkbAOFbqY@J7bE45(q7sn{SW7b z@=!gWNGL!4*lr KJCY!BY5p(uDy>NX literal 0 HcmV?d00001 diff --git a/firmware/host/bin/ocmw_usb b/firmware/host/bin/ocmw_usb new file mode 100755 index 0000000000000000000000000000000000000000..158dbffa20671a009f658e5b4a2ed2d8cc80fe54 GIT binary patch literal 160168 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 NE0TV9BthiT{9nA-o{j(j literal 0 HcmV?d00001 diff --git a/firmware/host/bin/ocware_stub b/firmware/host/bin/ocware_stub new file mode 100755 index 0000000000000000000000000000000000000000..05aae2a6681f6d8caa30a1ab80203f069bb14d5e GIT binary patch literal 87632 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�rLOv`#YLxCdhN(+WKym%xmR(=^RO?jnj%X6?&v6 z#BYgff1k{2ueKU$UNs!!M`3iZ~XXUO`ex-Qk^7%TZ`dT8>T zuY-?YuXaj%UKmHO+2Lx5*Y@2t{&VB#HT=o0Z?$@PlAq=ur82LT>!mkII?X?t?yO)^ zzr<^CbGROZe(<;J$Z@w0{_8sUZ|mSU>);>P!RzhcY}KLfM?Gc20!J)KUR*x5R5v$0 zj!(rY^0_LGPrIDQbQ}H`7wD}&a^vJYRWS-RJ}ni@qFwHv#q+bbit>2;zdEmd|4M78 zUCz5&UN6Rvj*Dmi*28;jc^7&7fPa7ZhyDLsh)jHV^ z9jD3XcFCt=-Ra4*R`ZK{PLI#s8Xsw$4tc+Ivc~#q93RKOIqqum57zi@i_=e$`*2!2 z15F^glX(s{RqL|I=~(>X7?`|8C_6tAC%9 z`gLqLz5d-9XQzSMC*Ixzt=AvjVA*GHyk7FTMt|+cmme4;KCccEpVtS8&u<5bPrSYU z)%n5lkIp##J5O=`7;Jq{HU7oR(G{=XDXybG86-Y~HDAZ;IoNr<`@?~@^PjHgV2vN+ z^$s>k$JZ-PXd1^iPh4)6e46^9J7FXLhlPXHze!SWP4tda++We^4_11*{vRK|I^_Am zla+6)#kVR>*p%bjCoUhRjhlYxPS^+vN5=V~9(~0FvGV+@)_;2K zYxwwaW7pYV)9C-N)6?~j|JTRQ|Lgi?#*L?nQ@rmO7ssdR6xVOsIkLz&I7L1aobmp>X^{AA9wa^w4-%ip28qv>LE`g+LE`h|An|!>koY`3 zNPM0fBtAO^iO=(c#HVAB_`EnseEN$Ir&~T)@onEJ>KiZr>x0B6p6{vV2g^Qh|A*pCyCDM~fe)n+{g|Sta%A*ivy?B0VMJM*9y=kIx-ao~CW5$LCJTr~RqZ z<8!wr&yP-zPvkxEPoEwi?Y;gL&zv3~WspAeva>I5_>v!kn9Z zfygTtqbczZGPIY+&ALp`KOVnlA!`bH58hBG_`h|zpg%+V zj$d30f`05-8vQ@67WBW=p{G~b8I_^uYV>jJlw?RMs;Y(}3tqWbWmS}o_+njOiW;X7 zx7TOmYEmte@p=lAL7jnb<(Z6@q#;NWEHi*K{uVq;Y~< zWvFTV6cQ$kzLmh6Ay2}XuM+4+>j{}Z0ElKU1WBTr1+7%$HeAi4s)@!1P0XX43H%&# zo5!>Rv>FnpuK|s%5*LH53hrdIt;E%2qnD;9D8~CxEpav#gEr??qFoJ?!Db|D+KQRh z1x$kNOeko!-3eh6ZQp@J7F!C)RhtcXt75#3HWuxt z+G+u(***iGp*9C<4O5bm65GB8y5w(@fE(waNJ*Xn=80b;*pQqKMB;s94P)}#=!?X! zF92*x{u!z#euH3(V%!M6iQgpQlTs2l{gwE=La6TuejgC+gM!})%tHihhKunfNysqJ$RDYj*h$zXd1CNkQ_0%5Y9O)g@afeL2ZD!_@h#gNrvdl{8f z+d9|*U33FPwwz6`*-x@s#{LE=YiBt}Xm=D=v79TkdmSxU#u02xegTA*^MrOcqXo