Merged revisions 339831 via svnmerge from
[asterisk/asterisk.git] / channels / chan_unistim.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * UNISTIM channel driver for asterisk
5  *
6  * Copyright (C) 2005 - 2007, Cedric Hans
7  * 
8  * Cedric Hans <cedric.hans@mlkj.net>
9  *
10  * Asterisk 1.4 patch by Peter Be
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20  * at the top of the source tree.
21  */
22
23 /*!
24  * \file
25  *
26  * \brief chan_unistim channel driver for Asterisk
27  * \author Cedric Hans <cedric.hans@mlkj.net>
28  *
29  * Unistim (Unified Networks IP Stimulus) channel driver
30  * for Nortel i2002, i2004 and i2050
31  *
32  * \ingroup channel_drivers
33  */
34
35 /*** MODULEINFO
36         <support_level>extended</support_level>
37  ***/
38
39 #include "asterisk.h"
40
41 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
42
43 #include <sys/stat.h>
44 #include <signal.h>
45
46 #if defined(__CYGWIN__)
47 /*
48  * cygwin headers are partly inconsistent. struct iovec is defined in sys/uio.h
49  * which is not included by default by sys/socket.h - in_pktinfo is defined in
50  * w32api/ws2tcpip.h but this probably has compatibility problems with sys/socket.h
51  * So for the time being we simply disable HAVE_PKTINFO when building under cygwin.
52  *    This should be done in some common header, but for now this is the only file
53  * using iovec and in_pktinfo so it suffices to apply the fix here.
54  */
55 #ifdef HAVE_PKTINFO
56 #undef HAVE_PKTINFO
57 #endif
58 #endif /* __CYGWIN__ */
59
60 #include "asterisk/paths.h"     /* ast_config_AST_LOG_DIR used in (too ?) many places */
61 #include "asterisk/network.h"
62 #include "asterisk/channel.h"
63 #include "asterisk/config.h"
64 #include "asterisk/module.h"
65 #include "asterisk/pbx.h"
66 #include "asterisk/event.h"
67 #include "asterisk/rtp_engine.h"
68 #include "asterisk/netsock.h"
69 #include "asterisk/acl.h"
70 #include "asterisk/callerid.h"
71 #include "asterisk/cli.h"
72 #include "asterisk/app.h"
73 #include "asterisk/musiconhold.h"
74 #include "asterisk/causes.h"
75 #include "asterisk/indications.h"
76
77 /*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */
78
79 #define DEFAULTCONTEXT    "default"
80 #define DEFAULTCALLERID  "Unknown"
81 #define DEFAULTCALLERNAME       " "
82 #define DEFAULTHEIGHT    3
83 #define USTM_LOG_DIR        "unistimHistory"
84
85 /*! Size of the transmit buffer */
86 #define MAX_BUF_SIZE        64
87 /*! Number of slots for the transmit queue */
88 #define MAX_BUF_NUMBER    50
89 /*! Try x times before removing the phone */
90 #define NB_MAX_RETRANSMIT       8
91 /*! Nb of milliseconds waited when no events are scheduled */
92 #define IDLE_WAIT              1000
93 /*! Wait x milliseconds before resending a packet */
94 #define RETRANSMIT_TIMER        2000
95 /*! How often the mailbox is checked for new messages */
96 #define TIMER_MWI              10000
97 /*! Not used */
98 #define DEFAULT_CODEC      0x00
99 #define SIZE_PAGE              4096
100 #define DEVICE_NAME_LEN  16
101 #define AST_CONFIG_MAX_PATH     255
102 #define MAX_ENTRY_LOG      30
103
104 #define SUB_REAL                0
105 #define SUB_THREEWAY        1
106 #define MAX_SUBS                2
107
108 struct ast_format_cap *global_cap;
109
110 enum autoprovision {
111         AUTOPROVISIONING_NO = 0,
112         AUTOPROVISIONING_YES,
113         AUTOPROVISIONING_DB,
114         AUTOPROVISIONING_TN
115 };
116
117 enum autoprov_extn {
118         /*! Do not create an extension into the default dialplan */
119         EXTENSION_NONE = 0,
120         /*! Prompt user for an extension number and register it */
121         EXTENSION_ASK,
122         /*! Register an extension with the line=> value */
123         EXTENSION_LINE,
124         /*! Used with AUTOPROVISIONING_TN */
125         EXTENSION_TN
126 };
127 #define OUTPUT_HANDSET    0xC0
128 #define OUTPUT_HEADPHONE        0xC1
129 #define OUTPUT_SPEAKER    0xC2
130
131 #define VOLUME_LOW            0x01
132 #define VOLUME_LOW_SPEAKER      0x03
133 #define VOLUME_NORMAL      0x02
134 #define VOLUME_INSANELY_LOUD    0x07
135
136 #define MUTE_OFF                0x00
137 #define MUTE_ON          0xFF
138 #define MUTE_ON_DISCRET  0xCE
139
140 #define SIZE_HEADER          6
141 #define SIZE_MAC_ADDR      17
142 #define TEXT_LENGTH_MAX  24
143 #define TEXT_LINE0            0x00
144 #define TEXT_LINE1            0x20
145 #define TEXT_LINE2            0x40
146 #define TEXT_NORMAL          0x05
147 #define TEXT_INVERSE        0x25
148 #define STATUS_LENGTH_MAX       28
149
150 #define FAV_ICON_NONE              0x00
151 #define FAV_ICON_ONHOOK_BLACK      0x20
152 #define FAV_ICON_ONHOOK_WHITE      0x21
153 #define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22
154 #define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23
155 #define FAV_ICON_OFFHOOK_BLACK    0x24
156 #define FAV_ICON_OFFHOOK_WHITE    0x25
157 #define FAV_ICON_ONHOLD_BLACK      0x26
158 #define FAV_ICON_ONHOLD_WHITE      0x27
159 #define FAV_ICON_SPEAKER_OFFHOOK_BLACK  0x28
160 #define FAV_ICON_SPEAKER_OFFHOOK_WHITE  0x29
161 #define FAV_ICON_PHONE_BLACK        0x2A
162 #define FAV_ICON_PHONE_WHITE        0x2B
163 #define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C
164 #define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D
165 #define FAV_ICON_HEADPHONES          0x2E
166 #define FAV_ICON_HEADPHONES_ONHOLD      0x2F
167 #define FAV_ICON_HOME              0x30
168 #define FAV_ICON_CITY              0x31
169 #define FAV_ICON_SHARP            0x32
170 #define FAV_ICON_PAGER            0x33
171 #define FAV_ICON_CALL_CENTER        0x34
172 #define FAV_ICON_FAX                0x35
173 #define FAV_ICON_MAILBOX                0x36
174 #define FAV_ICON_REFLECT                0x37
175 #define FAV_ICON_COMPUTER              0x38
176 #define FAV_ICON_FORWARD                0x39
177 #define FAV_ICON_LOCKED          0x3A
178 #define FAV_ICON_TRASH            0x3B
179 #define FAV_ICON_INBOX            0x3C
180 #define FAV_ICON_OUTBOX          0x3D
181 #define FAV_ICON_MEETING                0x3E
182 #define FAV_ICON_BOX                0x3F
183
184 #define FAV_BLINK_FAST            0x20
185 #define FAV_BLINK_SLOW            0x40
186
187 #define FAV_MAX_LENGTH            0x0A
188
189 static void dummy(char *unused, ...)
190 {
191         return;
192 }
193
194 /*! \brief Global jitterbuffer configuration - by default, jb is disabled
195  *  \note Values shown here match the defaults shown in unistim.conf.sample */
196 static struct ast_jb_conf default_jbconf =
197 {
198         .flags = 0,
199         .max_size = 200,
200         .resync_threshold = 1000,
201         .impl = "fixed",
202         .target_extra = 40,
203 };
204 static struct ast_jb_conf global_jbconf;
205                                 
206
207 /* #define DUMP_PACKET 1 */
208 /* #define DEBUG_TIMER ast_verbose */
209
210 #define DEBUG_TIMER dummy
211 /*! Enable verbose output. can also be set with the CLI */
212 static int unistimdebug = 0;
213 static int unistim_port;
214 static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO;
215 static int unistim_keepalive;
216 static int unistimsock = -1;
217
218 static struct {
219         unsigned int tos;
220         unsigned int tos_audio;
221         unsigned int cos;
222         unsigned int cos_audio;
223 } qos = { 0, 0, 0, 0 };
224
225 static struct io_context *io;
226 static struct ast_sched_context *sched;
227 static struct sockaddr_in public_ip = { 0, };
228 /*! give the IP address for the last packet received */
229 static struct sockaddr_in address_from;
230 /*! size of the sockaddr_in (in WSARecvFrom) */
231 static unsigned int size_addr_from = sizeof(address_from);
232 /*! Receive buffer address */
233 static unsigned char *buff;
234 static int unistim_reloading = 0;
235 AST_MUTEX_DEFINE_STATIC(unistim_reload_lock);
236 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
237 static int usecnt = 0;
238 /* extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH]; */
239
240 /*! This is the thread for the monitor which checks for input on the channels
241  * which are not currently in use.  */
242 static pthread_t monitor_thread = AST_PTHREADT_NULL;
243
244 /*! Protect the monitoring thread, so only one process can kill or start it, and not
245  *    when it's doing something critical. */
246 AST_MUTEX_DEFINE_STATIC(monlock);
247 /*! Protect the session list */
248 AST_MUTEX_DEFINE_STATIC(sessionlock);
249 /*! Protect the device list */
250 AST_MUTEX_DEFINE_STATIC(devicelock);
251
252 enum phone_state {
253         STATE_INIT,
254         STATE_AUTHDENY,
255         STATE_MAINPAGE,
256         STATE_EXTENSION,
257         STATE_DIALPAGE,
258         STATE_RINGING,
259         STATE_CALL,
260         STATE_SELECTCODEC,
261         STATE_CLEANING,
262         STATE_HISTORY
263 };
264
265 enum handset_state {
266         STATE_ONHOOK,
267         STATE_OFFHOOK,
268 };
269
270 enum phone_key {
271         KEY_0 = 0x40,
272         KEY_1 = 0x41,
273         KEY_2 = 0x42,
274         KEY_3 = 0x43,
275         KEY_4 = 0x44,
276         KEY_5 = 0x45,
277         KEY_6 = 0x46,
278         KEY_7 = 0x47,
279         KEY_8 = 0x48,
280         KEY_9 = 0x49,
281         KEY_STAR = 0x4a,
282         KEY_SHARP = 0x4b,
283         KEY_UP = 0x4c,
284         KEY_DOWN = 0x4d,
285         KEY_RIGHT = 0x4e,
286         KEY_LEFT = 0x4f,
287         KEY_QUIT = 0x50,
288         KEY_COPY = 0x51,
289         KEY_FUNC1 = 0x54,
290         KEY_FUNC2 = 0x55,
291         KEY_FUNC3 = 0x56,
292         KEY_FUNC4 = 0x57,
293         KEY_ONHOLD = 0x5b,
294         KEY_HANGUP = 0x5c,
295         KEY_MUTE = 0x5d,
296         KEY_HEADPHN = 0x5e,
297         KEY_LOUDSPK = 0x5f,
298         KEY_FAV0 = 0x60,
299         KEY_FAV1 = 0x61,
300         KEY_FAV2 = 0x62,
301         KEY_FAV3 = 0x63,
302         KEY_FAV4 = 0x64,
303         KEY_FAV5 = 0x65,
304         KEY_COMPUTR = 0x7b,
305         KEY_CONF = 0x7c,
306         KEY_SNDHIST = 0x7d,
307         KEY_RCVHIST = 0x7e,
308         KEY_INDEX = 0x7f
309 };
310
311 struct tone_zone_unistim {
312         char country[3];
313         int freq1;
314         int freq2;
315 };
316
317 static const struct tone_zone_unistim frequency[] = {
318         {"us", 350, 440},
319         {"fr", 440, 0},
320         {"au", 413, 438},
321         {"nl", 425, 0},
322         {"uk", 350, 440},
323         {"fi", 425, 0},
324         {"es", 425, 0},
325         {"jp", 400, 0},
326         {"no", 425, 0},
327         {"at", 420, 0},
328         {"nz", 400, 0},
329         {"tw", 350, 440},
330         {"cl", 400, 0},
331         {"se", 425, 0},
332         {"be", 425, 0},
333         {"sg", 425, 0},
334         {"il", 414, 0},
335         {"br", 425, 0},
336         {"hu", 425, 0},
337         {"lt", 425, 0},
338         {"pl", 425, 0},
339         {"za", 400, 0},
340         {"pt", 425, 0},
341         {"ee", 425, 0},
342         {"mx", 425, 0},
343         {"in", 400, 0},
344         {"de", 425, 0},
345         {"ch", 425, 0},
346         {"dk", 425, 0},
347         {"cn", 450, 0},
348         {"--", 0, 0}
349 };
350
351 struct wsabuf {
352         u_long len;
353         unsigned char *buf;
354 };
355
356 struct systemtime {
357         unsigned short w_year;
358         unsigned short w_month;
359         unsigned short w_day_of_week;
360         unsigned short w_day;
361         unsigned short w_hour;
362         unsigned short w_minute;
363         unsigned short w_second;
364         unsigned short w_milliseconds;
365 };
366
367 struct unistim_subchannel {
368         ast_mutex_t lock;
369         /*! SUBS_REAL or SUBS_THREEWAY */
370         unsigned int subtype;
371         /*! Asterisk channel used by the subchannel */
372         struct ast_channel *owner;
373         /*! Unistim line */
374         struct unistim_line *parent;
375         /*! RTP handle */
376         struct ast_rtp_instance *rtp;
377         int alreadygone;
378         char ringvolume;
379         char ringstyle;
380 };
381
382 /*!
383  * \todo Convert to stringfields
384  */
385 struct unistim_line {
386         ast_mutex_t lock;
387         /*! Like 200 */
388         char name[80];
389         /*! Like USTM/200\@black */
390         char fullname[80];
391         /*! pointer to our current connection, channel... */
392         struct unistim_subchannel *subs[MAX_SUBS];
393         /*! Extension where to start */
394         char exten[AST_MAX_EXTENSION];
395         /*! Context to start in */
396         char context[AST_MAX_EXTENSION];
397         /*! Language for asterisk sounds */
398         char language[MAX_LANGUAGE];
399         /*! CallerID Number */
400         char cid_num[AST_MAX_EXTENSION];
401         /*! Mailbox for MWI */
402         char mailbox[AST_MAX_EXTENSION];
403         /*! Used by MWI */
404         int lastmsgssent;
405         /*! Used by MWI */
406         time_t nextmsgcheck;
407         /*! MusicOnHold class */
408         char musicclass[MAX_MUSICCLASS];
409         /*! Call group */
410         unsigned int callgroup;
411         /*! Pickup group */
412         unsigned int pickupgroup;
413         /*! Account code (for billing) */
414         char accountcode[80];
415         /*! AMA flags (for billing) */
416         int amaflags;
417         /*! Codec supported */
418         struct ast_format_cap *cap;
419         /*! Parkinglot */
420         char parkinglot[AST_MAX_CONTEXT];
421         struct unistim_line *next;
422         struct unistim_device *parent;
423 };
424
425 /*! 
426  * \brief A device containing one or more lines 
427  */
428 static struct unistim_device {
429         int receiver_state;           /*!< state of the receiver (see ReceiverState) */
430         int size_phone_number;    /*!< size of the phone number */
431         char phone_number[16];    /*!< the phone number entered by the user */
432         char redial_number[16];  /*!< the last phone number entered by the user */
433         int phone_current;                    /*!< Number of the current phone */
434         int pos_fav;                        /*!< Position of the displayed favorites (used for scrolling) */
435         char id[18];                        /*!< mac address of the current phone in ascii */
436         char name[DEVICE_NAME_LEN];     /*!< name of the device */
437         int softkeylinepos;                  /*!< position of the line softkey (default 0) */
438         char softkeylabel[6][11];       /*!< soft key label */
439         char softkeynumber[6][16];      /*!< number dialed when the soft key is pressed */
440         char softkeyicon[6];        /*!< icon number */
441         char softkeydevice[6][16];      /*!< name of the device monitored */
442         struct unistim_device *sp[6];   /*!< pointer to the device monitored by this soft key */
443         int height;                                                     /*!< The number of lines the phone can display */
444         char maintext0[25];                  /*!< when the phone is idle, display this string on line 0 */
445         char maintext1[25];                  /*!< when the phone is idle, display this string on line 1 */
446         char maintext2[25];                  /*!< when the phone is idle, display this string on line 2 */
447         char titledefault[13];    /*!< title (text before date/time) */
448         char datetimeformat;        /*!< format used for displaying time/date */
449         char contrast;                    /*!< contrast */
450         char country[3];                        /*!< country used for dial tone frequency */
451         struct ast_tone_zone *tz;              /*!< Tone zone for res_indications (ring, busy, congestion) */
452         char ringvolume;                        /*!< Ring volume */
453         char ringstyle;                  /*!< Ring melody */
454         int rtp_port;                      /*!< RTP port used by the phone */
455         int rtp_method;                  /*!< Select the unistim data used to establish a RTP session */
456         int status_method;                    /*!< Select the unistim packet used for sending status text */
457         char codec_number;                    /*!< The current codec used to make calls */
458         int missed_call;                        /*!< Number of call unanswered */
459         int callhistory;                        /*!< Allowed to record call history */
460         char lst_cid[TEXT_LENGTH_MAX];  /*!< Last callerID received */
461         char lst_cnm[TEXT_LENGTH_MAX];  /*!< Last callername recevied */
462         char call_forward[AST_MAX_EXTENSION];   /*!< Forward number */
463         int output;                                  /*!< Handset, headphone or speaker */
464         int previous_output;        /*!< Previous output */
465         int volume;                                  /*!< Default volume */
466         int mute;                                      /*!< Mute mode */
467         int moh;                                        /*!< Music on hold in progress */
468         int nat;                                        /*!< Used by the obscure ast_rtp_setnat */
469         enum autoprov_extn extension;   /*!< See ifdef EXTENSION for valid values */
470         char extension_number[11];      /*!< Extension number entered by the user */
471         char to_delete;                  /*!< Used in reload */
472         time_t start_call_timestamp;    /*!< timestamp for the length calculation of the call */
473         struct ast_silence_generator *silence_generator;
474         struct unistim_line *lines;
475         struct ast_ha *ha;
476         struct unistimsession *session;
477         struct unistim_device *next;
478 } *devices = NULL;
479
480 static struct unistimsession {
481         ast_mutex_t lock;
482         struct sockaddr_in sin;  /*!< IP address of the phone */
483         struct sockaddr_in sout;        /*!< IP address of server */
484         int timeout;                        /*!< time-out in ticks : resend packet if no ack was received before the timeout occured */
485         unsigned short seq_phone;       /*!< sequence number for the next packet (when we receive a request) */
486         unsigned short seq_server;      /*!< sequence number for the next packet (when we send a request) */
487         unsigned short last_seq_ack;    /*!< sequence number of the last ACK received */
488         unsigned long tick_next_ping;   /*!< time for the next ping */
489         int last_buf_available;  /*!< number of a free slot */
490         int nb_retransmit;                    /*!< number of retransmition */
491         int state;                                    /*!< state of the phone (see phone_state) */
492         int size_buff_entry;        /*!< size of the buffer used to enter datas */
493         char buff_entry[16];        /*!< Buffer for temporary datas */
494         char macaddr[18];                      /*!< mac adress of the phone (not always available) */
495         struct wsabuf wsabufsend[MAX_BUF_NUMBER];      /*!< Size of each paquet stored in the buffer array & pointer to this buffer */
496         unsigned char buf[MAX_BUF_NUMBER][MAX_BUF_SIZE];        /*!< Buffer array used to keep the lastest non-acked paquets */
497         struct unistim_device *device;
498         struct unistimsession *next;
499 } *sessions = NULL;
500
501 /*!
502  * \page Unistim datagram formats
503  *
504  * Format of datagrams :
505  * bytes 0 & 1 : ffff for discovery packet, 0000 for everything else
506  * byte 2 : sequence number (high part)
507  * byte 3 : sequence number (low part)
508  * byte 4 : 2 = ask question or send info, 1 = answer or ACK, 0 = retransmit request
509  * byte 5 : direction, 1 = server to phone, 2 = phone to server arguments
510  */
511
512 static const unsigned char packet_rcv_discovery[] =
513         { 0xff, 0xff, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 };
514 static const unsigned char packet_send_discovery_ack[] =
515         { 0x00, 0x00, /*Initial Seq (2 bytes) */ 0x00, 0x00, 0x00, 0x01 };
516
517 static const unsigned char packet_recv_firm_version[] =
518         { 0x00, 0x00, 0x00, 0x13, 0x9a, 0x0a, 0x02 };
519 static const unsigned char packet_recv_pressed_key[] =
520         { 0x00, 0x00, 0x00, 0x13, 0x99, 0x04, 0x00 };
521 static const unsigned char packet_recv_pick_up[] =
522         { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x04 };
523 static const unsigned char packet_recv_hangup[] =
524         { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x03 };
525 static const unsigned char packet_recv_r2[] = { 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 };
526
527 /*! TransportAdapter */
528 static const unsigned char packet_recv_resume_connection_with_server[] =
529         { 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 };
530 static const unsigned char packet_recv_mac_addr[] =
531         { 0xff, 0xff, 0xff, 0xff, 0x9a, 0x0d, 0x07 /*MacAddr */  };
532
533 static const unsigned char packet_send_date_time3[] =
534         { 0x11, 0x09, 0x02, 0x02, /*Month */ 0x05, /*Day */ 0x06, /*Hour */ 0x07,
535 /*Minutes */ 0x08, 0x32
536 };
537 static const unsigned char packet_send_date_time[] =
538         { 0x11, 0x09, 0x02, 0x0a, /*Month */ 0x05, /*Day */ 0x06, /*Hour */ 0x07, /*Minutes */
539 0x08, 0x32, 0x17, 0x04, 0x24, 0x07, 0x19,
540         0x04, 0x07, 0x00, 0x19, 0x05, 0x09, 0x3e, 0x0f, 0x16, 0x05, 0x00, 0x80, 0x00, 0x1e,
541                 0x05, 0x12, 0x00, 0x78
542 };
543
544 static const unsigned char packet_send_no_ring[] =
545         { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00 };
546 static const unsigned char packet_send_s4[] =
547         { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00, 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff,
548 0x16, 0x05, 0x1c, 0x00, 0x00, 0x17, 0x05,
549         0x0b, 0x00, 0x00, 0x19, 0x04, 0x00, 0x00, 0x19, 0x04, 0x00, 0x08, 0x19, 0x04, 0x00,
550                 0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
551         0x31, 0x00, 0x00, 0x16, 0x05, 0x04, 0x00, 0x00
552 };
553 static const unsigned char packet_send_call[] =
554         { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00, 0x16, 0x06, 0x32, 0xdf,
555         0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16, 0x0a, 0x38, 0x00, 0x12, 0xca, 0x03,
556                 0xc0, 0xc3, 0xc5, 0x16, 0x16, 0x30, 0x00,
557         0x00, /*codec */ 0x12, 0x12, /* frames per packet */ 0x01, 0x5c, 0x00, /*port RTP */
558                 0x0f, 0xa0, /* port RTCP */ 0x9c, 0x41,
559         /*port RTP */ 0x0f, 0xa0, /* port RTCP */ 0x9c, 0x41, /* IP Address */ 0x0a, 0x01,
560                 0x16, 0x66
561 };
562 static const unsigned char packet_send_stream_based_tone_off[] =
563         { 0x16, 0x05, 0x1c, 0x00, 0x00 };
564
565 /* static const unsigned char packet_send_Mute[] = { 0x16, 0x05, 0x04, 0x00, 0x00 };
566 static const unsigned char packet_send_CloseAudioStreamRX[] = { 0x16, 0x05, 0x31, 0x00, 0xff };
567 static const unsigned char packet_send_CloseAudioStreamTX[] = { 0x16, 0x05, 0x31, 0xff, 0x00 };*/
568 static const unsigned char packet_send_stream_based_tone_on[] =
569         { 0x16, 0x06, 0x1b, 0x00, 0x00, 0x05 };
570 static const unsigned char packet_send_stream_based_tone_single_freq[] =
571         { 0x16, 0x06, 0x1d, 0x00, 0x01, 0xb8 };
572 static const unsigned char packet_send_stream_based_tone_dial_freq[] =
573         { 0x16, 0x08, 0x1d, 0x00, 0x01, 0xb8, 0x01, 0x5e };
574 static const unsigned char packet_send_select_output[] =
575         { 0x16, 0x06, 0x32, 0xc0, 0x01, 0x00 };
576 static const unsigned char packet_send_ring[] =
577         { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16,
578         0x04, 0x1a, 0x01, 0x16, 0x05, 0x12, 0x13 /* Ring type 10 to 17 */ , 0x18, 0x16, 0x04, 0x18,     /* volume 00, 10, 20... */
579         0x20, 0x16, 0x04, 0x10, 0x00
580 };
581 static const unsigned char packet_send_end_call[] =
582         { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x31, 0x00, 0x00, 0x19, 0x04, 0x00,
583 0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
584         0x04, 0x00, 0x00, 0x16, 0x04, 0x37, 0x10
585 };
586 static const unsigned char packet_send_s9[] =
587         { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x19, 0x04, 0x00, 0x10, 0x16, 0x05, 0x1c, 0x00,
588 0x00 };
589 static const unsigned char packet_send_rtp_packet_size[] =
590         { 0x16, 0x08, 0x38, 0x00, 0x00, 0xe0, 0x00, 0xa0 };
591 static const unsigned char packet_send_jitter_buffer_conf[] =
592         { 0x16, 0x0e, 0x3a, 0x00, /* jitter */ 0x02, /* high water mark */ 0x04, 0x00, 0x00,
593 /* early packet resync 2 bytes */ 0x3e, 0x80,
594         0x00, 0x00, /* late packet resync 2 bytes */ 0x3e, 0x80
595 };
596
597 /* Duration in ms div 2 (0x20 = 64ms, 0x08 = 16ms) 
598 static unsigned char packet_send_StreamBasedToneCad[] =
599   { 0x16, 0x0a, 0x1e, 0x00, duration on  0x0a, duration off  0x0d, duration on 0x0a, duration off 0x0d, duration on 0x0a, duration off 0x2b }; */
600 static const unsigned char packet_send_open_audio_stream_rx[] =
601         { 0x16, 0x1a, 0x30, 0x00, 0xff, /* Codec */ 0x00, 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
602 0x0e, 0x01, /* Port */ 0x14, 0x50, 0x00,
603         0x00, /* Port */ 0x14, 0x50, 0x00, 0x00, /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
604 };
605 static const unsigned char packet_send_open_audio_stream_tx[] =
606         { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00, /* Codec */ 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
607 0x0e, 0x01, /* Local port */ 0x14, 0x50,
608         0x00, 0x00, /* Rmt Port */ 0x14, 0x50, 0x00, 0x00, /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
609 };
610
611 static const unsigned char packet_send_open_audio_stream_rx3[] =
612         { 0x16, 0x1a, 0x30, 0x00, 0xff, /* Codec */ 0x00, 0x00, 0x02, 0x01, 0xb8, 0xb8, 0x06,
613 0x06, 0x81, /* RTP Port */ 0x14, 0x50,
614 /* RTCP Port */ 0x14,
615         0x51, /* RTP Port */ 0x14, 0x50, /* RTCP Port */ 0x00, 0x00, /* Dest IP */ 0x0a, 0x93,
616                 0x69, 0x05
617 };
618 static const unsigned char packet_send_open_audio_stream_tx3[] =
619         { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00, /* Codec */ 0x00, 0x02, 0x01, 0xb8, 0xb8, 0x06,
620 0x06, 0x81, /* RTP Local port */ 0x14, 0x50,
621         /* RTCP Port */ 0x00, 0x00, /* RTP Rmt Port */ 0x14, 0x50, /* RTCP Port */ 0x00, 0x00,
622                 /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
623 };
624
625 static const unsigned char packet_send_arrow[] = { 0x17, 0x04, 0x04, 0x00 };
626 static const unsigned char packet_send_blink_cursor[] = { 0x17, 0x04, 0x10, 0x86 };
627 static const unsigned char packet_send_date_time2[] = { 0x17, 0x04, 0x17, 0x3d, 0x11, 0x09, 0x02, 0x0a, /*Month */ 0x05,   /*Day */
628         0x06, /*Hour */ 0x07, /*Minutes */ 0x08, 0x32
629 };
630 static const unsigned char packet_send_Contrast[] =
631         { 0x17, 0x04, 0x24, /*Contrast */ 0x08 };
632 static const unsigned char packet_send_StartTimer[] =
633         { 0x17, 0x05, 0x0b, 0x05, 0x00, 0x17, 0x08, 0x16, /* Text */ 0x44, 0x75, 0x72, 0xe9,
634 0x65 };
635 static const unsigned char packet_send_stop_timer[] = { 0x17, 0x05, 0x0b, 0x02, 0x00 };
636 static const unsigned char packet_send_icon[] = { 0x17, 0x05, 0x14, /*pos */ 0x00, /*icon */ 0x25 };      /* display an icon in front of the text zone */
637 static const unsigned char packet_send_S7[] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 };
638 static const unsigned char packet_send_set_pos_cursor[] =
639         { 0x17, 0x06, 0x10, 0x81, 0x04, /*pos */ 0x20 };
640
641 /*static unsigned char packet_send_MonthLabelsDownload[] =
642   { 0x17, 0x0a, 0x15,  Month (3 char)  0x46, 0x65, 0x62, 0x4d, 0xe4, 0x72, 0x20 }; */
643 static const unsigned char packet_send_favorite[] =
644         { 0x17, 0x0f, 0x19, 0x10, /*pos */ 0x01, /*name */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
645 0x20, 0x20, 0x20, 0x20, /*end_name */ 0x19,
646         0x05, 0x0f, /*pos */ 0x01, /*icone */ 0x00
647 };
648 static const unsigned char packet_send_title[] =
649         { 0x17, 0x10, 0x19, 0x02, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
650 0x20, 0x20, 0x20, 0x20 /*end_text */  };
651 static const unsigned char packet_send_text[] =
652         { 0x17, 0x1e, 0x1b, 0x04, /*pos */ 0x00, /*inverse */ 0x25, /*text */ 0x20, 0x20,
653 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
654         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
655                 /*end_text */ 0x17, 0x04, 0x10, 0x87
656 };
657 static const unsigned char packet_send_status[] =
658         { 0x17, 0x20, 0x19, 0x08, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
659 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
660         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20    /*end_text */
661 };
662 static const unsigned char packet_send_status2[] =
663         { 0x17, 0x0b, 0x19, /* pos [08|28|48|68] */ 0x00, /* text */ 0x20, 0x20, 0x20, 0x20,
664 0x20, 0x20, 0x20 /* end_text */  };
665
666 static const unsigned char packet_send_led_update[] = { 0x19, 0x04, 0x00, 0x00 };
667
668 static const unsigned char packet_send_query_basic_manager_04[] = { 0x1a, 0x04, 0x01, 0x04 };
669 static const unsigned char packet_send_query_mac_address[] = { 0x1a, 0x04, 0x01, 0x08 };
670 static const unsigned char packet_send_query_basic_manager_10[] = { 0x1a, 0x04, 0x01, 0x10 };
671 static const unsigned char packet_send_S1[] = { 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 };
672
673 static unsigned char packet_send_ping[] =
674         { 0x1e, 0x05, 0x12, 0x00, /*Watchdog timer */ 0x78 };
675
676 #define BUFFSEND unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }
677
678 static const char tdesc[] = "UNISTIM Channel Driver";
679 static const char channel_type[] = "USTM";
680
681 /*! Protos */
682 static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const char *linkedid);
683 static int load_module(void);
684 static int reload(void);
685 static int unload_module(void);
686 static int reload_config(void);
687 static void show_main_page(struct unistimsession *pte);
688 static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, 
689         void *data, int *cause);
690 static int unistim_call(struct ast_channel *ast, char *dest, int timeout);
691 static int unistim_hangup(struct ast_channel *ast);
692 static int unistim_answer(struct ast_channel *ast);
693 static struct ast_frame *unistim_read(struct ast_channel *ast);
694 static int unistim_write(struct ast_channel *ast, struct ast_frame *frame);
695 static int unistim_indicate(struct ast_channel *ast, int ind, const void *data,
696         size_t datalen);
697 static int unistim_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
698 static int unistim_senddigit_begin(struct ast_channel *ast, char digit);
699 static int unistim_senddigit_end(struct ast_channel *ast, char digit, 
700         unsigned int duration);
701 static int unistim_sendtext(struct ast_channel *ast, const char *text);
702
703 static int write_entry_history(struct unistimsession *pte, FILE * f, char c, 
704         char *line1);
705 static void change_callerid(struct unistimsession *pte, int type, char *callerid);
706
707 static struct ast_channel_tech unistim_tech = {
708         .type = channel_type,
709         .description = tdesc,
710         .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
711         .requester = unistim_request,
712         .call = unistim_call,
713         .hangup = unistim_hangup,
714         .answer = unistim_answer,
715         .read = unistim_read,
716         .write = unistim_write,
717         .indicate = unistim_indicate,
718         .fixup = unistim_fixup,
719         .send_digit_begin = unistim_senddigit_begin,
720         .send_digit_end = unistim_senddigit_end,
721         .send_text = unistim_sendtext,
722         .bridge = ast_rtp_instance_bridge,
723 };
724
725 static void display_last_error(const char *sz_msg)
726 {
727         time_t cur_time;
728         
729         time(&cur_time);
730
731         /* Display the error message */
732         ast_log(LOG_WARNING, "%s %s : (%u) %s\n", ctime(&cur_time), sz_msg, errno,
733                         strerror(errno));
734 }
735
736 static unsigned int get_tick_count(void)
737 {
738         struct timeval now = ast_tvnow();
739
740         return (now.tv_sec * 1000) + (now.tv_usec / 1000);
741 }
742
743 /* Send data to a phone without retransmit nor buffering */
744 static void send_raw_client(int size, const unsigned char *data, struct sockaddr_in *addr_to,
745                             const struct sockaddr_in *addr_ourip)
746 {
747 #ifdef HAVE_PKTINFO
748         struct iovec msg_iov;
749         struct msghdr msg;
750         char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
751         struct cmsghdr *ip_msg = (struct cmsghdr *) buffer;
752         struct in_pktinfo *pki = (struct in_pktinfo *) CMSG_DATA(ip_msg);
753
754         /* cast this to a non-const pointer, since the sendmsg() API
755          * does not provide read-only and write-only flavors of the
756          * structures used for its arguments, but in this case we know
757          * the data will not be modified
758          */
759         msg_iov.iov_base = (char *) data;
760         msg_iov.iov_len = size;
761
762         msg.msg_name = addr_to;  /* optional address */
763         msg.msg_namelen = sizeof(struct sockaddr_in);   /* size of address */
764         msg.msg_iov = &msg_iov;  /* scatter/gather array */
765         msg.msg_iovlen = 1;                  /* # elements in msg_iov */
766         msg.msg_control = ip_msg;       /* ancillary data */
767         msg.msg_controllen = sizeof(buffer);    /* ancillary data buffer len */
768         msg.msg_flags = 0;                    /* flags on received message */
769
770         ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
771         ip_msg->cmsg_level = IPPROTO_IP;
772         ip_msg->cmsg_type = IP_PKTINFO;
773         pki->ipi_ifindex = 0;      /* Interface index, 0 = use interface specified in routing table */
774         pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
775         /* pki->ipi_addr = ;   Header Destination address - ignored by kernel */
776
777 #ifdef DUMP_PACKET
778         if (unistimdebug) {
779                 int tmp;
780                 char iabuf[INET_ADDRSTRLEN];
781                 char iabuf2[INET_ADDRSTRLEN];
782                 ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
783                                         ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
784                                         ast_inet_ntoa(addr_to->sin_addr));
785                 for (tmp = 0; tmp < size; tmp++)
786                         ast_verb(0, "%.2x ", (unsigned char) data[tmp]);
787                 ast_verb(0, "\n******************************************\n");
788
789         }
790 #endif
791
792         if (sendmsg(unistimsock, &msg, 0) == -1)
793                 display_last_error("Error sending datas");
794 #else
795         if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
796                 == -1)
797                 display_last_error("Error sending datas");
798 #endif
799 }
800
801 static void send_client(int size, const unsigned char *data, struct unistimsession *pte)
802 {
803         unsigned int tick;
804         int buf_pos;
805         unsigned short seq = ntohs(++pte->seq_server);
806
807         ast_mutex_lock(&pte->lock);
808         buf_pos = pte->last_buf_available;
809
810         if (buf_pos >= MAX_BUF_NUMBER) {
811                 ast_log(LOG_WARNING, "Error : send queue overflow\n");
812                 ast_mutex_unlock(&pte->lock);
813                 return;
814         }
815         memcpy((void *)data + sizeof(unsigned short), (void *)&seq, sizeof(unsigned short));
816         pte->wsabufsend[buf_pos].len = size;
817         memcpy(pte->wsabufsend[buf_pos].buf, data, size);
818
819         tick = get_tick_count();
820         pte->timeout = tick + RETRANSMIT_TIMER;
821
822 /*#ifdef DUMP_PACKET */
823         if (unistimdebug)
824                 ast_verb(6, "Sending datas with seq #0x%.4x Using slot #%d :\n", pte->seq_server, buf_pos);
825 /*#endif */
826         send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
827                                   &(pte->sout));
828         pte->last_buf_available++;
829         ast_mutex_unlock(&pte->lock);
830 }
831
832 static void send_ping(struct unistimsession *pte)
833 {
834         BUFFSEND;
835         if (unistimdebug)
836                 ast_verb(6, "Sending ping\n");
837         pte->tick_next_ping = get_tick_count() + unistim_keepalive;
838         memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
839         send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
840 }
841
842 static int get_to_address(int fd, struct sockaddr_in *toAddr)
843 {
844 #ifdef HAVE_PKTINFO
845         int err;
846         struct msghdr msg;
847         struct {
848                 struct cmsghdr cm;
849                 int len;
850                 struct in_addr address;
851         } ip_msg;
852
853         /* Zero out the structures before we use them */
854         /* This sets several key values to NULL */
855         memset(&msg, 0, sizeof(msg));
856         memset(&ip_msg, 0, sizeof(ip_msg));
857
858         /* Initialize the message structure */
859         msg.msg_control = &ip_msg;
860         msg.msg_controllen = sizeof(ip_msg);
861         /* Get info about the incoming packet */
862         err = recvmsg(fd, &msg, MSG_PEEK);
863         if (err == -1)
864                 ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
865         memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
866         return err;
867 #else
868         memcpy(&toAddr, &public_ip, sizeof(&toAddr));
869         return 0;
870 #endif
871 }
872
873 /* Allocate memory & initialize structures for a new phone */
874 /* addr_from : ip address of the phone */
875 static struct unistimsession *create_client(const struct sockaddr_in *addr_from)
876 {
877         int tmp;
878         struct unistimsession *s;
879
880         if (!(s = ast_calloc(1, sizeof(*s))))
881                 return NULL;
882
883         memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
884         get_to_address(unistimsock, &s->sout);
885         if (unistimdebug) {
886                 ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
887                          ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
888         }
889         ast_mutex_init(&s->lock);
890         ast_mutex_lock(&sessionlock);
891         s->next = sessions;
892         sessions = s;
893
894         s->timeout = get_tick_count() + RETRANSMIT_TIMER;
895         s->seq_phone = (short) 0x0000;
896         s->seq_server = (short) 0x0000;
897         s->last_seq_ack = (short) 0x000;
898         s->last_buf_available = 0;
899         s->nb_retransmit = 0;
900         s->state = STATE_INIT;
901         s->tick_next_ping = get_tick_count() + unistim_keepalive;
902         /* Initialize struct wsabuf  */
903         for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
904                 s->wsabufsend[tmp].buf = s->buf[tmp];
905         }
906         ast_mutex_unlock(&sessionlock);
907         return s;
908 }
909
910 static void send_end_call(struct unistimsession *pte)
911 {
912         BUFFSEND;
913         if (unistimdebug)
914                 ast_verb(0, "Sending end call\n");
915         memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
916         send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
917 }
918
919 static void set_ping_timer(struct unistimsession *pte)
920 {
921         unsigned int tick = 0;  /* XXX what is this for, anyways */
922
923         pte->timeout = pte->tick_next_ping;
924         DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
925         return;
926 }
927
928 /* Checking if our send queue is empty,
929  * if true, setting up a timer for keepalive */
930 static void check_send_queue(struct unistimsession *pte)
931 {
932         /* Check if our send queue contained only one element */
933         if (pte->last_buf_available == 1) {
934                 if (unistimdebug)
935                         ast_verb(6, "Our single packet was ACKed.\n");
936                 pte->last_buf_available--;
937                 set_ping_timer(pte);
938                 return;
939         }
940         /* Check if this ACK catch up our latest packet */
941         else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
942                 if (unistimdebug)
943                         ast_verb(6, "Our send queue is completely ACKed.\n");
944                 pte->last_buf_available = 0;    /* Purge the send queue */
945                 set_ping_timer(pte);
946                 return;
947         }
948         if (unistimdebug)
949                 ast_verb(6, "We still have packets in our send queue\n");
950         return;
951 }
952
953 static void send_start_timer(struct unistimsession *pte)
954 {
955         BUFFSEND;
956         if (unistimdebug)
957                 ast_verb(0, "Sending start timer\n");
958         memcpy(buffsend + SIZE_HEADER, packet_send_StartTimer, sizeof(packet_send_StartTimer));
959         send_client(SIZE_HEADER + sizeof(packet_send_StartTimer), buffsend, pte);
960 }
961
962 static void send_stop_timer(struct unistimsession *pte)
963 {
964         BUFFSEND;
965         if (unistimdebug)
966                 ast_verb(0, "Sending stop timer\n");
967         memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
968         send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
969 }
970
971 static void Sendicon(unsigned char pos, unsigned char status, struct unistimsession *pte)
972 {
973         BUFFSEND;
974         if (unistimdebug)
975                 ast_verb(0, "Sending icon pos %d with status 0x%.2x\n", pos, status);
976         memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
977         buffsend[9] = pos;
978         buffsend[10] = status;
979         send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
980 }
981
982 static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
983 {
984         BUFFSEND;
985         if (!tone1) {
986                 if (unistimdebug)
987                         ast_verb(0, "Sending Stream Based Tone Off\n");
988                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
989                            sizeof(packet_send_stream_based_tone_off));
990                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
991                 return;
992         }
993         /* Since most of the world use a continuous tone, it's useless
994            if (unistimdebug)
995            ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
996            memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
997            send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
998         if (unistimdebug)
999                 ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
1000         tone1 *= 8;
1001         if (!tone2) {
1002                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
1003                            sizeof(packet_send_stream_based_tone_single_freq));
1004                 buffsend[10] = (tone1 & 0xff00) >> 8;
1005                 buffsend[11] = (tone1 & 0x00ff);
1006                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
1007                                    pte);
1008         } else {
1009                 tone2 *= 8;
1010                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
1011                            sizeof(packet_send_stream_based_tone_dial_freq));
1012                 buffsend[10] = (tone1 & 0xff00) >> 8;
1013                 buffsend[11] = (tone1 & 0x00ff);
1014                 buffsend[12] = (tone2 & 0xff00) >> 8;
1015                 buffsend[13] = (tone2 & 0x00ff);
1016                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
1017                                    pte);
1018         }
1019
1020         if (unistimdebug)
1021                 ast_verb(0, "Sending Stream Based Tone On\n");
1022         memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
1023                    sizeof(packet_send_stream_based_tone_on));
1024         send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
1025 }
1026
1027 /* Positions for favorites
1028  |--------------------|
1029  |  5       2    |
1030  |  4       1    |
1031  |  3       0    |
1032 */
1033
1034 /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */
1035 static void
1036 send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte,
1037                          const char *text)
1038 {
1039         BUFFSEND;
1040         int i;
1041
1042         if (unistimdebug)
1043                 ast_verb(0, "Sending favorite pos %d with status 0x%.2x\n", pos, status);
1044         memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1045         buffsend[10] = pos;
1046         buffsend[24] = pos;
1047         buffsend[25] = status;
1048         i = strlen(text);
1049         if (i > FAV_MAX_LENGTH)
1050                 i = FAV_MAX_LENGTH;
1051         memcpy(buffsend + FAV_MAX_LENGTH + 1, text, i);
1052         send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1053 }
1054
1055 static void refresh_all_favorite(struct unistimsession *pte)
1056 {
1057         int i = 0;
1058
1059         if (unistimdebug)
1060                 ast_verb(0, "Refreshing all favorite\n");
1061         for (i = 0; i < 6; i++) {
1062                 if ((pte->device->softkeyicon[i] <= FAV_ICON_HEADPHONES_ONHOLD) &&
1063                         (pte->device->softkeylinepos != i))
1064                         send_favorite((unsigned char) i, pte->device->softkeyicon[i] + 1, pte,
1065                                                  pte->device->softkeylabel[i]);
1066                 else
1067                         send_favorite((unsigned char) i, pte->device->softkeyicon[i], pte,
1068                                                  pte->device->softkeylabel[i]);
1069
1070         }
1071 }
1072
1073 /* Change the status for this phone (pte) and update for each phones where pte is bookmarked
1074  * use FAV_ICON_*_BLACK constant in status parameters */
1075 static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
1076 {
1077         struct unistim_device *d = devices;
1078         int i;
1079         /* Update the current phone */
1080         if (pte->state != STATE_CLEANING)
1081                 send_favorite(pte->device->softkeylinepos, status, pte,
1082                                          pte->device->softkeylabel[pte->device->softkeylinepos]);
1083         /* Notify other phones if we're in their bookmark */
1084         while (d) {
1085                 for (i = 0; i < 6; i++) {
1086                         if (d->sp[i] == pte->device) {  /* It's us ? */
1087                                 if (d->softkeyicon[i] != status) {      /* Avoid resending the same icon */
1088                                         d->softkeyicon[i] = status;
1089                                         if (d->session)
1090                                                 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1091                                 }
1092                         }
1093                 }
1094                 d = d->next;
1095         }
1096 }
1097
1098 static int RegisterExtension(const struct unistimsession *pte)
1099 {
1100         if (unistimdebug)
1101                 ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
1102                                         pte->device->extension_number, pte->device->lines->context,
1103                                         pte->device->lines->fullname);
1104         return ast_add_extension(pte->device->lines->context, 0,
1105                                                          pte->device->extension_number, 1, NULL, NULL, "Dial",
1106                                                          pte->device->lines->fullname, 0, "Unistim");
1107 }
1108
1109 static int UnregisterExtension(const struct unistimsession *pte)
1110 {
1111         if (unistimdebug)
1112                 ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
1113                                         pte->device->extension_number, pte->device->lines->context);
1114         return ast_context_remove_extension(pte->device->lines->context,
1115                                                                                 pte->device->extension_number, 1, "Unistim");
1116 }
1117
1118 /* Free memory allocated for a phone */
1119 static void close_client(struct unistimsession *s)
1120 {
1121         struct unistim_subchannel *sub;
1122         struct unistimsession *cur, *prev = NULL;
1123         ast_mutex_lock(&sessionlock);
1124         cur = sessions;
1125         /* Looking for the session in the linked chain */
1126         while (cur) {
1127                 if (cur == s)
1128                         break;
1129                 prev = cur;
1130                 cur = cur->next;
1131         }
1132         if (cur) {                                    /* Session found ? */
1133                 if (cur->device) {            /* This session was registered ? */
1134                         s->state = STATE_CLEANING;
1135                         if (unistimdebug)
1136                                 ast_verb(0, "close_client session %p device %p lines %p sub %p\n",
1137                                                         s, s->device, s->device->lines,
1138                                                         s->device->lines->subs[SUB_REAL]);
1139                         change_favorite_icon(s, FAV_ICON_NONE);
1140                         sub = s->device->lines->subs[SUB_REAL];
1141                         if (sub) {
1142                                 if (sub->owner) {       /* Call in progress ? */
1143                                         if (unistimdebug)
1144                                                 ast_verb(0, "Aborting call\n");
1145                                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NETWORK_OUT_OF_ORDER);
1146                                 }
1147                         } else
1148                                 ast_log(LOG_WARNING, "Freeing a client with no subchannel !\n");
1149                         if (!ast_strlen_zero(s->device->extension_number))
1150                                 UnregisterExtension(s);
1151                         cur->device->session = NULL;
1152                 } else {
1153                         if (unistimdebug)
1154                                 ast_verb(0, "Freeing an unregistered client\n");
1155                 }
1156                 if (prev)
1157                         prev->next = cur->next;
1158                 else
1159                         sessions = cur->next;
1160                 ast_mutex_destroy(&s->lock);
1161                 ast_free(s);
1162         } else
1163                 ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
1164         ast_mutex_unlock(&sessionlock);
1165         return;
1166 }
1167
1168 /* Return 1 if the session chained link was modified */
1169 static int send_retransmit(struct unistimsession *pte)
1170 {
1171         int i;
1172
1173         ast_mutex_lock(&pte->lock);
1174         if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
1175                 if (unistimdebug)
1176                         ast_verb(0, "Too many retransmit - freeing client\n");
1177                 ast_mutex_unlock(&pte->lock);
1178                 close_client(pte);
1179                 return 1;
1180         }
1181         pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
1182
1183         for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
1184                  i < pte->last_buf_available; i++) {
1185                 if (i < 0) {
1186                         ast_log(LOG_WARNING,
1187                                         "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%.4x last_seq_ack = #0x%.4x\n",
1188                                         pte->last_buf_available, pte->seq_server, pte->last_seq_ack);
1189                         continue;
1190                 }
1191
1192                 if (unistimdebug) {
1193                         unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
1194                         unsigned short seq;
1195
1196                         seq = ntohs(sbuf[1]);
1197                         ast_verb(0, "Retransmit slot #%d (seq=#0x%.4x), last ack was #0x%.4x\n", i,
1198                                                 seq, pte->last_seq_ack);
1199                 }
1200                 send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
1201                                           &pte->sout);
1202         }
1203         ast_mutex_unlock(&pte->lock);
1204         return 0;
1205 }
1206
1207 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1208 static void
1209 send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte,
1210                  const char *text)
1211 {
1212         int i;
1213         BUFFSEND;
1214         if (unistimdebug)
1215                 ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
1216         memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
1217         buffsend[10] = pos;
1218         buffsend[11] = inverse;
1219         i = strlen(text);
1220         if (i > TEXT_LENGTH_MAX)
1221                 i = TEXT_LENGTH_MAX;
1222         memcpy(buffsend + 12, text, i);
1223         send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
1224 }
1225
1226 static void send_text_status(struct unistimsession *pte, const char *text)
1227 {
1228         BUFFSEND;
1229         int i;
1230         if (unistimdebug)
1231                 ast_verb(0, "Sending status text\n");
1232         if (pte->device) {
1233                 if (pte->device->status_method == 1) {  /* For new firmware and i2050 soft phone */
1234                         int n = strlen(text);
1235                         /* Must send individual button separately */
1236                         int j;
1237                         for (i = 0, j = 0; i < 4; i++, j += 7) {
1238                                 int pos = 0x08 + (i * 0x20);
1239                                 memcpy(buffsend + SIZE_HEADER, packet_send_status2,
1240                                            sizeof(packet_send_status2));
1241
1242                                 buffsend[9] = pos;
1243                                 memcpy(buffsend + 10, (j < n) ? (text + j) : "       ", 7);
1244                                 send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
1245                         }
1246                         return;
1247                 }
1248         }
1249
1250
1251         memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
1252         i = strlen(text);
1253         if (i > STATUS_LENGTH_MAX)
1254                 i = STATUS_LENGTH_MAX;
1255         memcpy(buffsend + 10, text, i);
1256         send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
1257
1258 }
1259
1260 /* led values in hexa : 0 = bar off, 1 = bar on, 2 = bar 1s on/1s off, 3 = bar 2.5s on/0.5s off
1261  * 4 = bar 0.6s on/0.3s off, 5 = bar 0.5s on/0.5s off, 6 = bar 2s on/0.5s off
1262  * 7 = bar off, 8 = speaker off, 9 = speaker on, 10 = headphone off, 11 = headphone on
1263  * 18 = mute off, 19 mute on */
1264 static void send_led_update(struct unistimsession *pte, unsigned char led)
1265 {
1266         BUFFSEND;
1267         if (unistimdebug)
1268                 ast_verb(0, "Sending led_update (%x)\n", led);
1269         memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1270         buffsend[9] = led;
1271         send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1272 }
1273
1274 /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
1275  * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
1276  * mute = MUTE_OFF, MUTE_ON */
1277 static void
1278 send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume,
1279                                  unsigned char mute)
1280 {
1281         BUFFSEND;
1282         if (unistimdebug)
1283                 ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n", output,
1284                                         volume, mute);
1285         memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1286                    sizeof(packet_send_select_output));
1287         buffsend[9] = output;
1288         if (output == OUTPUT_SPEAKER)
1289                 volume = VOLUME_LOW_SPEAKER;
1290         else
1291                 volume = VOLUME_LOW;
1292         buffsend[10] = volume;
1293         if (mute == MUTE_ON_DISCRET)
1294                 buffsend[11] = MUTE_ON;
1295         else
1296                 buffsend[11] = mute;
1297         send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1298         if (mute == MUTE_OFF)
1299                 send_led_update(pte, 0x18);
1300         else if (mute == MUTE_ON)
1301                 send_led_update(pte, 0x19);
1302         pte->device->mute = mute;
1303         if (output == OUTPUT_HANDSET) {
1304                 if (mute == MUTE_ON)
1305                         change_favorite_icon(pte, FAV_ICON_ONHOLD_BLACK);
1306                 else
1307                         change_favorite_icon(pte, FAV_ICON_OFFHOOK_BLACK);
1308                 send_led_update(pte, 0x08);
1309                 send_led_update(pte, 0x10);
1310         } else if (output == OUTPUT_HEADPHONE) {
1311                 if (mute == MUTE_ON)
1312                         change_favorite_icon(pte, FAV_ICON_HEADPHONES_ONHOLD);
1313                 else
1314                         change_favorite_icon(pte, FAV_ICON_HEADPHONES);
1315                 send_led_update(pte, 0x08);
1316                 send_led_update(pte, 0x11);
1317         } else if (output == OUTPUT_SPEAKER) {
1318                 send_led_update(pte, 0x10);
1319                 send_led_update(pte, 0x09);
1320                 if (pte->device->receiver_state == STATE_OFFHOOK) {
1321                         if (mute == MUTE_ON)
1322                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
1323                         else
1324                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOOK_BLACK);
1325                 } else {
1326                         if (mute == MUTE_ON)
1327                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
1328                         else
1329                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_OFFHOOK_BLACK);
1330                 }
1331         } else
1332                 ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
1333         if (output != pte->device->output)
1334                 pte->device->previous_output = pte->device->output;
1335         pte->device->output = output;
1336 }
1337
1338 static void send_ring(struct unistimsession *pte, char volume, char style)
1339 {
1340         BUFFSEND;
1341         if (unistimdebug)
1342                 ast_verb(0, "Sending ring packet\n");
1343         memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1344         buffsend[24] = style + 0x10;
1345         buffsend[29] = volume * 0x10;
1346         send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1347 }
1348
1349 static void send_no_ring(struct unistimsession *pte)
1350 {
1351         BUFFSEND;
1352         if (unistimdebug)
1353                 ast_verb(0, "Sending no ring packet\n");
1354         memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1355         send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1356 }
1357
1358 static void send_texttitle(struct unistimsession *pte, const char *text)
1359 {
1360         BUFFSEND;
1361         int i;
1362         if (unistimdebug)
1363                 ast_verb(0, "Sending title text\n");
1364         memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1365         i = strlen(text);
1366         if (i > 12)
1367                 i = 12;
1368         memcpy(buffsend + 10, text, i);
1369         send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1370
1371 }
1372
1373 static void send_date_time(struct unistimsession *pte)
1374 {
1375         BUFFSEND;
1376         struct timeval now = ast_tvnow();
1377         struct ast_tm atm = { 0, };
1378
1379         if (unistimdebug)
1380                 ast_verb(0, "Sending Time & Date\n");
1381         memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1382         ast_localtime(&now, &atm, NULL);
1383         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1384         buffsend[11] = (unsigned char) atm.tm_mday;
1385         buffsend[12] = (unsigned char) atm.tm_hour;
1386         buffsend[13] = (unsigned char) atm.tm_min;
1387         send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1388 }
1389
1390 static void send_date_time2(struct unistimsession *pte)
1391 {
1392         BUFFSEND;
1393         struct timeval now = ast_tvnow();
1394         struct ast_tm atm = { 0, };
1395
1396         if (unistimdebug)
1397                 ast_verb(0, "Sending Time & Date #2\n");
1398         memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1399         ast_localtime(&now, &atm, NULL);
1400         if (pte->device)
1401                 buffsend[9] = pte->device->datetimeformat;
1402         else
1403                 buffsend[9] = 61;
1404         buffsend[14] = (unsigned char) atm.tm_mon + 1;
1405         buffsend[15] = (unsigned char) atm.tm_mday;
1406         buffsend[16] = (unsigned char) atm.tm_hour;
1407         buffsend[17] = (unsigned char) atm.tm_min;
1408         send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1409 }
1410
1411 static void send_date_time3(struct unistimsession *pte)
1412 {
1413         BUFFSEND;
1414         struct timeval now = ast_tvnow();
1415         struct ast_tm atm = { 0, };
1416
1417         if (unistimdebug)
1418                 ast_verb(0, "Sending Time & Date #3\n");
1419         memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1420         ast_localtime(&now, &atm, NULL);
1421         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1422         buffsend[11] = (unsigned char) atm.tm_mday;
1423         buffsend[12] = (unsigned char) atm.tm_hour;
1424         buffsend[13] = (unsigned char) atm.tm_min;
1425         send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1426 }
1427
1428 static void send_blink_cursor(struct unistimsession *pte)
1429 {
1430         BUFFSEND;
1431         if (unistimdebug)
1432                 ast_verb(0, "Sending set blink\n");
1433         memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
1434         send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1435         return;
1436 }
1437
1438 /* pos : 0xab (a=0/2/4 = line ; b = row) */
1439 static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
1440 {
1441         BUFFSEND;
1442         if (unistimdebug)
1443                 ast_verb(0, "Sending set cursor position\n");
1444         memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1445                    sizeof(packet_send_set_pos_cursor));
1446         buffsend[11] = pos;
1447         send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1448         return;
1449 }
1450
1451 static void rcv_resume_connection_with_server(struct unistimsession *pte)
1452 {
1453         BUFFSEND;
1454         if (unistimdebug) {
1455                 ast_verb(0, "ResumeConnectionWithServer received\n");
1456                 ast_verb(0, "Sending packet_send_query_mac_address\n");
1457         }
1458         memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1459                    sizeof(packet_send_query_mac_address));
1460         send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1461         return;
1462 }
1463
1464 static int unistim_register(struct unistimsession *s)
1465 {
1466         struct unistim_device *d;
1467
1468         ast_mutex_lock(&devicelock);
1469         d = devices;
1470         while (d) {
1471                 if (!strcasecmp(s->macaddr, d->id)) {
1472                         /* XXX Deal with IP authentication */
1473                         s->device = d;
1474                         d->session = s;
1475                         d->codec_number = DEFAULT_CODEC;
1476                         d->pos_fav = 0;
1477                         d->missed_call = 0;
1478                         d->receiver_state = STATE_ONHOOK;
1479                         break;
1480                 }
1481                 d = d->next;
1482         }
1483         ast_mutex_unlock(&devicelock);
1484
1485         if (!d)
1486                 return 0;
1487
1488         return 1;
1489 }
1490
1491 static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
1492 {
1493         struct ast_format_cap *tmp = src->cap;
1494         memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
1495         src->cap = tmp;
1496         ast_format_cap_copy(src->cap, dst->cap);
1497 }
1498
1499 static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
1500 {
1501         if (!l) {
1502                 return NULL;
1503         }
1504         l->cap = ast_format_cap_destroy(l->cap);
1505         ast_free(l);
1506         return NULL;
1507 }
1508
1509 static struct unistim_line *unistim_line_alloc(void)
1510 {
1511         struct unistim_line *l;
1512         if (!(l = ast_calloc(1, sizeof(*l)))) {
1513                 return NULL;
1514         }
1515
1516         if (!(l->cap = ast_format_cap_alloc_nolock())) {
1517                 ast_free(l);
1518                 return NULL;
1519         }
1520         return l;
1521 }
1522
1523 static int alloc_sub(struct unistim_line *l, int x)
1524 {
1525         struct unistim_subchannel *sub;
1526         if (!(sub = ast_calloc(1, sizeof(*sub))))
1527                 return 0;
1528
1529         if (unistimdebug)
1530                 ast_verb(3, "Allocating UNISTIM subchannel #%d on %s@%s ptr=%p\n", x, l->name, l->parent->name, sub);
1531         sub->parent = l;
1532         sub->subtype = x;
1533         l->subs[x] = sub;
1534         ast_mutex_init(&sub->lock);
1535         return 1;
1536 }
1537
1538 static int unalloc_sub(struct unistim_line *p, int x)
1539 {
1540         if (!x) {
1541                 ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name,
1542                                 p->parent->name);
1543                 return -1;
1544         }
1545         if (unistimdebug)
1546                 ast_debug(1, "Released sub %d of channel %s@%s\n", x, p->name,
1547                                 p->parent->name);
1548         ast_mutex_destroy(&p->lock);
1549         ast_free(p->subs[x]);
1550         p->subs[x] = 0;
1551         return 0;
1552 }
1553
1554 static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
1555 {
1556         BUFFSEND;
1557         int tmp, i = 0;
1558         char addrmac[19];
1559         int res = 0;
1560         if (unistimdebug)
1561                 ast_verb(0, "Mac Address received : ");
1562         for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
1563                 sprintf(&addrmac[i], "%.2x", (unsigned char) buf[tmp]);
1564                 i += 2;
1565         }
1566         if (unistimdebug)
1567                 ast_verb(0, "%s\n", addrmac);
1568         strcpy(pte->macaddr, addrmac);
1569         res = unistim_register(pte);
1570         if (!res) {
1571                 switch (autoprovisioning) {
1572                 case AUTOPROVISIONING_NO:
1573                         ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
1574                         pte->state = STATE_AUTHDENY;
1575                         break;
1576                 case AUTOPROVISIONING_YES:
1577                         {
1578                                 struct unistim_device *d, *newd;
1579                                 struct unistim_line *newl;
1580                                 if (unistimdebug)
1581                                         ast_verb(0, "New phone, autoprovisioning on\n");
1582                                 /* First : locate the [template] section */
1583                                 ast_mutex_lock(&devicelock);
1584                                 d = devices;
1585                                 while (d) {
1586                                         if (!strcasecmp(d->name, "template")) {
1587                                                 /* Found, cloning this entry */
1588                                                 if (!(newd = ast_malloc(sizeof(*newd)))) {
1589                                                         ast_mutex_unlock(&devicelock);
1590                                                         return;
1591                                                 }
1592
1593                                                 memcpy(newd, d, sizeof(*newd));
1594                                                 if (!(newl = unistim_line_alloc())) {
1595                                                         ast_free(newd);
1596                                                         ast_mutex_unlock(&devicelock);
1597                                                         return;
1598                                                 }
1599
1600                                                 unistim_line_copy(d->lines, newl);
1601                                                 if (!alloc_sub(newl, SUB_REAL)) {
1602                                                         ast_free(newd);
1603                                                         unistim_line_destroy(newl);
1604                                                         ast_mutex_unlock(&devicelock);
1605                                                         return;
1606                                                 }
1607                                                 /* Ok, now updating some fields */
1608                                                 ast_copy_string(newd->id, addrmac, sizeof(newd->id));
1609                                                 ast_copy_string(newd->name, addrmac, sizeof(newd->name));
1610                                                 if (newd->extension == EXTENSION_NONE)
1611                                                         newd->extension = EXTENSION_ASK;
1612                                                 newd->lines = newl;
1613                                                 newd->receiver_state = STATE_ONHOOK;
1614                                                 newd->session = pte;
1615                                                 newd->to_delete = -1;
1616                                                 pte->device = newd;
1617                                                 newd->next = NULL;
1618                                                 newl->parent = newd;
1619                                                 strcpy(newl->name, d->lines->name);
1620                                                 snprintf(d->lines->name, sizeof(d->lines->name), "%d",
1621                                                                  atoi(d->lines->name) + 1);
1622                                                 snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
1623                                                                  newl->name, newd->name);
1624                                                 /* Go to the end of the linked chain */
1625                                                 while (d->next) {
1626                                                         d = d->next;
1627                                                 }
1628                                                 d->next = newd;
1629                                                 d = newd;
1630                                                 break;
1631                                         }
1632                                         d = d->next;
1633                                 }
1634                                 ast_mutex_unlock(&devicelock);
1635                                 if (!d) {
1636                                         ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
1637                                         pte->state = STATE_AUTHDENY;
1638                                 }
1639                         }
1640                         break;
1641                 case AUTOPROVISIONING_TN:
1642                         pte->state = STATE_AUTHDENY;
1643                         break;
1644                 case AUTOPROVISIONING_DB:
1645                         ast_log(LOG_WARNING,
1646                                         "Autoprovisioning with database is not yet functional\n");
1647                         break;
1648                 default:
1649                         ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %d\n",
1650                                         autoprovisioning);
1651                 }
1652         }
1653         if (pte->state != STATE_AUTHDENY) {
1654                 ast_verb(3, "Device '%s' successfuly registered\n", pte->device->name);
1655                 switch (pte->device->extension) {
1656                 case EXTENSION_NONE:
1657                         pte->state = STATE_MAINPAGE;
1658                         break;
1659                 case EXTENSION_ASK:
1660                         /* Checking if we already have an extension number */
1661                         if (ast_strlen_zero(pte->device->extension_number))
1662                                 pte->state = STATE_EXTENSION;
1663                         else {
1664                                 /* Yes, because of a phone reboot. We don't ask again for the TN */
1665                                 if (RegisterExtension(pte))
1666                                         pte->state = STATE_EXTENSION;
1667                                 else
1668                                         pte->state = STATE_MAINPAGE;
1669                         }
1670                         break;
1671                 case EXTENSION_LINE:
1672                         ast_copy_string(pte->device->extension_number, pte->device->lines->name,
1673                                                         sizeof(pte->device->extension_number));
1674                         if (RegisterExtension(pte))
1675                                 pte->state = STATE_EXTENSION;
1676                         else
1677                                 pte->state = STATE_MAINPAGE;
1678                         break;
1679                 case EXTENSION_TN:
1680                         /* If we are here, it's because of a phone reboot */
1681                         pte->state = STATE_MAINPAGE;
1682                         break;
1683                 default:
1684                         ast_log(LOG_WARNING, "Internal error, extension value unknown : %d\n",
1685                                         pte->device->extension);
1686                         pte->state = STATE_AUTHDENY;
1687                         break;
1688                 }
1689         }
1690         if (pte->state == STATE_EXTENSION) {
1691                 if (pte->device->extension != EXTENSION_TN)
1692                         pte->device->extension = EXTENSION_ASK;
1693                 pte->device->extension_number[0] = '\0';
1694         }
1695         if (unistimdebug)
1696                 ast_verb(0, "\nSending S1\n");
1697         memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
1698         send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
1699
1700         if (unistimdebug)
1701                 ast_verb(0, "Sending query_basic_manager_04\n");
1702         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
1703                    sizeof(packet_send_query_basic_manager_04));
1704         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
1705
1706         if (unistimdebug)
1707                 ast_verb(0, "Sending query_basic_manager_10\n");
1708         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
1709                    sizeof(packet_send_query_basic_manager_10));
1710         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
1711
1712         send_date_time(pte);
1713         return;
1714 }
1715
1716 static int write_entry_history(struct unistimsession *pte, FILE * f, char c, char *line1)
1717 {
1718         if (fwrite(&c, 1, 1, f) != 1) {
1719                 display_last_error("Unable to write history log header.");
1720                 return -1;
1721         }
1722         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
1723                 display_last_error("Unable to write history entry - date.");
1724                 return -1;
1725         }
1726         if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
1727                 display_last_error("Unable to write history entry - callerid.");
1728                 return -1;
1729         }
1730         if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
1731                 display_last_error("Unable to write history entry - callername.");
1732                 return -1;
1733         }
1734         return 0;
1735 }
1736
1737 static int write_history(struct unistimsession *pte, char way, char ismissed)
1738 {
1739         char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
1740         char line1[TEXT_LENGTH_MAX + 1];
1741         char count = 0, *histbuf;
1742         int size;
1743         FILE *f, *f2;
1744         struct timeval now = ast_tvnow();
1745         struct ast_tm atm = { 0, };
1746
1747         if (!pte->device)
1748                 return -1;
1749         if (!pte->device->callhistory)
1750                 return 0;
1751         if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
1752                 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
1753                                 pte->device->name);
1754                 return -1;
1755         }
1756
1757         snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
1758         if (ast_mkdir(tmp, 0770)) {
1759                 if (errno != EEXIST) {
1760                         display_last_error("Unable to create directory for history");
1761                         return -1;
1762                 }
1763         }
1764
1765         ast_localtime(&now, &atm, NULL);
1766         if (ismissed) {
1767                 if (way == 'i')
1768                         strcpy(tmp2, "Miss");
1769                 else
1770                         strcpy(tmp2, "Fail");
1771         } else
1772                 strcpy(tmp2, "Answ");
1773         snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
1774                          atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
1775                          atm.tm_min, atm.tm_sec, tmp2);
1776
1777         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
1778                          USTM_LOG_DIR, pte->device->name, way);
1779         if ((f = fopen(tmp, "r"))) {
1780                 struct stat bufstat;
1781
1782                 if (stat(tmp, &bufstat)) {
1783                         display_last_error("Unable to stat history log.");
1784                         fclose(f);
1785                         return -1;
1786                 }
1787                 size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
1788                 if (bufstat.st_size != size) {
1789                         ast_log(LOG_WARNING,
1790                                         "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
1791                                         tmp, (int) bufstat.st_size, size);
1792                         fclose(f);
1793                         f = NULL;
1794                         count = 1;
1795                 }
1796         }
1797
1798         /* If we can't open the log file, we create a brand new one */
1799         if (!f) {
1800                 char c = 1;
1801                 int i;
1802
1803                 if ((errno != ENOENT) && (count == 0)) {
1804                         display_last_error("Unable to open history log.");
1805                         return -1;
1806                 }
1807                 f = fopen(tmp, "w");
1808                 if (!f) {
1809                         display_last_error("Unable to create history log.");
1810                         return -1;
1811                 }
1812                 if (write_entry_history(pte, f, c, line1)) {
1813                         fclose(f);
1814                         return -1;
1815                 }
1816                 memset(line1, ' ', TEXT_LENGTH_MAX);
1817                 for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
1818                         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
1819                                 display_last_error("Unable to write history entry - stuffing.");
1820                                 fclose(f);
1821                                 return -1;
1822                         }
1823                 }
1824                 if (fclose(f))
1825                         display_last_error("Unable to close history - creation.");
1826                 return 0;
1827         }
1828         /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
1829         if (fread(&count, 1, 1, f) != 1) {
1830                 display_last_error("Unable to read history header.");
1831                 fclose(f);
1832                 return -1;
1833         }
1834         if (count > MAX_ENTRY_LOG) {
1835                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
1836                                 count, MAX_ENTRY_LOG);
1837                 fclose(f);
1838                 return -1;
1839         }
1840         snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
1841                          USTM_LOG_DIR, pte->device->name, way);
1842         if (!(f2 = fopen(tmp2, "w"))) {
1843                 display_last_error("Unable to create temporary history log.");
1844                 fclose(f);
1845                 return -1;
1846         }
1847
1848         if (++count > MAX_ENTRY_LOG)
1849                 count = MAX_ENTRY_LOG;
1850
1851         if (write_entry_history(pte, f2, count, line1)) {
1852                 fclose(f);
1853                 fclose(f2);
1854                 return -1;
1855         }
1856
1857         size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
1858         if (!(histbuf = ast_malloc(size))) {
1859                 fclose(f);
1860                 fclose(f2);
1861                 return -1;
1862         }
1863
1864         if (fread(histbuf, size, 1, f) != 1) {
1865                 ast_free(histbuf);
1866                 fclose(f);
1867                 fclose(f2);
1868                 display_last_error("Unable to read previous history entries.");
1869                 return -1;
1870         }
1871         if (fwrite(histbuf, size, 1, f2) != 1) {
1872                 ast_free(histbuf);
1873                 fclose(f);
1874                 fclose(f2);
1875                 display_last_error("Unable to write previous history entries.");
1876                 return -1;
1877         }
1878         ast_free(histbuf);
1879         if (fclose(f))
1880                 display_last_error("Unable to close history log.");
1881         if (fclose(f2))
1882                 display_last_error("Unable to close temporary history log.");
1883         if (unlink(tmp))
1884                 display_last_error("Unable to remove old history log.");
1885         if (rename(tmp2, tmp))
1886                 display_last_error("Unable to rename new history log.");
1887         return 0;
1888 }
1889
1890 static void cancel_dial(struct unistimsession *pte)
1891 {
1892         send_no_ring(pte);
1893         pte->device->missed_call++;
1894         write_history(pte, 'i', 1);
1895         show_main_page(pte);
1896         return;
1897 }
1898
1899 static void swap_subs(struct unistim_line *p, int a, int b)
1900 {
1901 /*  struct ast_channel *towner; */
1902         struct ast_rtp_instance *rtp;
1903         int fds;
1904
1905         if (unistimdebug)
1906                 ast_verb(0, "Swapping %d and %d\n", a, b);
1907
1908         if ((!p->subs[a]->owner) || (!p->subs[b]->owner)) {
1909                 ast_log(LOG_WARNING,
1910                                 "Attempted to swap subchannels with a null owner : sub #%d=%p sub #%d=%p\n",
1911                                 a, p->subs[a]->owner, b, p->subs[b]->owner);
1912                 return;
1913         }
1914         rtp = p->subs[a]->rtp;
1915         p->subs[a]->rtp = p->subs[b]->rtp;
1916         p->subs[b]->rtp = rtp;
1917
1918         fds = p->subs[a]->owner->fds[0];
1919         p->subs[a]->owner->fds[0] = p->subs[b]->owner->fds[0];
1920         p->subs[b]->owner->fds[0] = fds;
1921
1922         fds = p->subs[a]->owner->fds[1];
1923         p->subs[a]->owner->fds[1] = p->subs[b]->owner->fds[1];
1924         p->subs[b]->owner->fds[1] = fds;
1925 }
1926
1927 static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
1928 {
1929         int res = 0;
1930         struct ast_channel
1931          *chana = NULL, *chanb = NULL, *bridgea = NULL, *bridgeb = NULL, *peera =
1932                 NULL, *peerb = NULL, *peerc = NULL;
1933
1934         if (!p1->owner || !p2->owner) {
1935                 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
1936                 return -1;
1937         }
1938         chana = p1->owner;
1939         chanb = p2->owner;
1940         bridgea = ast_bridged_channel(chana);
1941         bridgeb = ast_bridged_channel(chanb);
1942
1943         if (bridgea) {
1944                 peera = chana;
1945                 peerb = chanb;
1946                 peerc = bridgea;
1947         } else if (bridgeb) {
1948                 peera = chanb;
1949                 peerb = chana;
1950                 peerc = bridgeb;
1951         }
1952
1953         if (peera && peerb && peerc && (peerb != peerc)) {
1954                 /*ast_quiet_chan(peera);
1955                    ast_quiet_chan(peerb);
1956                    ast_quiet_chan(peerc);
1957                    ast_quiet_chan(peerd); */
1958
1959                 if (peera->cdr && peerb->cdr) {
1960                         peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
1961                 } else if (peera->cdr) {
1962                         peerb->cdr = peera->cdr;
1963                 }
1964                 peera->cdr = NULL;
1965
1966                 if (peerb->cdr && peerc->cdr) {
1967                         peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
1968                 } else if (peerc->cdr) {
1969                         peerb->cdr = peerc->cdr;
1970                 }
1971                 peerc->cdr = NULL;
1972
1973                 if (ast_channel_masquerade(peerb, peerc)) {
1974                         ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name,
1975                                         peerc->name);
1976                         res = -1;
1977                 }
1978                 return res;
1979         } else {
1980                 ast_log(LOG_NOTICE,
1981                                 "Transfer attempted with no appropriate bridged calls to transfer\n");
1982                 if (chana)
1983                         ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
1984                 if (chanb)
1985                         ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
1986                 return -1;
1987         }
1988         return 0;
1989 }
1990
1991 void change_callerid(struct unistimsession *pte, int type, char *callerid)
1992 {
1993         char *data;
1994         int size;
1995
1996         if (type)
1997                 data = pte->device->lst_cnm;
1998         else
1999                 data = pte->device->lst_cid;
2000
2001         /* This is very nearly strncpy(), except that the remaining buffer
2002          * is padded with ' ', instead of '\0' */
2003         memset(data, ' ', TEXT_LENGTH_MAX);
2004         size = strlen(callerid);
2005         if (size > TEXT_LENGTH_MAX)
2006                 size = TEXT_LENGTH_MAX;
2007         memcpy(data, callerid, size);
2008 }
2009
2010 static void close_call(struct unistimsession *pte)
2011 {
2012         struct unistim_subchannel *sub;
2013         struct unistim_line *l = pte->device->lines;
2014
2015         sub = pte->device->lines->subs[SUB_REAL];
2016         send_stop_timer(pte);
2017         if (sub->owner) {
2018                 sub->alreadygone = 1;
2019                 if (l->subs[SUB_THREEWAY]) {
2020                         l->subs[SUB_THREEWAY]->alreadygone = 1;
2021                         if (attempt_transfer(sub, l->subs[SUB_THREEWAY]) < 0)
2022                                 ast_verb(0, "attempt_transfer failed.\n");
2023                 } else
2024                         ast_queue_hangup(sub->owner);
2025         } else {
2026                 if (l->subs[SUB_THREEWAY]) {
2027                         if (l->subs[SUB_THREEWAY]->owner)
2028                                 ast_queue_hangup_with_cause(l->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
2029                         else
2030                                 ast_log(LOG_WARNING, "threeway sub without owner\n");
2031                 } else
2032                         ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2033                                                 sub->parent->parent->name, sub->subtype);
2034         }
2035         change_callerid(pte, 0, pte->device->redial_number);
2036         change_callerid(pte, 1, "");
2037         write_history(pte, 'o', pte->device->missed_call);
2038         pte->device->missed_call = 0;
2039         show_main_page(pte);
2040         return;
2041 }
2042
2043 static void IgnoreCall(struct unistimsession *pte)
2044 {
2045         send_no_ring(pte);
2046         return;
2047 }
2048
2049 static void *unistim_ss(void *data)
2050 {
2051         struct ast_channel *chan = data;
2052         struct unistim_subchannel *sub = chan->tech_pvt;
2053         struct unistim_line *l = sub->parent;
2054         struct unistimsession *s = l->parent->session;
2055         int res;
2056
2057         ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->subtype, s->device->phone_number);
2058         ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten));
2059         ast_copy_string(s->device->redial_number, s->device->phone_number,
2060                                         sizeof(s->device->redial_number));
2061         ast_setstate(chan, AST_STATE_RING);
2062         res = ast_pbx_run(chan);
2063         if (res) {
2064                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2065                 send_tone(s, 1000, 0);;
2066         }
2067         return NULL;
2068 }
2069
2070 static void start_rtp(struct unistim_subchannel *sub)
2071 {
2072         BUFFSEND;
2073         struct sockaddr_in us = { 0, };
2074         struct sockaddr_in public = { 0, };
2075         struct sockaddr_in sin = { 0, };
2076         int codec;
2077         struct sockaddr_in sout = { 0, };
2078         struct ast_sockaddr us_tmp;
2079         struct ast_sockaddr sin_tmp;
2080         struct ast_sockaddr sout_tmp;
2081
2082         /* Sanity checks */
2083         if (!sub) {
2084                 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2085                 return;
2086         }
2087         if (!sub->parent) {
2088                 ast_log(LOG_WARNING, "start_rtp with a null line !\n");
2089                 return;
2090         }
2091         if (!sub->parent->parent) {
2092                 ast_log(LOG_WARNING, "start_rtp with a null device !\n");
2093                 return;
2094         }
2095         if (!sub->parent->parent->session) {
2096                 ast_log(LOG_WARNING, "start_rtp with a null session !\n");
2097                 return;
2098         }
2099         sout = sub->parent->parent->session->sout;
2100
2101         ast_mutex_lock(&sub->lock);
2102         /* Allocate the RTP */
2103         if (unistimdebug)
2104                 ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2105         ast_sockaddr_from_sin(&sout_tmp, &sout);
2106         sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
2107         if (!sub->rtp) {
2108                 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2109                                 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2110                 ast_mutex_unlock(&sub->lock);
2111                 return;
2112         }
2113         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
2114         if (sub->owner) {
2115                 sub->owner->fds[0] = ast_rtp_instance_fd(sub->rtp, 0);
2116                 sub->owner->fds[1] = ast_rtp_instance_fd(sub->rtp, 1);
2117         }
2118         ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2119         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
2120
2121         /* Create the RTP connection */
2122         ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
2123         ast_sockaddr_to_sin(&us_tmp, &us);
2124         sin.sin_family = AF_INET;
2125         /* Setting up RTP for our side */
2126         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2127                    sizeof(sin.sin_addr));
2128         sin.sin_port = htons(sub->parent->parent->rtp_port);
2129         ast_sockaddr_from_sin(&sin_tmp, &sin);
2130         ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
2131         if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &sub->owner->readformat))) {
2132                 struct ast_format tmpfmt;
2133                 char tmp[256];
2134                 ast_best_codec(sub->owner->nativeformats, &tmpfmt);
2135                 ast_log(LOG_WARNING,
2136                                 "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
2137                                 ast_getformatname(&sub->owner->readformat),
2138                                 ast_getformatname(&tmpfmt),
2139                                 ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats));
2140                 ast_format_copy(&sub->owner->readformat, &tmpfmt);
2141                 ast_format_copy(&sub->owner->writeformat, &tmpfmt);
2142         }
2143         codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &sub->owner->readformat, 0);
2144         /* Setting up RTP of the phone */
2145         if (public_ip.sin_family == 0)  /* NAT IP override ?   */
2146                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2147         else
2148                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2149         if (unistimdebug) {
2150                 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
2151                          ast_inet_ntoa(us.sin_addr),
2152                          htons(us.sin_port), ast_getformatname(&sub->owner->readformat));
2153                 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2154                                         ast_inet_ntoa(public.sin_addr));
2155         }
2156         if ((sub->owner->readformat.id == AST_FORMAT_ULAW) ||
2157                 (sub->owner->readformat.id == AST_FORMAT_ALAW)) {
2158                 if (unistimdebug)
2159                         ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2160                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2161                            sizeof(packet_send_rtp_packet_size));
2162                 buffsend[10] = (int) codec & 0xffffffffLL;
2163                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend,
2164                                    sub->parent->parent->session);
2165         }
2166         if (unistimdebug)
2167                 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2168         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2169                    sizeof(packet_send_jitter_buffer_conf));
2170         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend,
2171                            sub->parent->parent->session);
2172         if (sub->parent->parent->rtp_method != 0) {
2173                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2174
2175                 if (unistimdebug)
2176                         ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n",
2177                                                 sub->parent->parent->rtp_method);
2178                 if (sub->parent->parent->rtp_method == 3)
2179                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2180                                    sizeof(packet_send_open_audio_stream_tx3));
2181                 else
2182                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2183                                    sizeof(packet_send_open_audio_stream_tx));
2184                 if (sub->parent->parent->rtp_method != 2) {
2185                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2186                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2187                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2188                         buffsend[23] = (rtcpsin_port & 0x00ff);
2189                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2190                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2191                         buffsend[24] = (us.sin_port & 0x00ff);
2192                         buffsend[27] = (rtcpsin_port & 0x00ff);
2193                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2194                 } else {
2195                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2196                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2197                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2198                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2199                         buffsend[19] = (us.sin_port & 0x00ff);
2200                         buffsend[11] = codec;
2201                 }
2202                 buffsend[12] = codec;
2203                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend,
2204                                    sub->parent->parent->session);
2205
2206                 if (unistimdebug)
2207                         ast_verb(0, "Sending OpenAudioStreamRX\n");
2208                 if (sub->parent->parent->rtp_method == 3)
2209                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2210                                    sizeof(packet_send_open_audio_stream_rx3));
2211                 else
2212                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2213                                    sizeof(packet_send_open_audio_stream_rx));
2214                 if (sub->parent->parent->rtp_method != 2) {
2215                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2216                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2217                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2218                         buffsend[23] = (rtcpsin_port & 0x00ff);
2219                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2220                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2221                         buffsend[24] = (us.sin_port & 0x00ff);
2222                         buffsend[27] = (rtcpsin_port & 0x00ff);
2223                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2224                 } else {
2225                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2226                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2227                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2228                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2229                         buffsend[19] = (us.sin_port & 0x00ff);
2230                         buffsend[12] = codec;
2231                 }
2232                 buffsend[11] = codec;
2233                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend,
2234                                    sub->parent->parent->session);
2235         } else {
2236                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2237
2238                 if (unistimdebug)
2239                         ast_verb(0, "Sending packet_send_call default method\n");
2240
2241                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2242                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2243                 /* Destination port when sending RTP */
2244                 buffsend[49] = (us.sin_port & 0x00ff);
2245                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2246                 /* Destination port when sending RTCP */
2247                 buffsend[52] = (rtcpsin_port & 0x00ff);
2248                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2249                 /* Codec */
2250                 buffsend[40] = codec;
2251                 buffsend[41] = codec;
2252                 if (sub->owner->readformat.id == AST_FORMAT_ULAW)
2253                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2254                 else if (sub->owner->readformat.id == AST_FORMAT_ALAW)
2255                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2256                 else if (sub->owner->readformat.id == AST_FORMAT_G723_1)
2257                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2258                 else if (sub->owner->readformat.id == AST_FORMAT_G729A)
2259                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2260                 else
2261                         ast_log(LOG_WARNING, "Unsupported codec %s!\n",
2262                                         ast_getformatname(&sub->owner->readformat));
2263                 /* Source port for transmit RTP and Destination port for receiving RTP */
2264                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2265                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2266                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2267                 buffsend[48] = (rtcpsin_port & 0x00ff);
2268                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend,
2269                                    sub->parent->parent->session);
2270         }
2271         ast_mutex_unlock(&sub->lock);
2272 }
2273
2274 static void SendDialTone(struct unistimsession *pte)
2275 {
2276         int i;
2277         /* No country defined ? Using US tone */
2278         if (ast_strlen_zero(pte->device->country)) {
2279                 if (unistimdebug)
2280                         ast_verb(0, "No country defined, using US tone\n");
2281                 send_tone(pte, 350, 440);
2282                 return;
2283         }
2284         if (strlen(pte->device->country) != 2) {
2285                 if (unistimdebug)
2286                         ast_verb(0, "Country code != 2 char, using US tone\n");
2287                 send_tone(pte, 350, 440);
2288                 return;
2289         }
2290         i = 0;
2291         while (frequency[i].freq1) {
2292                 if ((frequency[i].country[0] == pte->device->country[0]) &&
2293                         (frequency[i].country[1] == pte->device->country[1])) {
2294                         if (unistimdebug)
2295                                 ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
2296                                                         frequency[i].country, frequency[i].freq1, frequency[i].freq2);
2297                         send_tone(pte, frequency[i].freq1, frequency[i].freq2);
2298                 }
2299                 i++;
2300         }
2301 }
2302
2303 static void handle_dial_page(struct unistimsession *pte)
2304 {
2305         pte->state = STATE_DIALPAGE;
2306         if (pte->device->call_forward[0] == -1) {
2307                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2308                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
2309                 send_text_status(pte, "ForwardCancel BackSpcErase");
2310                 if (pte->device->call_forward[1] != 0) {
2311                         char tmp[TEXT_LENGTH_MAX + 1];
2312
2313                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2314                                                         sizeof(pte->device->phone_number));
2315                         pte->device->size_phone_number = strlen(pte->device->phone_number);
2316                         if (pte->device->size_phone_number > 15)
2317                                 pte->device->size_phone_number = 15;
2318                         strcpy(tmp, "Number : ...............");
2319                         memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
2320
2321                         if (pte->device->height == 1) {
2322                                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp);
2323                                 send_blink_cursor(pte);
2324                                 send_cursor_pos(pte,
2325                                                   (unsigned char) (TEXT_LINE0 + 0x09 +
2326                                                                                    pte->device->size_phone_number));
2327                         } else {
2328                                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
2329                                 send_blink_cursor(pte);
2330                                 send_cursor_pos(pte,
2331                                                   (unsigned char) (TEXT_LINE2 + 0x09 +
2332                                                                                    pte->device->size_phone_number));
2333                         }
2334
2335                         send_led_update(pte, 0);
2336                         return;
2337                 }
2338         } else {
2339                 if ((pte->device->output == OUTPUT_HANDSET) &&
2340                         (pte->device->receiver_state == STATE_ONHOOK))
2341                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2342                 else
2343                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2344                 SendDialTone(pte);
2345
2346                 if (pte->device->height > 1) {
2347                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
2348                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
2349                 }
2350                 send_text_status(pte, "Call   Redial BackSpcErase");
2351         }
2352
2353         if (pte->device->height == 1) {
2354                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ...............");
2355                 send_blink_cursor(pte);
2356                 send_cursor_pos(pte, TEXT_LINE0 + 0x09);
2357         } else {
2358                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2359                 send_blink_cursor(pte);
2360                 send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2361         }
2362         pte->device->size_phone_number = 0;
2363         pte->device->phone_number[0] = 0;
2364         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
2365         Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
2366         pte->device->missed_call = 0;
2367         send_led_update(pte, 0);
2368         return;
2369 }
2370
2371 /* Step 1 : Music On Hold for peer, Dialing screen for us */
2372 static void TransferCallStep1(struct unistimsession *pte)
2373 {
2374         struct unistim_subchannel *sub;
2375         struct unistim_line *p = pte->device->lines;
2376
2377         sub = p->subs[SUB_REAL];
2378
2379         if (!sub->owner) {
2380                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2381                 return;
2382         }
2383         if (p->subs[SUB_THREEWAY]) {
2384                 if (unistimdebug)
2385                         ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
2386                 if (p->subs[SUB_THREEWAY]->owner)
2387                         ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
2388                 else
2389                         ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
2390                 return;
2391         }
2392         /* Start music on hold if appropriate */
2393         if (pte->device->moh)
2394                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
2395         else {
2396                 if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
2397                         ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
2398                                                   pte->device->lines->musicclass, NULL);
2399                         pte->device->moh = 1;
2400                 } else {
2401                         ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
2402                         return;
2403                 }
2404         }
2405         /* Silence our channel */
2406         if (!pte->device->silence_generator) {
2407                 pte->device->silence_generator =
2408                         ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
2409                 if (pte->device->silence_generator == NULL)
2410                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2411                 else if (unistimdebug)
2412                         ast_verb(0, "Starting silence generator\n");
2413         }
2414         handle_dial_page(pte);
2415 }
2416
2417 /* From phone to PBX */
2418 static void HandleCallOutgoing(struct unistimsession *s)
2419 {
2420         struct ast_channel *c;
2421         struct unistim_subchannel *sub;
2422         pthread_t t;
2423         s->state = STATE_CALL;
2424         sub = s->device->lines->subs[SUB_REAL];
2425         if (!sub) {
2426                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2427                 return;
2428         }
2429         if (!sub->owner) {                    /* A call is already in progress ? */
2430                 c = unistim_new(sub, AST_STATE_DOWN, NULL);   /* No, starting a new one */
2431                 if (c) {
2432                         /* Need to start RTP before calling ast_pbx_run */
2433                         if (!sub->rtp)
2434                                 start_rtp(sub);
2435                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2436
2437                         if (s->device->height == 1) {
2438                                 send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
2439                         } else {
2440                                 send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
2441                                 send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2442                                 send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2443                         }
2444                         send_text_status(s, "Hangup");
2445
2446                         /* start switch */
2447                         if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
2448                                 display_last_error("Unable to create switch thread");
2449                                 ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
2450                         }
2451                 } else
2452                         ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
2453                                         sub->parent->name, s->device->name);
2454         } else {                                        /* We already have a call, so we switch in a threeway call */
2455
2456                 if (s->device->moh) {
2457                         struct unistim_subchannel *subchannel;
2458                         struct unistim_line *p = s->device->lines;
2459                         subchannel = p->subs[SUB_REAL];
2460
2461                         if (!subchannel->owner) {
2462                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2463                                 return;
2464                         }
2465                         if (p->subs[SUB_THREEWAY]) {
2466                                 ast_log(LOG_WARNING,
2467                                                 "Can't transfer while an another transfer is taking place\n");
2468                                 return;
2469                         }
2470                         if (!alloc_sub(p, SUB_THREEWAY)) {
2471                                 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
2472                                 return;
2473                         }
2474                         /* Stop the silence generator */
2475                         if (s->device->silence_generator) {
2476                                 if (unistimdebug)
2477                                         ast_verb(0, "Stopping silence generator\n");
2478                                 ast_channel_stop_silence_generator(subchannel->owner,
2479                                                                                                    s->device->silence_generator);
2480                                 s->device->silence_generator = NULL;
2481                         }
2482                         send_tone(s, 0, 0);
2483                         /* Make new channel */
2484                         c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN, NULL);
2485                         if (!c) {
2486                                 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
2487                                 return;
2488                         }
2489                         /* Swap things around between the three-way and real call */
2490                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
2491                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2492
2493                         if (s->device->height == 1) {
2494                                 send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
2495                         } else {
2496                                 send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
2497                                 send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2498                                 send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2499                         }
2500                         send_text_status(s, "TransfrCancel");
2501
2502                         if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
2503                                 ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
2504                                 ast_hangup(c);
2505                                 return;
2506                         }
2507                         if (unistimdebug)
2508                                 ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n",
2509                                          p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name,
2510                                          p->subs[SUB_THREEWAY]->subtype);
2511                 } else
2512                         ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
2513         }
2514         return;
2515 }
2516
2517 /* From PBX to phone */
2518 static void HandleCallIncoming(struct unistimsession *s)
2519 {
2520         struct unistim_subchannel *sub;
2521         s->state = STATE_CALL;
2522         s->device->missed_call = 0;
2523         send_no_ring(s);
2524         sub = s->device->lines->subs[SUB_REAL];
2525         if (!sub) {
2526                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2527                 return;
2528         } else if (unistimdebug)
2529                 ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
2530                                         s->device->name);
2531         start_rtp(sub);
2532         if (!sub->rtp)
2533                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
2534                                 s->device->name);
2535         ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
2536         send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
2537         send_text_status(s, "Hangup Transf");
2538         send_start_timer(s);
2539
2540         if ((s->device->output == OUTPUT_HANDSET) &&
2541                 (s->device->receiver_state == STATE_ONHOOK))
2542                 send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
2543         else
2544                 send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2545         s->device->start_call_timestamp = time(0);
2546         write_history(s, 'i', 0);
2547         return;
2548 }
2549
2550 static int unistim_do_senddigit(struct unistimsession *pte, char digit)
2551 {
2552         struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
2553         struct unistim_subchannel *sub;
2554         sub = pte->device->lines->subs[SUB_REAL];
2555         if (!sub->owner || sub->alreadygone) {
2556                 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
2557                 return -1;
2558         }
2559
2560         /* Send DTMF indication _before_ playing sounds */
2561         ast_queue_frame(sub->owner, &f);
2562
2563         if (unistimdebug)
2564                 ast_verb(0, "Send Digit %c\n", digit);
2565         switch (digit) {
2566         case '0':
2567                 send_tone(pte, 941, 1336);
2568                 break;
2569         case '1':
2570                 send_tone(pte, 697, 1209);
2571                 break;
2572         case '2':
2573                 send_tone(pte, 697, 1336);
2574                 break;
2575         case '3':
2576                 send_tone(pte, 697, 1477);
2577                 break;
2578         case '4':
2579                 send_tone(pte, 770, 1209);
2580                 break;
2581         case '5':
2582                 send_tone(pte, 770, 1336);
2583                 break;
2584         case '6':
2585                 send_tone(pte, 770, 1477);
2586                 break;
2587         case '7':
2588                 send_tone(pte, 852, 1209);
2589                 break;
2590         case '8':
2591                 send_tone(pte, 852, 1336);
2592                 break;
2593         case '9':
2594                 send_tone(pte, 852, 1477);
2595                 break;
2596         case 'A':
2597                 send_tone(pte, 697, 1633);
2598                 break;
2599         case 'B':
2600                 send_tone(pte, 770, 1633);
2601                 break;
2602         case 'C':
2603                 send_tone(pte, 852, 1633);
2604                 break;
2605         case 'D':
2606                 send_tone(pte, 941, 1633);
2607                 break;
2608         case '*':
2609                 send_tone(pte, 941, 1209);
2610                 break;
2611         case '#':
2612                 send_tone(pte, 941, 1477);
2613                 break;
2614         default:
2615                 send_tone(pte, 500, 2000);
2616         }
2617         usleep(150000);                  /* XXX Less than perfect, blocking an important thread is not a good idea */
2618         send_tone(pte, 0, 0);
2619         return 0;
2620 }
2621
2622 static void key_call(struct unistimsession *pte, char keycode)
2623 {
2624         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2625                 if (keycode == KEY_SHARP)
2626                         keycode = '#';
2627                 else if (keycode == KEY_STAR)
2628                         keycode = '*';
2629                 else
2630                         keycode -= 0x10;
2631                 unistim_do_senddigit(pte, keycode);
2632                 return;
2633         }
2634         switch (keycode) {
2635         case KEY_HANGUP:
2636         case KEY_FUNC1:
2637                 close_call(pte);
2638                 break;
2639         case KEY_FUNC2:
2640                 TransferCallStep1(pte);
2641                 break;
2642         case KEY_HEADPHN:
2643                 if (pte->device->output == OUTPUT_HEADPHONE)
2644                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2645                 else
2646                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2647                 break;
2648         case KEY_LOUDSPK:
2649                 if (pte->device->output != OUTPUT_SPEAKER)
2650                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2651                 else
2652                         send_select_output(pte, pte->device->previous_output, pte->device->volume,
2653                                                          MUTE_OFF);
2654                 break;
2655         case KEY_MUTE:
2656                 if (!pte->device->moh) {
2657                         if (pte->device->mute == MUTE_ON)
2658                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2659                         else
2660                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2661                         break;
2662                 }
2663         case KEY_ONHOLD:
2664                 {
2665                         struct unistim_subchannel *sub;
2666                         struct ast_channel *bridgepeer = NULL;
2667                         sub = pte->device->lines->subs[SUB_REAL];
2668                         if (!sub->owner) {
2669                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2670                                 return;
2671                         }
2672                         if ((bridgepeer = ast_bridged_channel(sub->owner))) {
2673                                 if (pte->device->moh) {
2674                                         ast_moh_stop(bridgepeer);
2675                                         pte->device->moh = 0;
2676                                         send_select_output(pte, pte->device->output, pte->device->volume,
2677                                                                          MUTE_OFF);
2678                                 } else {
2679                                         ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
2680                                         pte->device->moh = 1;
2681                                         send_select_output(pte, pte->device->output, pte->device->volume,
2682                                                                          MUTE_ON);
2683                                 }
2684                         } else
2685                                 ast_log(LOG_WARNING,
2686                                                 "Unable to find peer subchannel for music on hold\n");
2687                         break;
2688                 }
2689         }
2690         return;
2691 }
2692
2693 static void key_ringing(struct unistimsession *pte, char keycode)
2694 {
2695         if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
2696                 HandleCallIncoming(pte);
2697                 return;
2698         }
2699         switch (keycode) {
2700         case KEY_HANGUP:
2701         case KEY_FUNC4:
2702                 IgnoreCall(pte);
2703                 break;
2704         case KEY_FUNC1:
2705                 HandleCallIncoming(pte);
2706                 break;
2707         }
2708         return;
2709 }
2710
2711 static void Keyfavorite(struct unistimsession *pte, char keycode)
2712 {
2713         int fav;
2714
2715         if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
2716                 ast_log(LOG_WARNING, "It's not a favorite key\n");
2717                 return;
2718         }
2719         if (keycode == KEY_FAV0)
2720                 return;
2721         fav = keycode - KEY_FAV0;
2722         if (pte->device->softkeyicon[fav] == 0)
2723                 return;
2724         ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
2725                                         sizeof(pte->device->phone_number));
2726         HandleCallOutgoing(pte);
2727         return;
2728 }
2729
2730 static void key_dial_page(struct unistimsession *pte, char keycode)
2731 {
2732         if (keycode == KEY_FUNC3) {
2733                 if (pte->device->size_phone_number <= 1)
2734                         keycode = KEY_FUNC4;
2735                 else {
2736                         pte->device->size_phone_number -= 2;
2737                         keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
2738                 }
2739         }
2740         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2741                 char tmpbuf[] = "Number : ...............";
2742                 int i = 0;
2743
2744                 if (pte->device->size_phone_number >= 15)
2745                         return;
2746                 if (pte->device->size_phone_number == 0)
2747                         send_tone(pte, 0, 0);
2748                 while (i < pte->device->size_phone_number) {
2749                         tmpbuf[i + 9] = pte->device->phone_number[i];
2750                         i++;
2751                 }
2752                 if (keycode == KEY_SHARP)
2753                         keycode = '#';
2754                 else if (keycode == KEY_STAR)
2755                         keycode = '*';
2756                 else
2757                         keycode -= 0x10;
2758                 tmpbuf[i + 9] = keycode;
2759                 pte->device->phone_number[i] = keycode;
2760                 pte->device->size_phone_number++;
2761                 pte->device->phone_number[i + 1] = 0;
2762                 if (pte->device->height == 1) {
2763                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
2764                 } else {
2765                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2766                 }
2767                 send_blink_cursor(pte);
2768                 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
2769                 return;
2770         }
2771         if (keycode == KEY_FUNC4) {
2772
2773                 pte->device->size_phone_number = 0;
2774                 if (pte->device->height == 1) {
2775                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ...............");
2776                         send_blink_cursor(pte);
2777                         send_cursor_pos(pte, TEXT_LINE0 + 0x09);
2778                 } else {
2779                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2780                         send_blink_cursor(pte);
2781                         send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2782                 }
2783                 return;
2784         }
2785
2786         if (pte->device->call_forward[0] == -1) {
2787                 if (keycode == KEY_FUNC1) {
2788                         ast_copy_string(pte->device->call_forward, pte->device->phone_number,
2789                                                         sizeof(pte->device->call_forward));
2790                         show_main_page(pte);
2791                 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
2792                         pte->device->call_forward[0] = '\0';
2793                         show_main_page(pte);
2794                 }
2795                 return;
2796         }
2797         switch (keycode) {
2798         case KEY_FUNC2:
2799                 if (ast_strlen_zero(pte->device->redial_number))
2800                         break;
2801                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
2802                                                 sizeof(pte->device->phone_number));
2803         case KEY_FUNC1:
2804                 HandleCallOutgoing(pte);
2805                 break;
2806         case KEY_HANGUP:
2807                 if (pte->device->lines->subs[SUB_REAL]->owner) {
2808                         /* Stop the silence generator */
2809                         if (pte->device->silence_generator) {
2810                                 if (unistimdebug)
2811                                         ast_verb(0, "Stopping silence generator\n");
2812                                 ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
2813                                                                                                    owner, pte->device->silence_generator);
2814                                 pte->device->silence_generator = NULL;
2815                         }
2816                         send_tone(pte, 0, 0);
2817                         ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
2818                         pte->device->moh = 0;
2819                         pte->state = STATE_CALL;
2820
2821                         if (pte->device->height == 1) {
2822                                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dial Cancel,back to priv. call.");
2823                         } else {
2824                                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
2825                                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
2826                                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
2827                         }
2828                         send_text_status(pte, "Hangup Transf");
2829                 } else
2830                         show_main_page(pte);
2831                 break;
2832         case KEY_FAV1:
2833         case KEY_FAV2:
2834         case KEY_FAV3:
2835         case KEY_FAV4:
2836         case KEY_FAV5:
2837                 Keyfavorite(pte, keycode);
2838                 break;
2839         case KEY_LOUDSPK:
2840                 if (pte->device->output == OUTPUT_SPEAKER) {
2841                         if (pte->device->receiver_state == STATE_OFFHOOK)
2842                                 send_select_output(pte, pte->device->previous_output, pte->device->volume,
2843                                                                  MUTE_OFF);
2844                         else
2845                                 show_main_page(pte);
2846                 } else
2847                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2848                 break;
2849         case KEY_HEADPHN:
2850                 if (pte->device->output == OUTPUT_HEADPHONE) {
2851                         if (pte->device->receiver_state == STATE_OFFHOOK)
2852                                 send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2853                         else
2854                                 show_main_page(pte);
2855                 } else
2856                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2857                 break;
2858         }
2859         return;
2860 }
2861
2862 #define SELECTCODEC_START_ENTRY_POS 15
2863 #define SELECTCODEC_MAX_LENGTH 2
2864 #define SELECTCODEC_MSG "Codec number : .."
2865 static void HandleSelectCodec(struct unistimsession *pte)
2866 {
2867         char buf[30], buf2[5];
2868
2869         pte->state = STATE_SELECTCODEC;
2870         strcpy(buf, "Using codec ");
2871         sprintf(buf2, "%d", pte->device->codec_number);
2872         strcat(buf, buf2);
2873         strcat(buf, " (G711u=0,");
2874
2875         send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
2876         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
2877         send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2878         send_blink_cursor(pte);
2879         send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2880         pte->size_buff_entry = 0;
2881         send_text_status(pte, "Select BackSpcErase  Cancel");
2882         return;
2883 }
2884
2885 static void key_select_codec(struct unistimsession *pte, char keycode)
2886 {
2887         if (keycode == KEY_FUNC2) {
2888                 if (pte->size_buff_entry <= 1)
2889                         keycode = KEY_FUNC3;
2890                 else {
2891                         pte->size_buff_entry -= 2;
2892                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2893                 }
2894         }
2895         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2896                 char tmpbuf[] = SELECTCODEC_MSG;
2897                 int i = 0;
2898
2899                 if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
2900                         return;
2901
2902                 while (i < pte->size_buff_entry) {
2903                         tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
2904                         i++;
2905                 }
2906                 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
2907                 pte->buff_entry[i] = keycode - 0x10;
2908                 pte->size_buff_entry++;
2909                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
2910                 send_blink_cursor(pte);
2911                 send_cursor_pos(pte,
2912                                           (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
2913                 return;
2914         }
2915
2916         switch (keycode) {
2917         case KEY_FUNC1:
2918                 if (pte->size_buff_entry == 1)
2919                         pte->device->codec_number = pte->buff_entry[0] - 48;
2920                 else if (pte->size_buff_entry == 2)
2921                         pte->device->codec_number =
2922                                 ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
2923                 show_main_page(pte);
2924                 break;
2925         case KEY_FUNC3:
2926                 pte->size_buff_entry = 0;
2927                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2928                 send_blink_cursor(pte);
2929                 send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2930                 break;
2931         case KEY_HANGUP:
2932         case KEY_FUNC4:
2933                 show_main_page(pte);
2934                 break;
2935         }
2936         return;
2937 }
2938
2939 #define SELECTEXTENSION_START_ENTRY_POS 0
2940 #define SELECTEXTENSION_MAX_LENGTH 10
2941 #define SELECTEXTENSION_MSG ".........."
2942 static void ShowExtensionPage(struct unistimsession *pte)
2943 {
2944         pte->state = STATE_EXTENSION;
2945
2946         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
2947         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
2948         send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
2949         send_blink_cursor(pte);
2950         send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
2951         send_text_status(pte, "Enter  BackSpcErase");
2952         pte->size_buff_entry = 0;
2953         return;
2954 }
2955
2956 static void key_select_extension(struct unistimsession *pte, char keycode)
2957 {
2958         if (keycode == KEY_FUNC2) {
2959                 if (pte->size_buff_entry <= 1)
2960                         keycode = KEY_FUNC3;
2961                 else {
2962                         pte->size_buff_entry -= 2;
2963                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2964                 }
2965         }
2966         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2967                 char tmpbuf[] = SELECTEXTENSION_MSG;
2968                 int i = 0;
2969
2970                 if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
2971                         return;
2972
2973                 while (i < pte->size_buff_entry) {
2974                         tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
2975                         i++;
2976                 }
2977                 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
2978                 pte->buff_entry[i] = keycode - 0x10;
2979                 pte->size_buff_entry++;
2980                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2981                 send_blink_cursor(pte);
2982                 send_cursor_pos(pte,
2983                                           (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
2984                                                                            i));
2985                 return;
2986         }
2987
2988         switch (keycode) {
2989         case KEY_FUNC1:
2990                 if (pte->size_buff_entry < 1)
2991                         return;
2992                 if (autoprovisioning == AUTOPROVISIONING_TN) {
2993                         struct unistim_device *d;
2994
2995                         /* First step : looking for this TN in our device list */
2996                         ast_mutex_lock(&devicelock);
2997                         d = devices;
2998                         pte->buff_entry[pte->size_buff_entry] = '\0';
2999                         while (d) {
3000                                 if (d->id[0] == 'T') {  /* It's a TN device ? */
3001                                         /* It's the TN we're looking for ? */
3002                                         if (!strcmp((d->id) + 1, pte->buff_entry)) {
3003                                                 pte->device = d;
3004                                                 d->session = pte;
3005                                                 d->codec_number = DEFAULT_CODEC;
3006                                                 d->pos_fav = 0;
3007                                                 d->missed_call = 0;
3008                                                 d->receiver_state = STATE_ONHOOK;
3009                                                 strcpy(d->id, pte->macaddr);
3010                                                 pte->device->extension_number[0] = 'T';