/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _AT_COMMAND_H_ #define _AT_COMMAND_H_ #include #include #include #include #include "atr_config.h" #include "at_param.h" #include "osi_compiler.h" #include "quec_proj_config.h" #include "quec_atc_common.h" #include "quec_at_param.h" #ifdef __cplusplus extern "C" { #endif struct atCommand; struct atCmdEngine; struct osiEvent; #define AT_CMD_RETURN(r) OSI_DO_WHILE0(r; return;) #define AT_CFW_UTI_INVALID 0xff /** * \brief AT command type * * set: AT+CMD=1 * exe: AT+CMD * read: AT+CMD? * test: AT+CMD=? */ #ifndef CONFIG_QUEC_PROJECT_FEATURE_ATC_PARSE typedef enum { AT_CMD_SET, AT_CMD_TEST, AT_CMD_READ, AT_CMD_EXE } atCmdType_t; #endif /** * \brief AT command constrain * * Some AT commands are valid only when certain conditions are meet. * Each required condition is defined as a constrain. * * For each AT command, zero or more contrains can be declared. Only * when all contrains are meet, \p cmd->desc->handler will be called. * The constrain check is performed inside \p atCommandCheckConstrains. */ enum { AT_CONSTRAINT_NONE = 0, ///< no constrain AT_CON_CALIB_MODE = (1 << 0), ///< only in calibration mode, not in normal mode AT_CON_NOT_CALIB_MODE = (1 << 1), ///< only in normal mode, not in calibration mode AT_CON_NOT_CLAC = (1 << 2), ///< ignore in CLAC }; /** * \brief AT command description */ typedef struct atCmdDesc { const char *name; ///< AT command name, such as "+IPR" void (*handler)(struct atCommand *); ///< At command handler uint32_t constrains; ///< AT command constrains } atCmdDesc_t; /** * \brief function prototype to delete async context */ typedef void (*atCommandAsyncCtxDestroy_t)(struct atCommand *cmd); typedef SLIST_ENTRY(atCommand) atCommandIter_t; typedef SLIST_HEAD(atCommandHead, atCommand) atCommandHead_t; /** * \brief AT command context data struct * * AT engine will parse a whole command line, and put all commands in the * command line into a list. So, all commands are located on a list. * * Each AT command is bind to an AT command engine, which receives the * AT command. * * AT command can be executed asynchronously. For example, an event will be * sent to another thread, and then return. After a response event is * received, the command will be finished. \p async_ctx is a placeholder * for asynchronous context. \p async_ctx_destroy will be called to delete * \p async_ctx by AT command engine. It is not needed to delete \p async_ctx * by command handler explicitly. */ #ifdef CONFIG_QUEC_PROJECT_FEATURE_ATC_PARSE #include "quec_at_engine.h" typedef struct ql_at_cmd atCommand_t; #define atCommandAsyncCtxFree quec_at_async_param_free #else typedef struct atCommand { atCommandIter_t iter; const atCmdDesc_t *desc; struct atCmdEngine *engine; atCmdType_t type; uint8_t param_count; atCmdParam_t *params[CONFIG_ATR_CMD_PARAM_MAX]; uint16_t uti; void *async_ctx; atCommandAsyncCtxDestroy_t async_ctx_destroy; } atCommand_t; /** * \brief AT command description count * * AT command decriptions are stored in a global array. This will return * the count. * * \return AT command description count */ size_t atCommandDescCount(void); /** * \brief AT command description by index * * The index is the index for internal global AT command description * array. * * \param n AT command decription index * \return * - AT command description * - NULL is \p n is invalid */ const atCmdDesc_t *atCommandDescByIndex(size_t n); /** * \brief search AT command description by name * * The search is case insensitive. * * The terminating \0 is not needed in \p name, however \p length parameter * is required. It is designed to permit sub-string parameter without string * copy. * * \param name AT command name * \param length AT command name length * \return * - AT command description * - NULL is \p n is invalid */ const atCmdDesc_t *atCommandSearchDesc(const char *name, size_t length); /** * \brief check AT command constrains * * It is called by AT command engine. Only when it returns true, * \p cmd->desc->handler will be called. So, when it returns false, final * response should be called inside. * * \param cmd AT command, must be valid * \return * - true if the command is permitted * - false if the command is not permitted, and final response will be * called inside. */ bool atCommandCheckConstrains(atCommand_t *cmd); /** * \brief delete an AT command * * It should be called inside AT command engine only. * * When \p cmd is NULL, nothing will be done. * * \param cmd AT command, must be valid */ void atCommandDestroy(atCommand_t *cmd); /** * \brief delete all AT commands in the command line * * It should be called inside AT command engine only. * * \p cmd_list itself must be a valid pointer for list head. * * \param cmd_list AT command list */ void atCommandDestroyAll(atCommandHead_t *cmd_list); /** * \brief default dtor of AT command async context * * When \p cmd->asynx_ctx is a plain memory pointer, this can be set to * \p cmd->async_ctx_destroy. * * \param cmd AT command, must be valid */ void atCommandAsyncCtxFree(atCommand_t *cmd); #endif #ifdef __cplusplus } #endif #endif