#ifndef __PDU_H #define __PDU_H #include #include #include #include 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 */