summaryrefslogtreecommitdiff
path: root/src/pdu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdu.h')
-rw-r--r--src/pdu.h132
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 */