diff options
Diffstat (limited to 'src/pdu.h')
-rw-r--r-- | src/pdu.h | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/pdu.h b/src/pdu.h new file mode 100644 index 0000000..0305550 --- /dev/null +++ b/src/pdu.h @@ -0,0 +1,132 @@ +#ifndef __PDU_H +#define __PDU_H + +#include <stdint.h> +#include <string.h> +#include <time.h> + +#include <phonebook.h> + +extern char *strptime(const char *s, const char *format, struct tm *tm); + +#define PDU_BUFFER_SIZE 1024 +#define PDU_ADDR_SIZE PHONEBOOK_ADDR_SIZE + +#define PDU_OCTETS_MAX 140 +#define PDU_UD_8BIT_MAX PDU_OCTETS_MAX +#define PDU_UD_7BIT_MAX (PDU_OCTETS_MAX * 8 / 7) +#define PDU_UD_SIZE (PDU_UD_7BIT_MAX + 1) + +#define PDU_TIMESTAMP_LEN 14 +#define PDU_TIMESTAMP_SIZE (PDU_TIMESTAMP_LEN + 1) +#define GMT_OFFSET_LEN 2 +#define GMT_OFFSET_IDX (PDU_TIMESTAMP_LEN - GMT_OFFSET_LEN) + +#define PDU_VPF_RELATIVE_2DAYS 0xA8 + +struct pdu_addr { + char addr[PDU_ADDR_SIZE]; + uint8_t type; + uint8_t len; +}; + +enum { + PDU_MTI_DELIVER = 0, + PDU_MTI_SUBMIT = 1, + PDU_MTI_REPORT = 2, + PDU_MTI_RESERVED = 3, +}; + +enum { + PDU_VPF_NOT_PRESENT = 0, + PDU_VPF_ENHANCED = 1, + PDU_VPF_RELATIVE = 2, + PDU_VPF_ABSOUTE = 3, +}; + +enum { + PDU_ALPHABET_DEFAULT = 0, + PDU_ALPHABET_EIGHT = 1, + PDU_ALPHABET_UCS2 = 2, + PDU_ALPHABET_RESERVED = 3, +}; + +struct pdu_info { + int msg_len; + struct pdu_addr smsc_addr; + struct pdu_addr addr; + union { + uint8_t type; + struct { + uint8_t msg_type: 2; + uint8_t more_msg: 1; + uint8_t unused: 2; + uint8_t status_report: 1; + uint8_t user_data_header: 1; + uint8_t reply_path: 1; + }; + struct { + uint8_t msg_type: 2; + uint8_t reject_duplicates: 1; + uint8_t validity_period_format: 2; + uint8_t status_report: 1; + uint8_t user_data_header: 1; + uint8_t reply_path: 1; + }; + } type; + uint8_t msg_reference; + uint8_t protocol_id; + union { + uint8_t data_coding; + struct { + uint8_t msg_class: 2; + uint8_t alphabet: 2; + uint8_t have_msg_class: 1; + uint8_t compressed: 1; + uint8_t unused: 2; + } general; + } data_coding; + uint8_t validity_period; + struct tm timestamp; + uint8_t user_data_len; + uint8_t user_data[PDU_UD_SIZE]; +}; + +#define HEX_BYTE_LEN 2 + +int hex_nibble_scan(const char *buf, size_t len); +int hex_byte_decode(const char *buf); + +int hex_byte_encode(char *buf, size_t len, int byte); + +int nibble_swap(char *buf, size_t len); +int strunpad(char *str, unsigned char c); +int strpad(char *str, size_t len, unsigned char c); + +int pdu_format_timestamp(struct pdu_info *pdu, char *str, size_t len, const char *fmt); +int pdu_format_vp(struct pdu_info *pdu, char *str, size_t len); +int pdu_addr_type_infer(const char *str); +int pdu_addr_fill(struct pdu_addr *addr, const char *addr_str, int type); +int pdu_user_data_read(int fd, struct pdu_info *pdu); + +#define shiftr(a, n) ((a) >> (n)) +#define shiftl(a, n) ((a) << (n)) + +#define bit_mask(n, s) (((1 << (n)) - 1) << (s)) +#define bit_maskr(n) bit_mask(n, 0) +#define bit_maskl(n, b) bit_mask(n, (b) - (n)) + +#define cycleup(n, mod) ((n) % (mod)) +#define cycledown(n, mod) ((mod - 1) - ((n) % (mod))) + +#define octet_align(n) ((((n) * 7) + ((-(n) * 7) & 7)) / 8) + +#define STRLEN_CHECK(str, len, ret) \ +do { \ + if (strnlen(str, len) < len) { \ + log_error("buffer ends unexpectedly early"); \ + return ret; \ + } \ +} while (0) + +#endif /* ~__PDU_H */ |