This source file includes following definitions.
- gettimeofday
- lpwrap_pri_event_str
- __pri_lpwrap_read
- __pri_lpwrap_write
- lpwrap_init_pri
- lpwrap_init_bri
- lpwrap_one_loop
- lpwrap_run_pri
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 #include "private/ftdm_core.h"
37 #include "lpwrap_pri.h"
38
39 #ifndef HAVE_GETTIMEOFDAY
40 #ifdef WIN32
41 #include <mmsystem.h>
42
43 static __inline int gettimeofday(struct timeval *tp, void *nothing)
44 {
45 #ifdef WITHOUT_MM_LIB
46 SYSTEMTIME st;
47 time_t tt;
48 struct tm tmtm;
49
50 GetLocalTime (&st);
51 tmtm.tm_sec = st.wSecond;
52 tmtm.tm_min = st.wMinute;
53 tmtm.tm_hour = st.wHour;
54 tmtm.tm_mday = st.wDay;
55 tmtm.tm_mon = st.wMonth - 1;
56 tmtm.tm_year = st.wYear - 1900; tmtm.tm_isdst = -1;
57 tt = mktime (&tmtm);
58 tp->tv_sec = tt;
59 tp->tv_usec = st.wMilliseconds * 1000;
60 #else
61
62
63
64
65
66
67 unsigned long Ticks = 0;
68 unsigned long Sec =0;
69 unsigned long Usec = 0;
70 Ticks = timeGetTime();
71
72 Sec = Ticks/1000;
73 Usec = (Ticks - (Sec*1000))*1000;
74 tp->tv_sec = Sec;
75 tp->tv_usec = Usec;
76 #endif
77 (void)nothing;
78 return 0;
79 }
80 #endif
81 #endif
82
83 static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[] = {
84 {0, LPWRAP_PRI_EVENT_ANY, "ANY"},
85 {1, LPWRAP_PRI_EVENT_DCHAN_UP, "DCHAN_UP"},
86 {2, LPWRAP_PRI_EVENT_DCHAN_DOWN, "DCHAN_DOWN"},
87 {3, LPWRAP_PRI_EVENT_RESTART, "RESTART"},
88 {4, LPWRAP_PRI_EVENT_CONFIG_ERR, "CONFIG_ERR"},
89 {5, LPWRAP_PRI_EVENT_RING, "RING"},
90 {6, LPWRAP_PRI_EVENT_HANGUP, "HANGUP"},
91 {7, LPWRAP_PRI_EVENT_RINGING, "RINGING"},
92 {8, LPWRAP_PRI_EVENT_ANSWER, "ANSWER"},
93 {9, LPWRAP_PRI_EVENT_HANGUP_ACK, "HANGUP_ACK"},
94 {10, LPWRAP_PRI_EVENT_RESTART_ACK, "RESTART_ACK"},
95 {11, LPWRAP_PRI_EVENT_FACILITY, "FACILITY"},
96 {12, LPWRAP_PRI_EVENT_INFO_RECEIVED, "INFO_RECEIVED"},
97 {13, LPWRAP_PRI_EVENT_PROCEEDING, "PROCEEDING"},
98 {14, LPWRAP_PRI_EVENT_SETUP_ACK, "SETUP_ACK"},
99 {15, LPWRAP_PRI_EVENT_HANGUP_REQ, "HANGUP_REQ"},
100 {16, LPWRAP_PRI_EVENT_NOTIFY, "NOTIFY"},
101 {17, LPWRAP_PRI_EVENT_PROGRESS, "PROGRESS"},
102 {18, LPWRAP_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"},
103 {19, LPWRAP_PRI_EVENT_IO_FAIL, "IO_FAIL"},
104 };
105
106 #define LINE "--------------------------------------------------------------------------------"
107
108 const char *lpwrap_pri_event_str(lpwrap_pri_event_t event_id)
109 {
110 if (event_id < 0 || event_id >= LPWRAP_PRI_EVENT_MAX)
111 return "";
112
113 return LPWRAP_PRI_EVENT_LIST[event_id].name;
114 }
115
116 static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen)
117 {
118 struct lpwrap_pri *spri = (struct lpwrap_pri *) pri_get_userdata(pri);
119 ftdm_size_t len = buflen;
120 ftdm_status_t zst;
121 int res;
122
123 if ((zst = ftdm_channel_read(spri->dchan, buf, &len)) != FTDM_SUCCESS) {
124 if (zst == FTDM_FAIL) {
125 ftdm_log(FTDM_LOG_CRIT, "span %d D-READ FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error);
126 spri->errs++;
127 } else {
128 ftdm_log(FTDM_LOG_CRIT, "span %d D-READ TIMEOUT\n", spri->span->span_id);
129 }
130
131 return 0;
132 }
133 spri->errs = 0;
134 res = (int)len;
135
136 if (res > 0) {
137 memset(&((unsigned char*)buf)[res], 0, 2);
138 res += 2;
139 #ifdef IODEBUG
140 {
141 char bb[2048] = { 0 };
142
143 print_hex_bytes(buf, res - 2, bb, sizeof(bb));
144 ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2);
145 }
146 #endif
147 }
148 return res;
149 }
150
151 static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen)
152 {
153 struct lpwrap_pri *spri = (struct lpwrap_pri *) pri_get_userdata(pri);
154 ftdm_size_t len = buflen - 2;
155
156 if (ftdm_channel_write(spri->dchan, buf, buflen, &len) != FTDM_SUCCESS) {
157 ftdm_log(FTDM_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error);
158
159 return 0;
160 }
161
162 #ifdef IODEBUG
163 {
164 char bb[2048] = { 0 };
165
166 print_hex_bytes(buf, buflen - 2, bb, sizeof(bb));
167 ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n", (int)buflen - 2);
168 }
169 #endif
170 return (int)buflen;
171 }
172
173 int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int debug)
174 {
175 int ret = -1;
176
177 memset(spri, 0, sizeof(struct lpwrap_pri));
178 spri->dchan = dchan;
179 spri->span = span;
180
181 if (!spri->dchan) {
182 ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create PRI\n");
183 return ret;
184 }
185
186 if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))) {
187 unsigned char buf[4] = { 0 };
188 size_t buflen = sizeof(buf), len = 0;
189
190 pri_set_debug(spri->pri, debug);
191 #ifdef HAVE_LIBPRI_AOC
192 pri_aoc_events_enable(spri->pri, 1);
193 #endif
194 ftdm_channel_write(spri->dchan, buf, buflen, &len);
195
196 ret = 0;
197 } else {
198 ftdm_log(FTDM_LOG_ERROR, "Unable to create PRI\n");
199 }
200 return ret;
201 }
202
203 int lpwrap_init_bri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int ptp, int debug)
204 {
205 int ret = -1;
206
207 #ifdef HAVE_LIBPRI_BRI
208 memset(spri, 0, sizeof(struct lpwrap_pri));
209 spri->dchan = dchan;
210 spri->span = span;
211
212 if (!spri->dchan) {
213 ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create BRI\n");
214 return ret;
215 }
216
217 if ((spri->pri = pri_new_bri_cb(spri->dchan->sockfd, ptp, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))) {
218 unsigned char buf[4] = { 0 };
219 size_t buflen = sizeof(buf), len = 0;
220
221 pri_set_debug(spri->pri, debug);
222 #ifdef HAVE_LIBPRI_AOC
223 pri_aoc_events_enable(spri->pri, 1);
224 #endif
225 ftdm_channel_write(spri->dchan, buf, buflen, &len);
226
227 ret = 0;
228 } else {
229 ftdm_log(FTDM_LOG_ERROR, "Unable to create BRI\n");
230 }
231 #else
232 ftdm_log(FTDM_LOG_ERROR, "Installed libpri version (%s) has no BRI support\n",
233 pri_get_version());
234 #endif
235 return ret;
236 }
237
238
239 int lpwrap_one_loop(struct lpwrap_pri *spri)
240 {
241 fd_set rfds, efds;
242 struct timeval now = {0,0}, *next = NULL;
243 pri_event *event = NULL;
244 event_handler handler;
245 int sel;
246
247 if (spri->on_loop) {
248 if ((sel = spri->on_loop(spri)) < 0) {
249 return sel;
250 }
251 }
252
253 if (spri->errs >= 2) {
254 spri->errs = 0;
255 return -1;
256 }
257
258 FD_ZERO(&rfds);
259 FD_ZERO(&efds);
260
261 #ifdef _MSC_VER
262
263 #pragma warning(push)
264 #pragma warning(disable:4127)
265 #endif
266
267 FD_SET(pri_fd(spri->pri), &rfds);
268 FD_SET(pri_fd(spri->pri), &efds);
269
270 #ifdef _MSC_VER
271 #pragma warning(pop)
272 #endif
273
274 now.tv_sec = 0;
275 now.tv_usec = 100000;
276
277 sel = select(pri_fd(spri->pri) + 1, &rfds, NULL, &efds, &now);
278 if (!sel) {
279 if ((next = pri_schedule_next(spri->pri))) {
280 gettimeofday(&now, NULL);
281 if (now.tv_sec >= next->tv_sec && (now.tv_usec >= next->tv_usec || next->tv_usec <= 100000)) {
282
283 event = pri_schedule_run(spri->pri);
284 }
285 }
286 } else if (sel > 0) {
287 event = pri_check_event(spri->pri);
288 }
289
290 if (event) {
291
292 if (event->e < 0 || event->e >= LPWRAP_PRI_EVENT_MAX) {
293 handler = spri->eventmap[0];
294 } else if (spri->eventmap[event->e]) {
295 handler = spri->eventmap[event->e];
296 } else {
297 handler = spri->eventmap[0];
298 }
299
300 if (handler) {
301 handler(spri, event->e, event);
302 } else {
303 ftdm_log(FTDM_LOG_CRIT, "No event handler found for event %d.\n", event->e);
304 }
305 }
306 return sel;
307 }
308
309 int lpwrap_run_pri(struct lpwrap_pri *spri)
310 {
311 int ret = 0;
312
313 for (;;) {
314 if ((ret = lpwrap_one_loop(spri)) < 0) {
315 #ifndef WIN32
316 if (errno == EINTR){
317
318 continue;
319 }
320 #endif
321 ftdm_log(FTDM_LOG_CRIT, "Error = %i [%s]\n", ret, strerror(errno));
322 break;
323 }
324 }
325 return ret;
326 }
327
328
329
330
331
332
333
334
335
336
337