asterisk-chan-dongle/at_queue.h

114 lines
5.0 KiB
C
Raw Normal View History

2023-05-25 08:30:27 +00:00
/*
Copyright (C) 2010 bg <bg_one@mail.ru>
*/
#ifndef CHAN_DONGLE_AT_CMD_QUEUE_H_INCLUDED
#define CHAN_DONGLE_AT_CMD_QUEUE_H_INCLUDED
#include <sys/time.h> /* struct timeval */
#include <asterisk.h>
#include <asterisk/linkedlists.h> /* AST_LIST_ENTRY */
#include "at_command.h" /* at_cmd_t */
#include "at_response.h" /* at_res_t */
#include "export.h" /* EXPORT_DECL EXPORT_DEF */
typedef struct at_queue_cmd
{
at_cmd_t cmd; /*!< command code */
at_res_t res; /*!< expected response code, can be RES_OK, RES_CMGR, RES_SMS_PROMPT */
unsigned flags; /*!< flags */
#define ATQ_CMD_FLAG_DEFAULT 0x00 /*!< empty flags */
#define ATQ_CMD_FLAG_STATIC 0x01 /*!< data is static no try deallocate */
#define ATQ_CMD_FLAG_IGNORE 0x02 /*!< ignore response non match condition */
#define ATQ_CMD_FLAG_SUPPRESS_ERROR 0x04 /*!< don't print error message if command fails */
struct timeval timeout; /*!< timeout value, started at time when command actually written on device */
#define ATQ_CMD_TIMEOUT_SHORT 1 /*!< timeout value 1 sec */
#define ATQ_CMD_TIMEOUT_MEDIUM 5 /*!< timeout value 5 sec */
#define ATQ_CMD_TIMEOUT_LONG 40 /*!< timeout value 40 sec */
char* data; /*!< command and data to send in device */
unsigned length; /*!< data length */
} at_queue_cmd_t;
/* initializers */
#define ATQ_CMD_INIT_STF(e,icmd,iflags,idata) do { \
(e).cmd = (icmd); \
(e).res = RES_OK; \
(e).flags = iflags | ATQ_CMD_FLAG_STATIC; \
(e).timeout.tv_sec = ATQ_CMD_TIMEOUT_MEDIUM; \
(e).timeout.tv_usec = 0; \
(e).data = (char*)(idata); \
(e).length = STRLEN(idata); \
} while(0)
#define ATQ_CMD_INIT_ST(e,icmd,idata) ATQ_CMD_INIT_STF(e, icmd, ATQ_CMD_FLAG_DEFAULT, idata)
#define ATQ_CMD_INIT_DYNF(e,icmd,iflags) do { \
(e).cmd = (icmd); \
(e).res = RES_OK; \
(e).flags = iflags & ~ATQ_CMD_FLAG_STATIC; \
(e).timeout.tv_sec = ATQ_CMD_TIMEOUT_MEDIUM; \
(e).timeout.tv_usec = 0; \
} while(0)
#define ATQ_CMD_INIT_DYN(e,icmd) ATQ_CMD_INIT_DYNF(e, icmd, ATQ_CMD_FLAG_DEFAULT)
#define ATQ_CMD_INIT_DYNI(e,icmd) ATQ_CMD_INIT_DYNF(e, icmd, ATQ_CMD_FLAG_IGNORE)
/* static initializers */
#define ATQ_CMD_DECLARE_STFT(cmd,res,data,flags,s,u) { (cmd), (res), ATQ_CMD_FLAG_STATIC|flags, {(s), (u)}, (char*)(data), STRLEN(data) }
#define ATQ_CMD_DECLARE_STF(cmd,res,data,flags) ATQ_CMD_DECLARE_STFT(cmd, res, data, flags, ATQ_CMD_TIMEOUT_MEDIUM, 0)
//#define ATQ_CMD_DECLARE_STF(cmd,res,data,flags) { (cmd), (res), ATQ_CMD_FLAG_STATIC|flags, {ATQ_CMD_TIMEOUT_MEDIUM, 0}, (char*)(data), STRLEN(data) }
#define ATQ_CMD_DECLARE_ST(cmd,data) ATQ_CMD_DECLARE_STF(cmd, RES_OK, data, ATQ_CMD_FLAG_DEFAULT)
#define ATQ_CMD_DECLARE_STI(cmd,data) ATQ_CMD_DECLARE_STF(cmd, RES_OK, data, ATQ_CMD_FLAG_IGNORE)
#define ATQ_CMD_DECLARE_STIT(cmd,data,s,u) ATQ_CMD_DECLARE_STFT(cmd, RES_OK, data, ATQ_CMD_FLAG_IGNORE,s,u)
#define ATQ_CMD_DECLARE_DYNFT(cmd,res,flags,s,u) { (cmd), (res), flags & ~ATQ_CMD_FLAG_STATIC, {(s), (u)}, 0, 0 }
#define ATQ_CMD_DECLARE_DYNF(cmd,res,flags) ATQ_CMD_DECLARE_DYNFT(cmd,res,flags,ATQ_CMD_TIMEOUT_MEDIUM, 0)
//#define ATQ_CMD_DECLARE_DYNF(cmd,res,flags) { (cmd), (res), flags & ~ATQ_CMD_FLAG_STATIC, {ATQ_CMD_TIMEOUT_MEDIUM, 0}, 0, 0 }
#define ATQ_CMD_DECLARE_DYN(cmd) ATQ_CMD_DECLARE_DYNF(cmd, RES_OK, ATQ_CMD_FLAG_DEFAULT)
#define ATQ_CMD_DECLARE_DYNI(cmd) ATQ_CMD_DECLARE_DYNF(cmd, RES_OK, ATQ_CMD_FLAG_IGNORE)
#define ATQ_CMD_DECLARE_DYNIT(cmd,s,u) ATQ_CMD_DECLARE_DYNFT(cmd, RES_OK, ATQ_CMD_FLAG_IGNORE,s,u)
#define ATQ_CMD_DECLARE_DYN2(cmd,res) ATQ_CMD_DECLARE_DYNF(cmd, res, ATQ_CMD_FLAG_DEFAULT)
typedef struct at_queue_task
{
AST_LIST_ENTRY (at_queue_task) entry;
unsigned cmdsno;
unsigned cindex;
struct cpvt* cpvt;
int uid;
at_queue_cmd_t cmds[0]; /* this field must be last */
} at_queue_task_t;
EXPORT_DECL int at_queue_insert_const (struct cpvt * cpvt, const at_queue_cmd_t * cmds, unsigned cmdsno, int athead);
EXPORT_DECL int at_queue_insert (struct cpvt * cpvt, at_queue_cmd_t * cmds, unsigned cmdsno, int athead);
EXPORT_DECL int at_queue_insert_uid (struct cpvt * cpvt, at_queue_cmd_t * cmds, unsigned cmdsno, int athead, int uid);
EXPORT_DECL void at_queue_handle_result (struct pvt * pvt, at_res_t res);
EXPORT_DECL void at_queue_flush (struct pvt * pvt);
EXPORT_DECL const at_queue_task_t * at_queue_head_task (const struct pvt * pvt);
EXPORT_DECL const at_queue_cmd_t * at_queue_head_cmd(const struct pvt * pvt);
EXPORT_DECL int at_queue_timeout(const struct pvt * pvt);
EXPORT_DECL int at_queue_run (struct pvt * pvt);
INLINE_DECL at_cmd_suppress_error_t at_cmd_suppress_error_mode(int flags)
{
return ((flags & ATQ_CMD_FLAG_SUPPRESS_ERROR) ? SUPPRESS_ERROR_ENABLED : SUPPRESS_ERROR_DISABLED);
}
static inline const at_queue_cmd_t * at_queue_task_cmd (const at_queue_task_t * task)
{
return task ? &task->cmds[task->cindex] : NULL;
}
/* direct device write, dangerouse */
/* TODO: move */
EXPORT_DECL int at_write (struct pvt * pvt, const char * buf, size_t count);
EXPORT_DECL size_t write_all (int fd, const char * buf, size_t count);
#endif /* CHAN_DONGLE_AT_CMD_QUEUE_H_INCLUDED */