1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#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_CDMA_TIMESTAMP_LEN 12
#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, //7-bit
PDU_ALPHABET_CDMA_DEFAULT = 2, //7-bit
PDU_ALPHABET_EIGHT = 4,
PDU_ALPHABET_CDMA_EIGHT = 8,
};
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 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: 4;
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 septet_idx(n) ((n) * 8 / 7)
#define octet_align_cdma(n) septet_idx(n)
#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 */
|