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