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