#ifndef __ATCMD_H
#define __ATCMD_H

#include <termios.h>
#include <stdarg.h>
#include <stddef.h>

#ifdef __ATCMD_C
#define ATCMD_EXTERN
#else
#define ATCMD_EXTERN extern
#endif

#define CONTROL_Z			0x1A
#define CONTROL_Z_STR			"\x1A"

#define ATCMD_EOL			"\r"
#define ATCMD_RESPONSE_EOL		"\r\n"

#define ATCMD_LINE_SIZE			1024

struct baud_map {
	speed_t baud;
	speed_t value;
};

speed_t value_to_baud(speed_t value);

int rts_get(int fd);
int dtr_get(int fd);
int cts_get(int fd);
int dsr_get(int fd);
int cd_get(int fd);
int ri_get(int fd);
int line_signal_set(int fd, int signal, int value);
int rts_set(int fd, int value);
int dtr_set(int fd, int value);

int tty_configure(int fd, speed_t baud_rate);
int tty_open(const char *dev, speed_t baud_rate);
int tty_close(int tty);
int tty_set_read_timeout(int fd, int timeout);


int atcmd_read_until(int fd, char *buf, size_t len, const char *stop);
int atcmd_readline(int fd, char *buf, size_t len);
int atcmd_expect_line(int fd, char *buf, size_t len, const char *expect);

int atcmd_write(int fd, const char *buf, size_t len);
int atcmd_write_str(int fd, const char *buf);
int atcmd_vprintf(int fd, char *fmt, va_list ap);
int atcmd_printf(int fd, char *fmt, ...);
int atcmd_writeline(int fd, char *fmt, ...);

char *atcmd_value_tok(char **str);
char *atcmd_response_brk(char **str);

typedef int (*atcmd_response_callback_t)(char *buf, size_t len, void *prv);
int atcmd_response_foreach_line(int fd, atcmd_response_callback_t call, void *prv);

int atcmd_e_write(int fd, int mode);
int atcmd_v_write(int fd, int mode);
int atcmd_q_write(int fd, int mode);
int atcmd_plus_cmgf_write(int fd, int mode);
int atcmd_plus_cmgw_write(int fd, const char *msg, size_t msg_len);
int atcmd_plus_cmgw_write_text(int fd, const char *addr, int addr_type,
	const char *status, const char *msg, size_t msg_len);
int atcmd_plus_cmgs_write(int fd, const char *msg, size_t msg_len);
int atcmd_plus_cmgs_write_text(int fd, const char *addr, const char *msg, size_t msg_len);
int atcmd_plus_cmss_write(int fd, int index, const char *addr, int addr_type);
int atcmd_plus_cmgd_write(int fd, int index);

int atcmd_plus_qcfg_write(int fd, int sms_format);

int isCdmaTypeModel();

#define STORE_NAME_LEN		2
#define STORE_NAME_SIZE		(STORE_NAME_LEN + 1)
#define STORE_LOCATIONS_MAX	8

struct data_store {
	char name[STORE_NAME_SIZE];
	int used;
	int max;
};

struct store_locations {
	char names[STORE_LOCATIONS_MAX][STORE_NAME_SIZE];
	int nr_locations;
};

struct msg_store {
	struct data_store selected;
	struct store_locations choices;
};

int atcmd_plus_cpms_read(int fd, struct data_store *read_store,
	struct data_store *send_store, struct data_store *new_store, const char *model);
int atcmd_plus_cpms_test(int fd, struct store_locations *read_loc,
	struct store_locations *send_loc, struct store_locations *new_loc);
int atcmd_plus_cpms_write(int fd, const char *read_name,
		const char *send_name, const char *new_name, const char *model);

struct phonebook_store {
	struct data_store selected;
	struct store_locations choices;
	int index_min;
	int index_max;
	int addr_max;
	int name_max;
};

int atcmd_plus_cpbs_read(int fd, struct data_store *store);
int atcmd_plus_cpbs_test(int fd, struct store_locations *loc);
int atcmd_plus_cpbs_write(int fd, const char *name);
int atcmd_plus_cpbr_test(int fd, struct phonebook_store *store);

int atcmd_plus_gmm_read(int fd);
int atcmd_plus_gmi_read(int fd);

int atcmd_init(int fd, int read_timeout);
int sms_device_close(int fd);
int sms_device_open(void);
int is_vzw_lte(void);
int is_quectel_dual_sms_format(void);
int is_telit_model(void);
int is_quectel_model(void);

#if __ATCMD_C
const char *abort_dfl[] = {
	"NO DIAL TONE",
	"NO DIALTONE",
	"NO ANSWER",
	"NO CARRIER",
	"DELAYED",
	"VOICE",
	"BUSY",
};
#else
ATCMD_EXTERN const char *abort_dfl[];
#endif

#endif /* ~__ATCMD_H */