1 //indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90
2 #undef GIOVA48
3 #define CELLIAX_ALSA
4 #ifndef _CELLIAX_H_
5 #define _CELLIAX_H_
6 
7 #ifndef CELLIAX_SVN_VERSION
8 #define CELLIAX_SVN_VERSION "????NO_REVISION???"
9 #endif
10 
11 #include <asterisk/version.h>   /* needed here for conditional compilation on version.h */
12   /* the following #defs are for LINUX */
13 #ifndef __CYGWIN__
14 #ifndef ASTERISK_VERSION_1_6_0
15 #ifndef ASTERISK_VERSION_1_4
16 #ifndef ASTERISK_VERSION_1_2
17 #define ASTERISK_VERSION_1_4
18 #if(ASTERISK_VERSION_NUM == 999999)
19 #undef ASTERISK_VERSION_1_4
20 #elif(ASTERISK_VERSION_NUM < 10400)
21 #undef ASTERISK_VERSION_1_4
22 #endif /* ASTERISK_VERSION_NUM == 999999 || ASTERISK_VERSION_NUM < 10400 */
23 #endif /* ASTERISK_VERSION_1_2 */
24 #endif /* ASTERISK_VERSION_1_4 */
25 #endif /* ASTERISK_VERSION_1_6_0 */
26 #ifdef ASTERISK_VERSION_1_2
27 #undef ASTERISK_VERSION_1_4
28 #endif /* ASTERISK_VERSION_1_2 */
29 #ifdef ASTERISK_VERSION_1_6_0
30 #define ASTERISK_VERSION_1_4
31 #endif /* ASTERISK_VERSION_1_6_0 */
32 #define CELLIAX_DIR
33 #undef CELLIAX_LIBCSV
34 #endif /* NOT __CYGWIN__ */
35   /* the following #defs are for WINDOWS */
36 #ifdef __CYGWIN__
37 #undef ASTERISK_VERSION_1_4
38 #undef ASTERISK_VERSION_1_6_0
39 #define CELLIAX_DIR
40 #undef CELLIAX_LIBCSV
41 #endif /* __CYGWIN__ */
42 
43 /* CELLIAX_CVM */
44 #undef CELLIAX_CVM
45 /* CELLIAX_CVM */
46 
47 #undef CELLIAX_FBUS2
48 #define CELLIAX_DIR
49 #define CELLIAX_LIBCSV
50 
51 /* INCLUDES */
52 #ifdef ASTERISK_VERSION_1_6_0
53 #include <asterisk.h>           /* some asterisk-devel package do not contains asterisk.h, but seems that is needed for the 1.6 series, at least from trunk */
54 #endif /* ASTERISK_VERSION_1_6_0 */
55 #include <unistd.h>
56 #include <termios.h>
57 #include <fcntl.h>
58 #include <errno.h>
59 #include <math.h>
60 #include <sys/ioctl.h>
61 #include <sys/time.h>
62 #include <string.h>
63 #include <sys/types.h>
64 #include <signal.h>
65 #include <ctype.h>
66 #ifndef ASTERISK_VERSION_1_4
67 #include <stdlib.h>
68 #include <stdio.h>
69 #endif /* ASTERISK_VERSION_1_4 */
70 #ifndef CELLIAX_ALSA
71 #include "pablio.h"
72 #endif /* CELLIAX_ALSA */
73 //#include <asterisk/frame.h>
74 #include <asterisk/channel.h>
75 #include <asterisk/module.h>
76 #include <asterisk/pbx.h>
77 #include <asterisk/causes.h>
78 #include <asterisk/cli.h>
79 #include <asterisk/options.h>
80 #include <asterisk/config.h>
81 #include <asterisk/endian.h>
82 #include <asterisk/dsp.h>
83 #include <asterisk/lock.h>
84 #include <asterisk/devicestate.h>
85 #include <asterisk/file.h>
86 #include <asterisk/say.h>
87 #include <asterisk/manager.h>
88 #ifdef ASTERISK_VERSION_1_6_0
89 #include <asterisk/astobj2.h>
90 #include <asterisk/paths.h>
91 #endif /* ASTERISK_VERSION_1_6_0 */
92 #ifdef ASTERISK_VERSION_1_4
93 #include <asterisk/stringfields.h>
94 #include <asterisk/abstract_jb.h>
95 #include <asterisk/logger.h>
96 #include <asterisk/utils.h>
97 #endif /* ASTERISK_VERSION_1_4 */
98 #ifdef ASTERISK_VERSION_1_2
99 #include <asterisk/utils.h>
100 #include <asterisk/logger.h>
101 #endif /* ASTERISK_VERSION_1_2 */
102 #ifdef HAVE_CONFIG_H
103 #include <config.h>
104 #endif
105 #include "celliax_spandsp.h"
106 #ifdef CELLIAX_LIBCSV
107 #include "celliax_libcsv.h"
108 #endif /* CELLIAX_LIBCSV */
109 #ifdef __CYGWIN__
110 #include <windows.h>
111 #endif /* __CYGWIN__ */
112 #ifndef AST_DIGIT_ANYDIG
113 #define AST_DIGIT_ANYDIG "0123456789*#"
114 #else
115 #warning Please review Celliax AST_DIGIT_ANYDIG
116 #endif
117 #ifndef _ASTERISK_H
118 #define AST_CONFIG_MAX_PATH 255 /* defined in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
119 extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
120 int ast_register_atexit(void (*func) (void));   /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
121 void ast_unregister_atexit(void (*func) (void));    /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
122 #endif
123 #ifdef CELLIAX_ALSA
124 #define ALSA_PCM_NEW_HW_PARAMS_API
125 #define ALSA_PCM_NEW_SW_PARAMS_API
126 #include <alsa/asoundlib.h>
127 #endif /* CELLIAX_ALSA */
128 
129 /* DEFINITIONS */
130 /* LUIGI RIZZO's magic */
131 /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
132  * be representable in 16 bits to avoid overflows.
133  */
134 #define	BOOST_SCALE	(1<<9)
135 #define	BOOST_MAX	40          /* slightly less than 7 bits */
136 /* call flow from the device */
137 #define 	FBUS2_OUTGOING_ACK   999
138 #define 	FBUS2_SECURITY_COMMAND_ON   444
139 #define 	CALLFLOW_CALL_IDLE  AST_STATE_DOWN
140 #define 	CALLFLOW_INCOMING_RING  AST_STATE_RING
141 #define 	CALLFLOW_CALL_DIALING   AST_STATE_DIALING
142 #define 	CALLFLOW_CALL_LINEBUSY   AST_STATE_BUSY
143 #define 	CALLFLOW_CALL_ACTIVE   300
144 #define 	CALLFLOW_INCOMING_HANGUP   100
145 #define 	CALLFLOW_CALL_RELEASED   101
146 #define 	CALLFLOW_CALL_NOCARRIER   102
147 #define 	CALLFLOW_CALL_INFLUX   103
148 #define 	CALLFLOW_CALL_INCOMING   104
149 #define 	CALLFLOW_CALL_FAILED   105
150 #define 	CALLFLOW_CALL_NOSERVICE   106
151 #define 	CALLFLOW_CALL_OUTGOINGRESTRICTED   107
152 #define 	CALLFLOW_CALL_SECURITYFAIL   108
153 #define 	CALLFLOW_CALL_NOANSWER   109
154 #define 	CALLFLOW_CALL_HANGUP_REQUESTED   110
155   //fixme CALLFLOW_GOT_IMEI to be removed
156 #define 	CALLFLOW_GOT_IMEI   1009
157   //fixme CALLFLOW_INCOMING_CALLID to be removed
158 #define 	CALLFLOW_INCOMING_CALLID   1019
159 #define 	AT_OK   0
160 #define 	AT_ERROR   1
161 /* FBUS2 (old Nokia phones) undocumented proprietary protocol */
162 #define 	FBUS2_ACK_BYTE   0x7f
163 #define 	FBUS2_CALL_CALLID   0x05
164 #define 	FBUS2_CALL_HANGUP   0x04
165 #define 	FBUS2_CALL_STATUS_OFF   0x01
166 #define 	FBUS2_CALL_STATUS_ON   0x02
167 #define 	FBUS2_COMMAND_BYTE_1   0x00
168 #define 	FBUS2_COMMAND_BYTE_2   0x01
169 #define 	FBUS2_DEVICE_PC   0x0c
170 #define 	FBUS2_DEVICE_PHONE   0x00
171 #define 	FBUS2_IRDA_FRAME_ID   0x1c
172 #define 	FBUS2_IS_LAST_FRAME   0x01
173 #define 	FBUS2_MAX_TRANSMIT_LENGTH   120
174 #define 	FBUS2_NETWORK_STATUS_REGISTERED   0x71
175 #define 	FBUS2_SECURIY_CALL_COMMAND_ANSWER   0x02
176 #define 	FBUS2_SECURIY_CALL_COMMAND_CALL   0x01
177 #define 	FBUS2_SECURIY_CALL_COMMAND_RELEASE   0x03
178 #define 	FBUS2_SECURIY_CALL_COMMANDS   0x7c
179 #define 	FBUS2_SECURIY_EXTENDED_COMMAND_ON   0x01
180 #define 	FBUS2_SECURIY_EXTENDED_COMMANDS   0x64
181 #define 	FBUS2_SECURIY_IMEI_COMMAND_GET   0x00
182 #define 	FBUS2_SECURIY_IMEI_COMMANDS   0x66
183 #define 	FBUS2_SEQNUM_MAX   0x47
184 #define 	FBUS2_SEQNUM_MIN   0x40
185 #define 	FBUS2_SERIAL_FRAME_ID   0x1e
186 #define 	FBUS2_SMS_INCOMING   0x10
187 #define 	FBUS2_TYPE_CALL   0x01
188 #define 	FBUS2_TYPE_CALL_DIVERT   0x06
189 #define 	FBUS2_TYPE_CALL_STATUS   0x0d
190 #define 	FBUS2_TYPE_NETWORK_STATUS   0x0a
191 #define 	FBUS2_TYPE_SECURITY   0x40
192 #define 	FBUS2_TYPE_SMS   0x02
193 #define 	FBUS2_TYPE_MODEL_ASK   0xd1
194 #define   FBUS2_TYPE_MODEL_ANSWER   0xd2
195 //#define   FBUS2_TYPE_MODEL_ANSWER   0xffffffd2
196 #ifdef CELLIAX_CVM
197 #define   CVM_BUSMAIL_SEQNUM_MAX   0x7
198 #endif /* CELLIAX_CVM */
199 /* debugging bitmask */
200 #define DEBUG_SOUND 1
201 #define DEBUG_SERIAL 2
202 #define DEBUG_SKYPE 4
203 #define DEBUG_AT 8
204 #define DEBUG_FBUS2 16
205 #define DEBUG_CALL 32
206 #define DEBUG_LOCKS 64
207 #define DEBUG_PBX 128
208 #define DEBUG_MONITORLOCKS 256
209 #ifndef CELLIAX_CVM
210 #define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS
211 #else
212 #define DEBUG_CVM 512
213 #define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS|DEBUG_CVM
214 #endif /* CELLIAX_CVM */
215 /* wrappers for ast_log */
216 #define DEBUGA_SOUND(...)  if (celliax_debug & DEBUG_SOUND) ast_log(LOG_DEBUG, 		"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SOUND  %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
217 #define DEBUGA_SERIAL(...)  if (celliax_debug & DEBUG_SERIAL) ast_log(LOG_DEBUG, 	"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SERIAL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
218 #define DEBUGA_SKYPE(...)  if (celliax_debug & DEBUG_SKYPE) ast_log(LOG_DEBUG, 		"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SKYPE  %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
219 #define DEBUGA_AT(...)  if (celliax_debug & DEBUG_AT) ast_log(LOG_DEBUG, 		"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_AT     %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
220 #define DEBUGA_FBUS2(...)  if (celliax_debug & DEBUG_FBUS2) ast_log(LOG_DEBUG, 		"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_FBUS2  %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
221 #define DEBUGA_CALL(...)  if (celliax_debug & DEBUG_CALL) ast_log(LOG_DEBUG, 		"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CALL   %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
222 #define DEBUGA_PBX(...)  if (celliax_debug & DEBUG_PBX) ast_log(LOG_DEBUG, 		"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_PBX    %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
223 #ifdef CELLIAX_CVM
224 #define DEBUGA_CVM(...)  if (celliax_debug & DEBUG_CVM) ast_log(LOG_DEBUG,  "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CVM    %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
225 #endif /* CELLIAX_CVM */
226 #define ERRORA(...)  ast_log(LOG_ERROR, 						"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][ERROR        %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
227 #define NOTICA(...)  ast_log(LOG_NOTICE, 						"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][NOTICE      %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
228 #define WARNINGA(...)  ast_log(LOG_WARNING, 						"rev "CELLIAX_SVN_VERSION "[%p|%-7lx][WARNING    %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
229 /* macros for logging */
230 #define CELLIAX_P_LOG p ? p->owner : NULL, (unsigned long)pthread_self(), __LINE__, p ? p->name ? p->name : "none" : "none", p ? p->owner ? p->owner->_state : -1 : -1,  p ? p->interface_state : -1, p ? p->phone_callflow : -1
231 #define CELLIAX_TMP_LOG tmp ? tmp->owner : NULL, (unsigned long)pthread_self(), __LINE__, tmp ? tmp->name ? tmp->name : "none" : "none", tmp ? tmp->owner ? tmp->owner->_state : -1 : -1,  tmp ? tmp->interface_state : -1, tmp ? tmp->phone_callflow : -1
232 /* logging wrappers for ast_mutex_lock and ast_mutex_unlock */
233 #define LOKKA(x)  if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" :  x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n");   if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
234 #define UNLOCKA(x)  if (celliax_debug & DEBUG_LOCKS)  ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n",  CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n");   if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
235 #define CVM_LOKKA(x)  if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" :  x == &p->cvm_busmail_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n");   if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "CVM_BUSMAIL_OUTGOING_LIST_LOCK" : "?????");
236 #define CVM_UNLOCKA(x)  if (celliax_debug & DEBUG_LOCKS)  ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n",  CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n");   if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS  %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "CVM_BUSMAIL_OUTGOING_LIST_LOCK" : "?????");
237 #define PUSHA_UNLOCKA(x)    pthread_cleanup_push(celliax_unlocka_log, (void *) x);
238 #define POPPA_UNLOCKA(x)    pthread_cleanup_pop(0);
239 #define MONITORLOKKA(x)  if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS  %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" :  x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n");   if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS  %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
240 #define MONITORUNLOCKA(x)  if (celliax_debug & DEBUG_MONITORLOCKS)  ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS  %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n",  CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n");   if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS  %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
241 /* macros used for config file parsing */
242 #define 	M_BOOL(tag, dst)   M_F(tag, (dst) = ast_true(__val) )
243 #define 	M_END(x)   x;
244 #define 	M_F(tag, f)   if (!strcasecmp((__s), tag)) { f; } else
245 #ifdef ASTERISK_VERSION_1_6_0
246 #define 	M_START(var, val)   const char *__s = var; const char *__val = val;
247 #else
248 #define 	M_START(var, val)   char *__s = var; char *__val = val;
249 #endif /* ASTERISK_VERSION_1_6_0 */
250 #define 	M_STR(tag, dst)   M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
251 #define 	M_UINT(tag, dst)   M_F(tag, (dst) = strtoul(__val, NULL, 0) )
252 /* which protocol we use to control the phone through serial device */
253 #ifdef CELLIAX_CVM
254 #define   PROTOCOL_CVM_BUSMAIL   5
255 #endif /* CELLIAX_CVM */
256 #define 	PROTOCOL_ALSA_VOICEMODEM   4
257 #define 	PROTOCOL_AT   2
258 #define 	PROTOCOL_FBUS2   1
259 #define 	PROTOCOL_NO_SERIAL   3
260 #ifndef GIOVA48
261 #define 	CELLIAX_FRAME_SIZE   160
262 #else //GIOVA48
263 #define 	CELLIAX_FRAME_SIZE   960
264 #endif //GIOVA48
265 #define		AT_BUFSIZ 8192
266 #define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */
267 #define AT_MESG_MAX_LINES 256   /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */
268 
269 #ifdef CELLIAX_CVM
270 /* MAIL PRIMITIVES */
271 /* CVM -> CELLIAX */
272 #define API_PP_LOCKED_IND 0x8558    //PP locked with FP
273 #define API_PP_UNLOCKED_IND 0x8559  //PP out of service, unlocked from FP
274 
275 #define API_PP_SETUP_IND 0x8574 //Incoming call to PP
276 
277 #define API_PP_SETUP_IND_CALL_TYPE_OFFSET 0x0
278 #define API_PP_SETUP_IND_RING_TYPE_OFFSET 0x1
279 
280 #define API_PP_SETUP_IND_CALL_EXT 0x0
281 #define API_PP_SETUP_IND_CALL_INT 0x1
282 
283 #define API_PP_SETUP_IND_RING_INT_CALL 0x40
284 #define API_PP_SETUP_IND_RING_PAGE_ALL 0x46
285 
286 #define API_PP_SETUP_ACK_IND 0x857F //internal connection established with FPs, waiting for handsetnumber
287 
288 #define API_PP_CONNECT_IND 0x8576   //air-link established with FPs
289 #define API_PP_CONNECT_CFM 0x8578   //PP answered incoming call
290 
291 #define API_PP_ALERT_IND 0x8581
292 #define API_PP_ALERT_ON_IND 0x857D
293 #define API_PP_ALERT_OFF_IND 0x857E
294 
295 #define API_PP_SIGNAL_ON_IND 0x2F9C
296 #define API_PP_SIGNAL_OFF_IND 0x2F9D
297 
298 #define API_PP_RELEASE_IND 0x857B
299 #define API_PP_RELEASE_CFM 0x857A
300 #define API_PP_REJECT_IND 0x8564
301 
302 #define API_PP_ACCESS_RIGHTS_CFM 0x8568
303 #define API_PP_ACCESS_RIGHTS_REJ 0x8569
304 
305 #define API_PP_DELETE_SUBS_CFM 0x8561
306 #define API_PP_REMOTE_DELETE_SUBS_CFM 0x2F9F
307 
308 #define API_PP_CLIP_IND 0x2F93
309 #define API_PP_SW_STATUS_IND 0x2FC2
310 #define API_PP_MESSAGE_WAITING_IND 0x2FA1
311 
312 #define CVM_PP_PLUG_STATUS_IND 0x2F4F
313 #define CVM_PP_LINE_STATUS_IND 0x2F53
314 #define CVM_PP_ON_KEY_IND 0x2F64
315 
316 #define API_PP_READ_RSSI_CFM 0x2FC7
317 #define API_PP_ALERT_BROADCAST_IND 0x2FA3
318 
319 /* CELLIAX -> CVM */
320 #define API_PP_LOCK_REQ 0x8554  //select FP to lock once
321 #define API_PP_SETUP_REQ 0x8571 //setup air-link PP<->FP
322 
323 #define API_PP_KEYPAD_REQ 0x858A    //send string for dialing
324 
325 #define API_PP_CONNECT_REQ 0x8577   //answer incoming call
326 
327 #define API_PP_ALERT_REQ 0x2F8D //inform FP that alering is started
328 
329 #define API_PP_RELEASE_REQ 0x8579   //release connection
330 #define API_PP_RELEASE_RES 0x857C   //confirm FP initiated release of connection
331 #define API_PP_REJECT_REQ 0x8565    //PP reject incoming call
332 
333 #define API_PP_ACCESS_RIGHTS_REQ 0x8566 //init registration to FP
334 #define API_PP_DELETE_SUBS_REQ 0x8560   //deregister from FP (locally only in PP)
335 #define API_PP_REMOTE_DELETE_SUBS_REQ 0x2F9E    //remotly deregister from FP
336 
337 #define API_PP_STOP_PROTOCOL_REQ 0x2FC4 //stop protocol from running  (even registration)
338 
339 #define API_PP_READ_RSSI_REQ 0x2FC6 //RSSI readout request
340 #define API_PP_READ_RSSI_CFM 0x2FC7 //RSSI readout result
341 
342 #define CVM_PP_AUDIO_OPEN_REQ 0x2F0E    //Enable audio
343 #define CVM_PP_AUDIO_CLOSE_REQ 0x2F0F   //Disable audio
344 
345 #define CVM_PP_AUDIO_SET_VOLUME_REQ 0x2F1D  //set volume
346 
347 #define CVM_PP_AUDIO_UNMUTE_MIC_REQ 0x2F1A  //unmute mic
348 #define CVM_PP_AUDIO_MUTE_MIC_REQ 0x2F19    //mute mic
349 
350 #define CVM_PP_AUDIO_HS_PLUG_IND 0x2F1C //mute mic
351 
352 #define CVM_PP_AUDIO_OPEN_ADPCM_OFF_REQ 0x2F68  //open audio even before making connection
353 
354 /* END OF MAIL PRIMITIVES */
355 
356 enum CvmLockState {
357   CVM_UNKNOWN_LOCK_STATE = 0,
358   CVM_UNLOCKED_TO_FP,
359   CVM_LOCKED_TO_FP
360 };
361 
362 enum CvmRegisterState {
363   CVM_UNKNOWN_REGISTER_STATE = 0,
364   CVM_UNREGISTERED_TO_FP,
365   CVM_REGISTERED_TO_FP
366 };
367 
368 #define BUSMAIL_MAIL_MAX_PARAMS_LENGTH 128
369 #define BUSMAIL_MAX_FRAME_LENGTH (BUSMAIL_MAIL_MAX_PARAMS_LENGTH + 9)
370 
371 #define BUSMAIL_OFFSET_SOF 0
372 #define BUSMAIL_OFFSET_LEN_MSB 1
373 #define BUSMAIL_OFFSET_LEN_LSB 2
374 #define BUSMAIL_OFFSET_HEADER 3
375 #define BUSMAIL_OFFSET_MAIL BUSMAIL_OFFSET_MAIL_PROGRAM_ID
376 #define BUSMAIL_OFFSET_MAIL_PROGRAM_ID 4
377 #define BUSMAIL_OFFSET_MAIL_TASK_ID 5
378 #define BUSMAIL_OFFSET_MAIL_PRIMITIVE_MSB 7
379 #define BUSMAIL_OFFSET_MAIL_PRIMITIVE_LSB 6
380 #define BUSMAIL_OFFSET_MAIL_PARAMS 8
381 
382 #define BUSMAIL_MAIL_PRIMITIVE_MSB 1
383 #define BUSMAIL_MAIL_PRIMITIVE_LSB 0
384 #define BUSMAIL_LEN_MSB 0
385 #define BUSMAIL_LEN_LSB 1
386 
387 #define BUSMAIL_SOF 0x10
388 
389 #define BUSMAIL_MAIL_PROGRAM_ID 0x0
390 #define BUSMAIL_MAIL_USERTASK_TASK_ID 0x0f
391 #define BUSMAIL_MAIL_TBHANDLE_TASK_ID 0x0
392 #define BUSMAIL_MAIL_TASK_ID BUSMAIL_MAIL_USERTASK_TASK_ID
393 
394 #define BUSMAIL_HEADER_IC_BIT_MASK 0x80
395 #define BUSMAIL_HEADER_SU_BIT_MASK 0x40
396 #define BUSMAIL_HEADER_PF_BIT_MASK 0x08
397 #define BUSMAIL_HEADER_TXSEQ_MASK 0x70
398 #define BUSMAIL_HEADER_RXSEQ_MASK 0x07
399 #define BUSMAIL_HEADER_SUID_MASK 0x30
400 #define BUSMAIL_HEADER_UNID_MASK BUSMAIL_HEADER_SUID_MASK
401 
402 #define BUSMAIL_HEADER_INFO_FRAME 0x0
403 #define BUSMAIL_HEADER_CTRL_FRAME 0x80
404 #define BUSMAIL_HEADER_CTRL_SU_FRAME 0x0
405 #define BUSMAIL_HEADER_CTRL_UN_FRAME 0x40
406 
407 #define BUSMAIL_HEADER_UNID_SABM 0x0
408 #define BUSMAIL_HEADER_SUID_RR 0x0
409 #define BUSMAIL_HEADER_SUID_REJ 0x10
410 #define BUSMAIL_HEADER_SUID_RNR 0x20
411 
412 #define BUSMAIL_HEADER_SABM_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK | BUSMAIL_HEADER_UNID_MASK)
413 #define BUSMAIL_HEADER_SABM (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | BUSMAIL_HEADER_UNID_SABM)
414 
415 #define BUSMAIL_HEADER_REJ_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK | BUSMAIL_HEADER_SUID_MASK)
416 #define BUSMAIL_HEADER_REJ (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_REJ)
417 
418 #define BUSMAIL_HEADER_SU_FRAME_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK)
419 #define BUSMAIL_HEADER_SU_FRAME (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME)
420 
421 /*!
422  * \brief structure holding raw data to be send throught serial
423  */
424 struct cvm_busmail_msg {
425   int valid;
426   unsigned char busmail_msg_buffer[BUSMAIL_MAX_FRAME_LENGTH];
427   unsigned int busmail_msg_len;
428 
429   unsigned int tv_sec;
430   unsigned int tv_usec;
431 
432   unsigned char txseqno;
433   int acknowledged;
434   int how_many_sent;
435   int sent;
436 
437   struct cvm_busmail_msg *next;
438   struct cvm_busmail_msg *previous;
439 };
440 
441 /*!
442  * \brief structure holding busmail frame, for internal use
443  */
444 struct cvm_busmail_frame {
445   unsigned char busmail_sof;
446   unsigned char busmail_len[2];
447   unsigned char busmail_header;
448   unsigned char busmail_mail_program_id;
449   unsigned char busmail_mail_task_id;
450   unsigned char busmail_mail_primitive[2];
451   unsigned char busmail_mail_params_buffer[BUSMAIL_MAIL_MAX_PARAMS_LENGTH];
452   unsigned int busmail_mail_params_buffer_len;
453   unsigned char busmail_crc;
454 };
455 #endif /* CELLIAX_CVM */
456 
457 /* CELLIAX INTERNAL STRUCTS */
458 
459 /*!
460  * \brief structure for the linked list of FBUS2 Nokia proprietary protocol messages
461  */
462 struct fbus2_msg {
463   int msg;
464   int seqnum;
465   int len;
466   int acknowledged;
467   int how_many_sent;
468   int sent;
469   unsigned int tv_sec;
470   unsigned int tv_usec;
471   unsigned char buffer[FBUS2_MAX_TRANSMIT_LENGTH + 10];
472   struct fbus2_msg *next;
473   struct fbus2_msg *previous;
474 };
475 
476 /*!
477  * \brief structure for storing the results of AT commands, in an array of AT_MESG_MAX_LINES * AT_MESG_MAX_LENGTH chars
478  */
479 struct s_result {
480   int elemcount;
481   char result[AT_MESG_MAX_LINES][AT_MESG_MAX_LENGTH];
482 };
483 
484 /*!
485  * \brief PVT structure for a celliax interface (channel), created by celliax_mkif
486  */
487 struct celliax_pvt {
488   char *name;                   /*!< \brief 'name' of the interface (channel) */
489   int interface_state;          /*!< \brief 'state' of the interface (channel) */
490   int phone_callflow;           /*!< \brief 'callflow' of the phone interface (as opposed to skype interface) */
491   struct ast_channel *owner;    /*!< \brief channel we belong to, possibly NULL */
492   struct celliax_pvt *next;     /*!< \brief Next interface (channel) in list */
493   int readpos;                  /*!< \brief read position above */
494   struct ast_frame read_f;      /*!< \brief returned by oss_read */
495   char context[AST_MAX_EXTENSION];  /*!< \brief default Asterisk dialplan context for this interface */
496   char language[MAX_LANGUAGE];  /*!< \brief default Asterisk dialplan language for this interface */
497   char exten[AST_MAX_EXTENSION];    /*!< \brief default Asterisk dialplan extension for this interface */
498   struct ast_dsp *dsp;          /*!< \brief Used for in-band DTMF detection */
499   int celliax_sound_rate;       /*!< \brief rate of the sound device, in Hz, eg: 8000 */
500   int celliax_sound_capt_fd;    /*!< \brief file descriptor for sound capture dev */
501   char controldevice_name[50];  /*!< \brief name of the serial device controlling the interface, possibly none */
502   int controldevprotocol;       /*!< \brief which protocol is used for serial control of this interface */
503   char controldevprotocolname[50];  /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */
504   int controldevfd;             /*!< \brief serial controlling file descriptor for this interface */
505   char callid_name[50];
506   char callid_number[50];
507   unsigned char rxm[255];       /*!< \brief read buffer for FBUS2 serial protocol controlling Nokia phones */
508   unsigned char array[255];     /*!< \brief read buffer for FBUS2 serial protocol controlling Nokia phones */
509   int arraycounter;             /*!< \brief position in the 'array' read buffer for FBUS2 serial protocol controlling Nokia phones */
510   int seqnumfbus;               /*!< \brief sequential number of FBUS2 messages, hex, revolving */
511   pthread_t controldev_thread;  /*!< \brief serial control thread for this interface, running during the call */
512   struct fbus2_msg *fbus2_outgoing_list;    /*!< \brief list used to track FBUS2 traffic acknowledgement and resending */
513   ast_mutex_t fbus2_outgoing_list_lock;
514   int dsp_silence_threshold;
515   int need_acoustic_ring;       /*!< \brief bool, this interface get the incoming ring from soundcard, not serial */
516   char oss_write_buf[CELLIAX_FRAME_SIZE * 2];
517   int oss_write_dst;
518   char oss_read_buf[CELLIAX_FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];  /*!< in bytes */
519   time_t celliax_serial_synced_timestamp;
520   time_t celliax_serial_sync_period;
521   time_t audio_play_reset_timestamp;
522   time_t audio_capture_reset_timestamp;
523   speed_t controldevice_speed;
524   struct s_result line_array;
525   struct timeval ringtime;
526   struct timeval call_incoming_time;
527   int at_result;
528 
529   char at_dial_pre_number[64];
530   char at_dial_post_number[64];
531   char at_dial_expect[64];
532   unsigned int at_early_audio;
533   char at_hangup[64];
534   char at_hangup_expect[64];
535   char at_answer[64];
536   char at_answer_expect[64];
537   unsigned int at_initial_pause;
538   char at_preinit_1[64];
539   char at_preinit_1_expect[64];
540   char at_preinit_2[64];
541   char at_preinit_2_expect[64];
542   char at_preinit_3[64];
543   char at_preinit_3_expect[64];
544   char at_preinit_4[64];
545   char at_preinit_4_expect[64];
546   char at_preinit_5[64];
547   char at_preinit_5_expect[64];
548   unsigned int at_after_preinit_pause;
549 
550   char at_postinit_1[64];
551   char at_postinit_1_expect[64];
552   char at_postinit_2[64];
553   char at_postinit_2_expect[64];
554   char at_postinit_3[64];
555   char at_postinit_3_expect[64];
556   char at_postinit_4[64];
557   char at_postinit_4_expect[64];
558   char at_postinit_5[64];
559   char at_postinit_5_expect[64];
560 
561   char at_send_dtmf[64];
562 
563   char at_query_battchg[64];
564   char at_query_battchg_expect[64];
565   char at_query_signal[64];
566   char at_query_signal_expect[64];
567   char at_call_idle[64];
568   char at_call_incoming[64];
569   char at_call_active[64];
570   char at_call_failed[64];
571   char at_call_calling[64];
572 
573 #define CIEV_STRING_SIZE 64
574   char at_indicator_noservice_string[64];
575   char at_indicator_nosignal_string[64];
576   char at_indicator_lowsignal_string[64];
577   char at_indicator_lowbattchg_string[64];
578   char at_indicator_nobattchg_string[64];
579   char at_indicator_callactive_string[64];
580   char at_indicator_nocallactive_string[64];
581   char at_indicator_nocallsetup_string[64];
582   char at_indicator_callsetupincoming_string[64];
583   char at_indicator_callsetupoutgoing_string[64];
584   char at_indicator_callsetupremoteringing_string[64];
585 
586   int at_indicator_callp;
587   int at_indicator_callsetupp;
588   int at_indicator_roamp;
589   int at_indicator_battchgp;
590   int at_indicator_servicep;
591   int at_indicator_signalp;
592 
593   int at_has_clcc;
594   int at_has_ecam;
595 
596   double playback_boost;
597   double capture_boost;
598   int stripmsd;
599   int controldev_dead;
600   ast_mutex_t controldev_lock;
601   struct timeval fbus2_list_tv;
602   struct timezone fbus2_list_tz;
603   dtmf_rx_state_t dtmf_state;
604   int dtmf_inited;
605   pthread_t sync_thread;
606   pthread_t celliax_sound_monitor_thread;
607   pthread_t celliax_serial_monitor_thread;
608   int celliax_serial_monitoring;
609   int skype;                    /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */
610   int phonebook_listing;
611   int phonebook_querying;
612   int phonebook_listing_received_calls;
613 
614   int phonebook_first_entry;
615   int phonebook_last_entry;
616   int phonebook_number_lenght;
617   int phonebook_text_lenght;
618   FILE *phonebook_writing_fp;
619   int celliax_dir_entry_extension_prefix;
620 #ifdef CELLIAX_CVM
621   char cvm_subsc_1_pin[20];
622   char cvm_subsc_2_pin[20];
623   int cvm_subsc_no;
624   int cvm_lock_state;
625   int cvm_register_state;
626   int cvm_volume_level;
627   int cvm_celliax_serial_delay;
628   unsigned char cvm_handset_no;
629   unsigned char cvm_fp_is_cvm;
630   unsigned char cvm_rssi;
631 
632   unsigned char busmail_rxseq_cvm_last; /*!< \brief sequential number of BUSMAIL messages, (0-7) */
633   unsigned char busmail_txseq_celliax_last; /*!< \brief sequential number of BUSMAIL messages, (0-7) */
634 
635   struct cvm_busmail_msg *cvm_busmail_outgoing_list;    /*!< \brief list used to track CVM BUSMAIL traffic acknowledgement and resending */
636   ast_mutex_t cvm_busmail_outgoing_list_lock;
637 
638   struct timeval cvm_busmail_list_tv;
639   struct timezone cvm_busmail_list_tz;
640 #endif                          /* CELLIAX_CVM */
641 #ifdef CELLIAX_LIBCSV
642   int csv_separator_is_semicolon;
643   int csv_complete_name_pos;
644   int csv_email_pos;
645   int csv_home_phone_pos;
646   int csv_mobile_phone_pos;
647   int csv_business_phone_pos;
648   int csv_first_row_is_title;
649   int csv_fields;
650   int csv_rows;
651   char csv_complete_name[256];
652   char csv_email[256];
653   char csv_home_phone[256];
654   char csv_mobile_phone[256];
655   char csv_business_phone[256];
656 #endif                          /* CELLIAX_LIBCSV */
657   int audio_play_reset_period;
658 
659   char at_cmgw[16];
660 
661   int isInputInterleaved;
662   int isOutputInterleaved;
663   int numInputChannels;
664   int numOutputChannels;
665   int framesPerCallback;
666 #ifndef CELLIAX_ALSA
667   PABLIO_Stream *stream;
668 #endif /* CELLIAX_ALSA */
669   int audiopipe[2];
670   int speexecho;
671   int speexpreprocess;
672   int portaudiocindex;          /*!< \brief Index of the Portaudio capture audio device */
673   int portaudiopindex;          /*!< \brief Index of the Portaudio playback audio device */
674   int control_to_send;
675   int unread_sms_msg_id;
676   int reading_sms_msg;
677   char sms_message[4800];
678   int sms_cnmi_not_supported;
679   char sms_receiving_program[256];
680   int celliax_dir_prefix;
681   int no_ucs2;
682 #ifdef CELLIAX_ALSA
683   snd_pcm_t *alsac;             /*!< \brief handle of the ALSA capture audio device */
684   snd_pcm_t *alsap;             /*!< \brief handle of the ALSA playback audio device */
685   char alsacname[50];           /*!< \brief name of the ALSA capture audio device */
686   char alsapname[50];           /*!< \brief name of the ALSA playback audio device */
687   int alsa_period_size;         /*!< \brief ALSA period_size, in byte */
688   int alsa_periods_in_buffer;   /*!< \brief how many periods in ALSA buffer, to calculate buffer_size */
689   unsigned long int alsa_buffer_size;   /*!< \brief ALSA buffer_size, in byte */
690   int alsawrite_filled;
691   int alsa_capture_is_mono;
692   int alsa_play_is_mono;
693   struct pollfd pfd;
694 #endif                          /* CELLIAX_ALSA */
695 
696   struct timeval dtmf_timestamp;
697 };
698 
699 /* LOCKS */
700 /*! \brief Protect the celliax_usecnt */
701 AST_MUTEX_DEFINE_STATIC(celliax_usecnt_lock);
702 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
703  *    when it's doing something critical. */
704 AST_MUTEX_DEFINE_STATIC(celliax_monlock);
705 /*! \brief Protect the interfaces list */
706 AST_MUTEX_DEFINE_STATIC(celliax_iflock);
707 
708 /* FUNCTIONS */
709 
710 /* module helpers functions */
711 int load_module(void);
712 int unload_module(void);
713 int usecount(void);
714 char *description(void);
715 char *key(void);
716 
717 /* chan_celliax internal functions */
718 void celliax_unlocka_log(void *x);
719 #ifdef CELLIAX_FBUS2
720 int celliax_serial_sync_FBUS2(struct celliax_pvt *p);
721 int celliax_serial_answer_FBUS2(struct celliax_pvt *p);
722 int celliax_serial_call_FBUS2(struct celliax_pvt *p, char *dstr);
723 int celliax_serial_hangup_FBUS2(struct celliax_pvt *p);
724 int celliax_serial_config_FBUS2(struct celliax_pvt *p);
725 int celliax_serial_read_FBUS2(struct celliax_pvt *p);
726 int celliax_serial_getstatus_FBUS2(struct celliax_pvt *p);
727 int celliax_serial_get_seqnum_FBUS2(struct celliax_pvt *p);
728 int celliax_serial_security_command_FBUS2(struct celliax_pvt *p);
729 int celliax_serial_send_FBUS2(struct celliax_pvt *p, int len, unsigned char *buffer2);
730 int celliax_serial_list_acknowledge_FBUS2(struct celliax_pvt *p, int seqnum);
731 int celliax_serial_send_if_time_FBUS2(struct celliax_pvt *p);
732 int celliax_serial_write_FBUS2(struct celliax_pvt *p, unsigned char *MsgBuffer,
733                                int MsgLength, unsigned char MsgType);
734 int celliax_serial_send_ack_FBUS2(struct celliax_pvt *p, unsigned char MsgType,
735                                   unsigned char MsgSequence);
736 struct fbus2_msg *celliax_serial_list_init_FBUS2(struct celliax_pvt *p);
737 int celliax_serial_list_print_FBUS2(struct celliax_pvt *p, struct fbus2_msg *list);
738 
739 #endif /* CELLIAX_FBUS2 */
740 
741 #ifdef CELLIAX_CVM
742 int celliax_serial_sync_CVM_BUSMAIL(struct celliax_pvt *p);
743 int celliax_serial_answer_CVM_BUSMAIL(struct celliax_pvt *p);
744 int celliax_serial_call_CVM_BUSMAIL(struct celliax_pvt *p, char *dstr);
745 int celliax_serial_hangup_CVM_BUSMAIL(struct celliax_pvt *p);
746 int celliax_serial_config_CVM_BUSMAIL(struct celliax_pvt *p);
747 int celliax_serial_read_CVM_BUSMAIL(struct celliax_pvt *p);
748 int celliax_serial_getstatus_CVM_BUSMAIL(struct celliax_pvt *p);
749 int celliax_serial_send_CVM_BUSMAIL(struct celliax_pvt *p, int len,
750                                     unsigned char *mesg_ptr);
751 int celliax_serial_list_acknowledge_CVM_BUSMAIL(struct celliax_pvt *p,
752                                                 unsigned char TxSeqNo);
753 int celliax_serial_send_if_time_CVM_BUSMAIL(struct celliax_pvt *p);
754 int celliax_serial_write_CVM_BUSMAIL(struct celliax_pvt *p,
755                                      struct cvm_busmail_frame *busmail_frame);
756 int celliax_serial_send_ctrl_frame_CVM_BUSMAIL(struct celliax_pvt *p,
757                                                unsigned char FrameType);
758 int celliax_serial_send_info_frame_CVM_BUSMAIL(struct celliax_pvt *p, int FrameType,
759                                                unsigned char ParamsLen,
760                                                unsigned char *Params);
761 struct cvm_busmail_msg *celliax_serial_list_init_CVM_BUSMAIL(struct celliax_pvt *p);
762 int celliax_serial_list_print_CVM_BUSMAIL(struct celliax_pvt *p,
763                                           struct cvm_busmail_msg *list);
764 int celliax_serial_lists_free_CVM_BUSMAIL(struct celliax_pvt *p);
765 
766 #endif /* CELLIAX_CVM */
767 
768 /* CHAN_CELLIAX.C */
769 int celliax_queue_control(struct ast_channel *chan, int control);
770 struct celliax_pvt *celliax_console_find_desc(char *dev);
771 int celliax_serial_call(struct celliax_pvt *p, char *dstr);
772 
773 /* FUNCTIONS */
774 /* PBX interface functions */
775 struct ast_channel *celliax_request(const char *type, int format, void *data, int *cause);
776 int celliax_answer(struct ast_channel *c);
777 int celliax_hangup(struct ast_channel *c);
778 int celliax_call(struct ast_channel *c, char *idest, int timeout);
779 struct ast_frame *celliax_read(struct ast_channel *chan);
780 int celliax_write(struct ast_channel *c, struct ast_frame *f);
781 int celliax_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
782 #ifndef ASTERISK_VERSION_1_4
783 int celliax_indicate(struct ast_channel *c, int cond);
784 #else
785 int celliax_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen);
786 #endif
787 int celliax_devicestate(void *data);
788 #ifdef ASTERISK_VERSION_1_4
789 int celliax_senddigit_begin(struct ast_channel *ast, char digit);
790 int celliax_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
791 #else /* ASTERISK_VERSION_1_4 */
792 int celliax_senddigit(struct ast_channel *ast, char digit);
793 #endif /* ASTERISK_VERSION_1_4 */
794 
795 /* chan_celliax internal functions */
796 
797 struct celliax_pvt *celliax_mkif(struct ast_config *cfg, char *ctg,
798                                  int is_first_category);
799 struct ast_channel *celliax_new(struct celliax_pvt *p, int state, char *context);
800 int celliax_restart_monitor(void);
801 void *celliax_do_monitor(void *data);
802 void *celliax_do_audio_monitor(void *data);
803 int celliax_sound_boost(struct ast_frame *f, double boost);
804 int celliax_sound_init(struct celliax_pvt *p);
805 int celliax_sound_shutdown(struct celliax_pvt *p);
806 struct ast_frame *celliax_sound_dsp_analize(struct celliax_pvt *p, struct ast_frame *f,
807                                             int dsp_silence_threshold);
808 int celliax_sound_dsp_set(struct celliax_pvt *p, int dsp_silence_threshold,
809                           int silence_suppression);
810 struct ast_frame *celliax_sound_read(struct celliax_pvt *p);
811 int celliax_sound_write(struct celliax_pvt *p, struct ast_frame *f);
812 int celliax_sound_monitor(struct celliax_pvt *p);
813 void *celliax_do_controldev_thread(void *data);
814 int celliax_serial_init(struct celliax_pvt *p, speed_t controldevice_speed);
815 int celliax_serial_monitor(struct celliax_pvt *p);
816 int celliax_serial_read(struct celliax_pvt *p);
817 int celliax_serial_sync(struct celliax_pvt *p);
818 int celliax_serial_getstatus(struct celliax_pvt *p);
819 int celliax_serial_config(struct celliax_pvt *p);
820 int celliax_serial_hangup(struct celliax_pvt *p);
821 int celliax_serial_answer(struct celliax_pvt *p);
822 
823 #define celliax_serial_write_AT_expect(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 1, 2)
824 #define celliax_serial_write_AT_expect_noexpcr(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 0, 2)
825 #define celliax_serial_write_AT_expect_noexpcr_tout(P, D, S, T) celliax_serial_write_AT_expect1(P, D, S, 0, T)
826 // 20.5 sec timeout, used for querying the SIM and sending SMSs
827 #define celliax_serial_write_AT_expect_longtime(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 1, 20)
828 #define celliax_serial_write_AT_expect_longtime_noexpcr(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 0, 20)
829 int celliax_serial_write_AT(struct celliax_pvt *p, const char *data);
830 int celliax_serial_write_AT_nocr(struct celliax_pvt *p, const char *data);
831 int celliax_serial_write_AT_ack(struct celliax_pvt *p, const char *data);
832 int celliax_serial_write_AT_ack_nocr_longtime(struct celliax_pvt *p, const char *data);
833 int celliax_serial_write_AT_noack(struct celliax_pvt *p, const char *data);
834 int celliax_serial_write_AT_expect1(struct celliax_pvt *p, const char *data,
835                                     const char *expected_string, int expect_crlf,
836                                     int seconds);
837 int celliax_serial_AT_expect(struct celliax_pvt *p, const char *expected_string,
838                              int expect_crlf, int seconds);
839 int celliax_serial_read_AT(struct celliax_pvt *p, int look_for_ack, int timeout_usec,
840                            int timeout_sec, const char *expected_string, int expect_crlf);
841 int celliax_serial_answer_AT(struct celliax_pvt *p);
842 int celliax_serial_hangup_AT(struct celliax_pvt *p);
843 int celliax_serial_config_AT(struct celliax_pvt *p);
844 int celliax_serial_call_AT(struct celliax_pvt *p, char *dstr);
845 int celliax_serial_sync_AT(struct celliax_pvt *p);
846 int celliax_serial_getstatus_AT(struct celliax_pvt *p);
847 
848 #ifdef ASTERISK_VERSION_1_6_0
849 void celliax_store_boost(const char *s, double *boost);
850 #else
851 void celliax_store_boost(char *s, double *boost);
852 #endif /* ASTERISK_VERSION_1_6_0 */
853 int celliax_console_set_active(int fd, int argc, char *argv[]);
854 #ifndef ASTERISK_VERSION_1_6_0
855 int celliax_console_hangup(int fd, int argc, char *argv[]);
856 #else /* ASTERISK_VERSION_1_6_0 */
857 char *celliax_console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
858 #endif /*  ASTERISK_VERSION_1_6_0 */
859 int celliax_console_playback_boost(int fd, int argc, char *argv[]);
860 int celliax_console_capture_boost(int fd, int argc, char *argv[]);
861 int celliax_console_celliax(int fd, int argc, char *argv[]);
862 #ifdef CELLIAX_DIR
863 int celliax_console_celliax_dir_import(int fd, int argc, char *argv[]);
864 int celliax_console_celliax_dir_export(int fd, int argc, char *argv[]);
865 #endif /* CELLIAX_DIR */
866 int celliax_console_dial(int fd, int argc, char *argv[]);
867 int celliax_console_sendsms(int fd, int argc, char *argv[]);
868 int celliax_portaudio_init(struct celliax_pvt *p);
869 int celliax_portaudio_shutdown(struct celliax_pvt *p);
870 struct ast_frame *celliax_portaudio_read(struct celliax_pvt *p);
871 int celliax_portaudio_write(struct celliax_pvt *p, struct ast_frame *f);
872 int celliax_portaudio_devlist(struct celliax_pvt *p);
873 #ifdef CELLIAX_DIR
874 int celliax_dir_exec(struct ast_channel *chan, void *data);
875 int celliax_dir_create_extensions(void);
876 int celliax_dir_play_mailbox_owner(struct ast_channel *chan, char *context,
877                                    char *dialcontext, char *ext, char *name);
878 struct ast_config *celliax_dir_realtime(char *context);
879 int celliax_dir_do(struct ast_channel *chan, struct ast_config *cfg, char *context,
880                    char *dialcontext, char digit, int last);
881 #endif /* CELLIAX_DIR */
882 #ifdef CELLIAX_LIBCSV
883 void celliax_cb1(char *s, size_t len, void *data);
884 void celliax_cb2(char c, void *data);
885 #endif /* CELLIAX_LIBCSV */
886 int celliax_sendsms(struct ast_channel *c, void *data);
887 int celliax_console_echo(int fd, int argc, char *argv[]);
888 int celliax_console_at(int fd, int argc, char *argv[]);
889 #ifdef ASTERISK_VERSION_1_2
890 int celliax_manager_sendsms(struct mansession *s, struct message *m);
891 #endif //ASTERISK_VERSION_1_2
892 #ifdef ASTERISK_VERSION_1_4
893 int celliax_manager_sendsms(struct mansession *s, const struct message *m);
894 #endif //ASTERISK_VERSION_1_4
895 int utf_to_ucs2(struct celliax_pvt *p, char *utf_in, size_t inbytesleft, char *ucs2_out,
896                 size_t outbytesleft);
897 int ucs2_to_utf8(struct celliax_pvt *p, char *ucs2_in, char *utf8_out,
898                  size_t outbytesleft);
899 #endif /* _CELLIAX_H_ */
900 #ifdef CELLIAX_ALSA
901 int console_alsa_period(int fd, int argc, char *argv[]);
902 #endif /* CELLIAX_ALSA */
903 #ifdef CELLIAX_ALSA
904 int alsa_init(struct celliax_pvt *p);
905 int alsa_shutdown(struct celliax_pvt *p);
906 snd_pcm_t *alsa_open_dev(struct celliax_pvt *p, snd_pcm_stream_t stream);
907 struct ast_frame *alsa_read(struct celliax_pvt *p);
908 int alsa_write(struct celliax_pvt *p, struct ast_frame *f);
909 #endif /* CELLIAX_ALSA */
910