-
Notifications
You must be signed in to change notification settings - Fork 0
/
sip_client.c
179 lines (158 loc) · 4.53 KB
/
sip_client.c
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <stdbool.h>
#include "sip_client.h"
#include "voipms.h"
#include "constify.h"
typedef struct {
pjsua_acc_id aid;
pjsua_transport_id tid;
bool did_create;
bool did_transport;
bool did_account;
} global_pj_state;
global_pj_state gpj;
void global_pj_state_reset(void){
gpj.did_create = false;
gpj.did_transport = false;
gpj.did_account = false;
}
inline bool pj_str_match(const pj_str_t* a, const pj_str_t* b){
return (a->slen == b->slen) && (strncmp(a->ptr, b->ptr, a->slen) == 0);
}
void pager_cb(pjsua_call_id call_id,
const pj_str_t *from,
const pj_str_t *to,
const pj_str_t *contact,
const pj_str_t *mime,
const pj_str_t *body){
// print plain text messages to the buffer
pj_str_t text_plain = pj_str("text/plain");
if(pj_str_match(mime, &text_plain)){
// TODO: error handling
voip_plugin_handle_sms(from->ptr, from->slen,
body->ptr, body->slen);
}
// for non-text messages, save to a file and show an alert
else{
// TODO: error handling
voip_plugin_handle_mms(from->ptr, from->slen,
mime->ptr, mime->slen,
body->ptr, body->slen);
}
}
int sip_client_send_sms(const char* sip_uri, const char* msg){
pj_str_t to = constify(sip_uri, strlen(sip_uri));
pj_str_t mime = pj_str("text/plain");
pj_str_t content = constify(msg, strlen(msg));
pjsua_im_send(gpj.aid, &to, &mime, &content, NULL, NULL);
// TODO: error handling
return 0;
}
// log to a weechat buffer
void pj_log_cb(int level, const char* data, int len){
if(voip_buffer) weechat_printf(voip_buffer, "%.*s", len, data);
}
int sip_setup(void){
// set global_pj_state to default values
global_pj_state_reset();
// CREATE
pj_status_t pret = pjsua_create();
if(pret != PJ_SUCCESS){
// TODO print error message
return 1;
}
gpj.did_create = true;
// INIT
pjsua_config pc;
pjsua_config_default(&pc);
pc.cb.on_pager = &pager_cb;
//pc.cb.on_incoming_call = &incoming_call_cb;
//pc.cb.on_call_state = &on_call_state;
//pc.cb.on_call_media_state = &on_call_media_state;
// handle our own logging
pjsua_logging_config lc;
pjsua_logging_config_default(&lc);
lc.console_level = 5;
lc.level = 5;
lc.cb = pj_log_cb;
// configure media
pjsua_media_config mc;
pjsua_media_config_default(&mc);
// disable auto-closing of snd device
//// mc.snd_auto_close_time = -1;
pret = pjsua_init(&pc, &lc, &mc);
if(pret != PJ_SUCCESS){
// TODO print error message
sip_teardown();
return 2;
}
// TRANSPORT
pjsua_transport_config tc;
pjsua_transport_config_default(&tc);
pjsip_transport_type_e type = PJSIP_TRANSPORT_UDP;
pret = pjsua_transport_create(type, &tc, &gpj.tid);
if(pret != PJ_SUCCESS){
// TODO print error message
sip_teardown();
return 10;
}
gpj.did_transport = true;
// START
pret = pjsua_start();
if(pret != PJ_SUCCESS){
// TODO print error message
sip_teardown();
return 20;
}
// ACCOUNT ADD
pjsip_cred_info creds = {
.realm = pj_str(REALM),
.scheme = pj_str("digest"),
.username = pj_str(USERNAME),
.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD,
.data = pj_str(PASSWORD),
};
pjsua_acc_config ac;
pjsua_acc_config_default(&ac);
ac.id = pj_str(ACCOUNT_ID);
ac.reg_uri = pj_str(REGISTER_URI);
ac.cred_info[0] = creds;
ac.cred_count = 1;
int make_default_account = 1;
pret = pjsua_acc_add(&ac, make_default_account, &gpj.aid);
if(pret != PJ_SUCCESS){
// TODO print error message
sip_teardown();
return 30;
}
gpj.did_account = true;
return 0;
}
int sip_teardown(){
pj_status_t pret;
int retval = 0;
// ACCOUNT DELETE
if(gpj.did_account){
pret = pjsua_acc_del(gpj.aid);
if(pret != PJ_SUCCESS){
// TODO print error message
retval = 1;
}
}
// TRANSPORT
if(gpj.did_transport){
pret = pjsua_transport_close(gpj.tid, 0);
if(pret != PJ_SUCCESS){
// TODO print error message
retval = 2;
}
}
// DESTROY
if(gpj.did_create){
pj_status_t pret = pjsua_destroy();
if(pret != PJ_SUCCESS){
// TODO log this
retval = 3;
}
}
return retval;
}