3021f7c55b7fd64f90de41b2797ee37b7f2946ee
[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, 0x31, 0x38 /*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_verbose("\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_verbose("%.2x ", (unsigned char) data[tmp]);
768                 ast_verbose("\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) && (option_verbose > 5)) {
805                 ast_verbose("Sending datas with seq #0x%.4x Using slot #%d :\n", pte->seq_server,
806                                         buf_pos);
807         }
808 /*#endif */
809         send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
810                                   &(pte->sout));
811         pte->last_buf_available++;
812         ast_mutex_unlock(&pte->lock);
813 }
814
815 static void send_ping(struct unistimsession *pte)
816 {
817         BUFFSEND;
818         if ((unistimdebug) && (option_verbose > 5))
819                 ast_verbose("Sending ping\n");
820         pte->tick_next_ping = get_tick_count() + unistim_keepalive;
821         memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
822         send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
823 }
824
825 static int get_to_address(int fd, struct sockaddr_in *toAddr)
826 {
827 #ifdef HAVE_PKTINFO
828         int err;
829         struct msghdr msg;
830         struct {
831                 struct cmsghdr cm;
832                 int len;
833                 struct in_addr address;
834         } ip_msg;
835
836         /* Zero out the structures before we use them */
837         /* This sets several key values to NULL */
838         memset(&msg, 0, sizeof(msg));
839         memset(&ip_msg, 0, sizeof(ip_msg));
840
841         /* Initialize the message structure */
842         msg.msg_control = &ip_msg;
843         msg.msg_controllen = sizeof(ip_msg);
844         /* Get info about the incoming packet */
845         err = recvmsg(fd, &msg, MSG_PEEK);
846         if (err == -1)
847                 ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
848         memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
849         return err;
850 #else
851         memcpy(&toAddr, &public_ip, sizeof(&toAddr));
852         return 0;
853 #endif
854 }
855
856 /* Allocate memory & initialize structures for a new phone */
857 /* addr_from : ip address of the phone */
858 static struct unistimsession *create_client(const struct sockaddr_in *addr_from)
859 {
860         int tmp;
861         struct unistimsession *s;
862
863         if (!(s = ast_calloc(1, sizeof(*s))))
864                 return NULL;
865
866         memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
867         get_to_address(unistimsock, &s->sout);
868         if (unistimdebug) {
869                 ast_verbose
870                         ("Creating a new entry for the phone from %s received via server ip %s\n",
871                          ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
872         }
873         ast_mutex_init(&s->lock);
874         ast_mutex_lock(&sessionlock);
875         s->next = sessions;
876         sessions = s;
877
878         s->timeout = get_tick_count() + RETRANSMIT_TIMER;
879         s->seq_phone = (short) 0x0000;
880         s->seq_server = (short) 0x0000;
881         s->last_seq_ack = (short) 0x000;
882         s->last_buf_available = 0;
883         s->nb_retransmit = 0;
884         s->state = STATE_INIT;
885         s->tick_next_ping = get_tick_count() + unistim_keepalive;
886         /* Initialize struct wsabuf  */
887         for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
888                 s->wsabufsend[tmp].buf = s->buf[tmp];
889         }
890         ast_mutex_unlock(&sessionlock);
891         return s;
892 }
893
894 static void send_end_call(struct unistimsession *pte)
895 {
896         BUFFSEND;
897         if (unistimdebug)
898                 ast_verbose("Sending end call\n");
899         memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
900         send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
901 }
902
903 static void set_ping_timer(struct unistimsession *pte)
904 {
905         unsigned int tick = 0;  /* XXX what is this for, anyways */
906
907         pte->timeout = pte->tick_next_ping;
908         DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
909         return;
910 }
911
912 /* Checking if our send queue is empty,
913  * if true, setting up a timer for keepalive */
914 static void check_send_queue(struct unistimsession *pte)
915 {
916         /* Check if our send queue contained only one element */
917         if (pte->last_buf_available == 1) {
918                 if ((unistimdebug) && (option_verbose > 5))
919                         ast_verbose("Our single packet was ACKed.\n");
920                 pte->last_buf_available--;
921                 set_ping_timer(pte);
922                 return;
923         }
924         /* Check if this ACK catch up our latest packet */
925         else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
926                 if ((unistimdebug) && (option_verbose > 5))
927                         ast_verbose("Our send queue is completely ACKed.\n");
928                 pte->last_buf_available = 0;    /* Purge the send queue */
929                 set_ping_timer(pte);
930                 return;
931         }
932         if ((unistimdebug) && (option_verbose > 5))
933                 ast_verbose("We still have packets in our send queue\n");
934         return;
935 }
936
937 static void send_start_timer(struct unistimsession *pte)
938 {
939         BUFFSEND;
940         if (unistimdebug)
941                 ast_verbose("Sending start timer\n");
942         memcpy(buffsend + SIZE_HEADER, packet_send_StartTimer, sizeof(packet_send_StartTimer));
943         send_client(SIZE_HEADER + sizeof(packet_send_StartTimer), buffsend, pte);
944 }
945
946 static void send_stop_timer(struct unistimsession *pte)
947 {
948         BUFFSEND;
949         if (unistimdebug)
950                 ast_verbose("Sending stop timer\n");
951         memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
952         send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
953 }
954
955 static void Sendicon(unsigned char pos, unsigned char status, struct unistimsession *pte)
956 {
957         BUFFSEND;
958         if (unistimdebug)
959                 ast_verbose("Sending icon pos %d with status 0x%.2x\n", pos, status);
960         memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
961         buffsend[9] = pos;
962         buffsend[10] = status;
963         send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
964 }
965
966 static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
967 {
968         BUFFSEND;
969         if (!tone1) {
970                 if (unistimdebug)
971                         ast_verbose("Sending Stream Based Tone Off\n");
972                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
973                            sizeof(packet_send_stream_based_tone_off));
974                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
975                 return;
976         }
977         /* Since most of the world use a continuous tone, it's useless
978            if (unistimdebug)
979            ast_verbose ("Sending Stream Based Tone Cadence Download\n");
980            memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
981            send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
982         if (unistimdebug)
983                 ast_verbose("Sending Stream Based Tone Frequency Component List Download %d %d\n",
984                                         tone1, tone2);
985         tone1 *= 8;
986         if (!tone2) {
987                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
988                            sizeof(packet_send_stream_based_tone_single_freq));
989                 buffsend[10] = (tone1 & 0xff00) >> 8;
990                 buffsend[11] = (tone1 & 0x00ff);
991                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
992                                    pte);
993         } else {
994                 tone2 *= 8;
995                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
996                            sizeof(packet_send_stream_based_tone_dial_freq));
997                 buffsend[10] = (tone1 & 0xff00) >> 8;
998                 buffsend[11] = (tone1 & 0x00ff);
999                 buffsend[12] = (tone2 & 0xff00) >> 8;
1000                 buffsend[13] = (tone2 & 0x00ff);
1001                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
1002                                    pte);
1003         }
1004
1005         if (unistimdebug)
1006                 ast_verbose("Sending Stream Based Tone On\n");
1007         memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
1008                    sizeof(packet_send_stream_based_tone_on));
1009         send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
1010 }
1011
1012 /* Positions for favorites
1013  |--------------------|
1014  |  5       2    |
1015  |  4       1    |
1016  |  3       0    |
1017 */
1018
1019 /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */
1020 static void
1021 send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte,
1022                          const char *text)
1023 {
1024         BUFFSEND;
1025         int i;
1026
1027         if (unistimdebug)
1028                 ast_verbose("Sending favorite pos %d with status 0x%.2x\n", pos, status);
1029         memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1030         buffsend[10] = pos;
1031         buffsend[24] = pos;
1032         buffsend[25] = status;
1033         i = strlen(text);
1034         if (i > FAV_MAX_LENGTH)
1035                 i = FAV_MAX_LENGTH;
1036         memcpy(buffsend + FAV_MAX_LENGTH + 1, text, i);
1037         send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1038 }
1039
1040 static void refresh_all_favorite(struct unistimsession *pte)
1041 {
1042         int i = 0;
1043
1044         if (unistimdebug)
1045                 ast_verbose("Refreshing all favorite\n");
1046         for (i = 0; i < 6; i++) {
1047                 if ((pte->device->softkeyicon[i] <= FAV_ICON_HEADPHONES_ONHOLD) &&
1048                         (pte->device->softkeylinepos != i))
1049                         send_favorite((unsigned char) i, pte->device->softkeyicon[i] + 1, pte,
1050                                                  pte->device->softkeylabel[i]);
1051                 else
1052                         send_favorite((unsigned char) i, pte->device->softkeyicon[i], pte,
1053                                                  pte->device->softkeylabel[i]);
1054
1055         }
1056 }
1057
1058 /* Change the status for this phone (pte) and update for each phones where pte is bookmarked
1059  * use FAV_ICON_*_BLACK constant in status parameters */
1060 static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
1061 {
1062         struct unistim_device *d = devices;
1063         int i;
1064         /* Update the current phone */
1065         if (pte->state != STATE_CLEANING)
1066                 send_favorite(pte->device->softkeylinepos, status, pte,
1067                                          pte->device->softkeylabel[pte->device->softkeylinepos]);
1068         /* Notify other phones if we're in their bookmark */
1069         while (d) {
1070                 for (i = 0; i < 6; i++) {
1071                         if (d->sp[i] == pte->device) {  /* It's us ? */
1072                                 if (d->softkeyicon[i] != status) {      /* Avoid resending the same icon */
1073                                         d->softkeyicon[i] = status;
1074                                         if (d->session)
1075                                                 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1076                                 }
1077                         }
1078                 }
1079                 d = d->next;
1080         }
1081 }
1082
1083 static int RegisterExtension(const struct unistimsession *pte)
1084 {
1085         if (unistimdebug)
1086                 ast_verbose("Trying to register extension '%s' into context '%s' to %s\n",
1087                                         pte->device->extension_number, pte->device->lines->context,
1088                                         pte->device->lines->fullname);
1089         return ast_add_extension(pte->device->lines->context, 0,
1090                                                          pte->device->extension_number, 1, NULL, NULL, "Dial",
1091                                                          pte->device->lines->fullname, 0, "Unistim");
1092 }
1093
1094 static int UnregisterExtension(const struct unistimsession *pte)
1095 {
1096         if (unistimdebug)
1097                 ast_verbose("Trying to unregister extension '%s' context '%s'\n",
1098                                         pte->device->extension_number, pte->device->lines->context);
1099         return ast_context_remove_extension(pte->device->lines->context,
1100                                                                                 pte->device->extension_number, 1, "Unistim");
1101 }
1102
1103 /* Free memory allocated for a phone */
1104 static void close_client(struct unistimsession *s)
1105 {
1106         struct unistim_subchannel *sub;
1107         struct unistimsession *cur, *prev = NULL;
1108         ast_mutex_lock(&sessionlock);
1109         cur = sessions;
1110         /* Looking for the session in the linked chain */
1111         while (cur) {
1112                 if (cur == s)
1113                         break;
1114                 prev = cur;
1115                 cur = cur->next;
1116         }
1117         if (cur) {                                    /* Session found ? */
1118                 if (cur->device) {            /* This session was registred ? */
1119                         s->state = STATE_CLEANING;
1120                         if (unistimdebug)
1121                                 ast_verbose("close_client session %p device %p lines %p sub %p\n",
1122                                                         s, s->device, s->device->lines,
1123                                                         s->device->lines->subs[SUB_REAL]);
1124                         change_favorite_icon(s, FAV_ICON_NONE);
1125                         sub = s->device->lines->subs[SUB_REAL];
1126                         if (sub) {
1127                                 if (sub->owner) {       /* Call in progress ? */
1128                                         if (unistimdebug)
1129                                                 ast_verbose("Aborting call\n");
1130                                         ast_queue_hangup(sub->owner);
1131                                 }
1132                         } else
1133                                 ast_log(LOG_WARNING, "Freeing a client with no subchannel !\n");
1134                         if (!ast_strlen_zero(s->device->extension_number))
1135                                 UnregisterExtension(s);
1136                         cur->device->session = NULL;
1137                 } else {
1138                         if (unistimdebug)
1139                                 ast_verbose("Freeing an unregistered client\n");
1140                 }
1141                 if (prev)
1142                         prev->next = cur->next;
1143                 else
1144                         sessions = cur->next;
1145                 ast_mutex_destroy(&s->lock);
1146                 ast_free(s);
1147         } else
1148                 ast_log(LOG_WARNING, "Trying to delete non-existant session %p?\n", s);
1149         ast_mutex_unlock(&sessionlock);
1150         return;
1151 }
1152
1153 /* Return 1 if the session chained link was modified */
1154 static int send_retransmit(struct unistimsession *pte)
1155 {
1156         int i;
1157
1158         ast_mutex_lock(&pte->lock);
1159         if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
1160                 if (unistimdebug)
1161                         ast_verbose("Too many retransmit - freeing client\n");
1162                 ast_mutex_unlock(&pte->lock);
1163                 close_client(pte);
1164                 return 1;
1165         }
1166         pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
1167
1168         for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
1169                  i < pte->last_buf_available; i++) {
1170                 if (i < 0) {
1171                         ast_log(LOG_WARNING,
1172                                         "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%.4x last_seq_ack = #0x%.4x\n",
1173                                         pte->last_buf_available, pte->seq_server, pte->last_seq_ack);
1174                         continue;
1175                 }
1176
1177                 if (unistimdebug) {
1178                         unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
1179                         unsigned short seq;
1180
1181                         seq = ntohs(sbuf[1]);
1182                         ast_verbose("Retransmit slot #%d (seq=#0x%.4x), last ack was #0x%.4x\n", i,
1183                                                 seq, pte->last_seq_ack);
1184                 }
1185                 send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
1186                                           &pte->sout);
1187         }
1188         ast_mutex_unlock(&pte->lock);
1189         return 0;
1190 }
1191
1192 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1193 static void
1194 send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte,
1195                  const char *text)
1196 {
1197         int i;
1198         BUFFSEND;
1199         if (unistimdebug)
1200                 ast_verbose("Sending text at pos %d, inverse flag %d\n", pos, inverse);
1201         memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
1202         buffsend[10] = pos;
1203         buffsend[11] = inverse;
1204         i = strlen(text);
1205         if (i > TEXT_LENGTH_MAX)
1206                 i = TEXT_LENGTH_MAX;
1207         memcpy(buffsend + 12, text, i);
1208         send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
1209 }
1210
1211 static void send_text_status(struct unistimsession *pte, const char *text)
1212 {
1213         BUFFSEND;
1214         int i;
1215         if (unistimdebug)
1216                 ast_verbose("Sending status text\n");
1217         if (pte->device) {
1218                 if (pte->device->status_method == 1) {  /* For new firmware and i2050 soft phone */
1219                         int n = strlen(text);
1220                         /* Must send individual button separately */
1221                         int j;
1222                         for (i = 0, j = 0; i < 4; i++, j += 7) {
1223                                 int pos = 0x08 + (i * 0x20);
1224                                 memcpy(buffsend + SIZE_HEADER, packet_send_status2,
1225                                            sizeof(packet_send_status2));
1226
1227                                 buffsend[9] = pos;
1228                                 memcpy(buffsend + 10, (j < n) ? (text + j) : "       ", 7);
1229                                 send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
1230                         }
1231                         return;
1232                 }
1233         }
1234
1235
1236         memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
1237         i = strlen(text);
1238         if (i > STATUS_LENGTH_MAX)
1239                 i = STATUS_LENGTH_MAX;
1240         memcpy(buffsend + 10, text, i);
1241         send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
1242
1243 }
1244
1245 /* led values in hexa : 0 = bar off, 1 = bar on, 2 = bar 1s on/1s off, 3 = bar 2.5s on/0.5s off
1246  * 4 = bar 0.6s on/0.3s off, 5 = bar 0.5s on/0.5s off, 6 = bar 2s on/0.5s off
1247  * 7 = bar off, 8 = speaker off, 9 = speaker on, 10 = headphone off, 11 = headphone on
1248  * 18 = mute off, 19 mute on */
1249 static void send_led_update(struct unistimsession *pte, unsigned char led)
1250 {
1251         BUFFSEND;
1252         if (unistimdebug)
1253                 ast_verbose("Sending led_update (%x)\n", led);
1254         memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1255         buffsend[9] = led;
1256         send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1257 }
1258
1259 /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
1260  * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
1261  * mute = MUTE_OFF, MUTE_ON */
1262 static void
1263 send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume,
1264                                  unsigned char mute)
1265 {
1266         BUFFSEND;
1267         if (unistimdebug)
1268                 ast_verbose("Sending select output packet output=%x volume=%x mute=%x\n", output,
1269                                         volume, mute);
1270         memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1271                    sizeof(packet_send_select_output));
1272         buffsend[9] = output;
1273         if (output == OUTPUT_SPEAKER)
1274                 volume = VOLUME_LOW_SPEAKER;
1275         else
1276                 volume = VOLUME_LOW;
1277         buffsend[10] = volume;
1278         if (mute == MUTE_ON_DISCRET)
1279                 buffsend[11] = MUTE_ON;
1280         else
1281                 buffsend[11] = mute;
1282         send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1283         if (mute == MUTE_OFF)
1284                 send_led_update(pte, 0x18);
1285         else if (mute == MUTE_ON)
1286                 send_led_update(pte, 0x19);
1287         pte->device->mute = mute;
1288         if (output == OUTPUT_HANDSET) {
1289                 if (mute == MUTE_ON)
1290                         change_favorite_icon(pte, FAV_ICON_ONHOLD_BLACK);
1291                 else
1292                         change_favorite_icon(pte, FAV_ICON_OFFHOOK_BLACK);
1293                 send_led_update(pte, 0x08);
1294                 send_led_update(pte, 0x10);
1295         } else if (output == OUTPUT_HEADPHONE) {
1296                 if (mute == MUTE_ON)
1297                         change_favorite_icon(pte, FAV_ICON_HEADPHONES_ONHOLD);
1298                 else
1299                         change_favorite_icon(pte, FAV_ICON_HEADPHONES);
1300                 send_led_update(pte, 0x08);
1301                 send_led_update(pte, 0x11);
1302         } else if (output == OUTPUT_SPEAKER) {
1303                 send_led_update(pte, 0x10);
1304                 send_led_update(pte, 0x09);
1305                 if (pte->device->receiver_state == STATE_OFFHOOK) {
1306                         if (mute == MUTE_ON)
1307                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
1308                         else
1309                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOOK_BLACK);
1310                 } else {
1311                         if (mute == MUTE_ON)
1312                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
1313                         else
1314                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_OFFHOOK_BLACK);
1315                 }
1316         } else
1317                 ast_log(LOG_WARNING, "Invalid ouput (%d)\n", output);
1318         if (output != pte->device->output)
1319                 pte->device->previous_output = pte->device->output;
1320         pte->device->output = output;
1321 }
1322
1323 static void send_ring(struct unistimsession *pte, char volume, char style)
1324 {
1325         BUFFSEND;
1326         if (unistimdebug)
1327                 ast_verbose("Sending ring packet\n");
1328         memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1329         buffsend[24] = style + 0x10;
1330         buffsend[29] = volume * 0x10;
1331         send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1332 }
1333
1334 static void send_no_ring(struct unistimsession *pte)
1335 {
1336         BUFFSEND;
1337         if (unistimdebug)
1338                 ast_verbose("Sending no ring packet\n");
1339         memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1340         send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1341 }
1342
1343 static void send_texttitle(struct unistimsession *pte, const char *text)
1344 {
1345         BUFFSEND;
1346         int i;
1347         if (unistimdebug)
1348                 ast_verbose("Sending title text\n");
1349         memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1350         i = strlen(text);
1351         if (i > 12)
1352                 i = 12;
1353         memcpy(buffsend + 10, text, i);
1354         send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1355
1356 }
1357
1358 static void send_date_time(struct unistimsession *pte)
1359 {
1360         BUFFSEND;
1361         struct timeval tv = ast_tvnow();
1362         struct ast_tm atm = { 0, };
1363
1364         if (unistimdebug)
1365                 ast_verbose("Sending Time & Date\n");
1366         memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1367         ast_localtime(&tv, &atm, NULL);
1368         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1369         buffsend[11] = (unsigned char) atm.tm_mday;
1370         buffsend[12] = (unsigned char) atm.tm_hour;
1371         buffsend[13] = (unsigned char) atm.tm_min;
1372         send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1373 }
1374
1375 static void send_date_time2(struct unistimsession *pte)
1376 {
1377         BUFFSEND;
1378         struct timeval tv = ast_tvnow();
1379         struct ast_tm atm = { 0, };
1380
1381         if (unistimdebug)
1382                 ast_verbose("Sending Time & Date #2\n");
1383         memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1384         ast_localtime(&tv, &atm, NULL);
1385         if (pte->device)
1386                 buffsend[9] = pte->device->datetimeformat;
1387         else
1388                 buffsend[9] = 61;
1389         buffsend[14] = (unsigned char) atm.tm_mon + 1;
1390         buffsend[15] = (unsigned char) atm.tm_mday;
1391         buffsend[16] = (unsigned char) atm.tm_hour;
1392         buffsend[17] = (unsigned char) atm.tm_min;
1393         send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1394 }
1395
1396 static void send_date_time3(struct unistimsession *pte)
1397 {
1398         BUFFSEND;
1399         struct timeval tv = ast_tvnow();
1400         struct ast_tm atm = { 0, };
1401
1402         if (unistimdebug)
1403                 ast_verbose("Sending Time & Date #3\n");
1404         memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1405         ast_localtime(&tv, &atm, NULL);
1406         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1407         buffsend[11] = (unsigned char) atm.tm_mday;
1408         buffsend[12] = (unsigned char) atm.tm_hour;
1409         buffsend[13] = (unsigned char) atm.tm_min;
1410         send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1411 }
1412
1413 static void send_blink_cursor(struct unistimsession *pte)
1414 {
1415         BUFFSEND;
1416         if (unistimdebug)
1417                 ast_verbose("Sending set blink\n");
1418         memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
1419         send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1420         return;
1421 }
1422
1423 /* pos : 0xab (a=0/2/4 = line ; b = row) */
1424 static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
1425 {
1426         BUFFSEND;
1427         if (unistimdebug)
1428                 ast_verbose("Sending set cursor position\n");
1429         memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1430                    sizeof(packet_send_set_pos_cursor));
1431         buffsend[11] = pos;
1432         send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1433         return;
1434 }
1435
1436 static void rcv_resume_connection_with_server(struct unistimsession *pte)
1437 {
1438         BUFFSEND;
1439         if (unistimdebug)
1440                 ast_verbose("ResumeConnectionWithServer received\n");
1441         if (unistimdebug)
1442                 ast_verbose("Sending packet_send_query_mac_address\n");
1443         memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1444                    sizeof(packet_send_query_mac_address));
1445         send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1446         return;
1447 }
1448
1449 static int unistim_register(struct unistimsession *s)
1450 {
1451         struct unistim_device *d;
1452
1453         ast_mutex_lock(&devicelock);
1454         d = devices;
1455         while (d) {
1456                 if (!strcasecmp(s->macaddr, d->id)) {
1457                         /* XXX Deal with IP authentication */
1458                         s->device = d;
1459                         d->session = s;
1460                         d->codec_number = DEFAULT_CODEC;
1461                         d->pos_fav = 0;
1462                         d->missed_call = 0;
1463                         d->receiver_state = STATE_ONHOOK;
1464                         break;
1465                 }
1466                 d = d->next;
1467         }
1468         ast_mutex_unlock(&devicelock);
1469
1470         if (!d)
1471                 return 0;
1472
1473         return 1;
1474 }
1475
1476 static int alloc_sub(struct unistim_line *l, int x)
1477 {
1478         struct unistim_subchannel *sub;
1479         if (!(sub = ast_calloc(1, sizeof(*sub))))
1480                 return 0;
1481
1482         if (unistimdebug)
1483                 ast_verbose(VERBOSE_PREFIX_3
1484                                         "Allocating UNISTIM subchannel #%d on %s@%s ptr=%p\n", x, l->name,
1485                                         l->parent->name, sub);
1486         sub->parent = l;
1487         sub->subtype = x;
1488         l->subs[x] = sub;
1489         ast_mutex_init(&sub->lock);
1490         return 1;
1491 }
1492
1493 static int unalloc_sub(struct unistim_line *p, int x)
1494 {
1495         if (!x) {
1496                 ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name,
1497                                 p->parent->name);
1498                 return -1;
1499         }
1500         if (unistimdebug)
1501                 ast_debug(1, "Released sub %d of channel %s@%s\n", x, p->name,
1502                                 p->parent->name);
1503         ast_mutex_destroy(&p->lock);
1504         ast_free(p->subs[x]);
1505         p->subs[x] = 0;
1506         return 0;
1507 }
1508
1509 static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
1510 {
1511         BUFFSEND;
1512         int tmp, i = 0;
1513         char addrmac[19];
1514         int res = 0;
1515         if (unistimdebug)
1516                 ast_verbose("Mac Address received : ");
1517         for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
1518                 sprintf(&addrmac[i], "%.2x", (unsigned char) buf[tmp]);
1519                 i += 2;
1520         }
1521         if (unistimdebug)
1522                 ast_verbose("%s\n", addrmac);
1523         strcpy(pte->macaddr, addrmac);
1524         res = unistim_register(pte);
1525         if (!res) {
1526                 switch (autoprovisioning) {
1527                 case AUTOPROVISIONING_NO:
1528                         ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
1529                         pte->state = STATE_AUTHDENY;
1530                         break;
1531                 case AUTOPROVISIONING_YES:
1532                         {
1533                                 struct unistim_device *d, *newd;
1534                                 struct unistim_line *newl;
1535                                 if (unistimdebug)
1536                                         ast_verbose("New phone, autoprovisioning on\n");
1537                                 /* First : locate the [template] section */
1538                                 ast_mutex_lock(&devicelock);
1539                                 d = devices;
1540                                 while (d) {
1541                                         if (!strcasecmp(d->name, "template")) {
1542                                                 /* Found, cloning this entry */
1543                                                 if (!(newd = ast_malloc(sizeof(*newd)))) {
1544                                                         ast_mutex_unlock(&devicelock);
1545                                                         return;
1546                                                 }
1547
1548                                                 memcpy(newd, d, sizeof(*newd));
1549                                                 if (!(newl = ast_malloc(sizeof(*newl)))) {
1550                                                         ast_free(newd);
1551                                                         ast_mutex_unlock(&devicelock);
1552                                                         return;
1553                                                 }
1554
1555                                                 memcpy(newl, d->lines, sizeof(*newl));
1556                                                 if (!alloc_sub(newl, SUB_REAL)) {
1557                                                         ast_free(newd);
1558                                                         ast_free(newl);
1559                                                         ast_mutex_unlock(&devicelock);
1560                                                         return;
1561                                                 }
1562                                                 /* Ok, now updating some fields */
1563                                                 ast_copy_string(newd->id, addrmac, sizeof(newd->id));
1564                                                 ast_copy_string(newd->name, addrmac, sizeof(newd->name));
1565                                                 if (newd->extension == EXTENSION_NONE)
1566                                                         newd->extension = EXTENSION_ASK;
1567                                                 newd->lines = newl;
1568                                                 newd->receiver_state = STATE_ONHOOK;
1569                                                 newd->session = pte;
1570                                                 newd->to_delete = -1;
1571                                                 pte->device = newd;
1572                                                 newd->next = NULL;
1573                                                 newl->parent = newd;
1574                                                 strcpy(newl->name, d->lines->name);
1575                                                 snprintf(d->lines->name, sizeof(d->lines->name), "%d",
1576                                                                  atoi(d->lines->name) + 1);
1577                                                 snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
1578                                                                  newl->name, newd->name);
1579                                                 /* Go to the end of the linked chain */
1580                                                 while (d->next) {
1581                                                         d = d->next;
1582                                                 }
1583                                                 d->next = newd;
1584                                                 d = newd;
1585                                                 break;
1586                                         }
1587                                         d = d->next;
1588                                 }
1589                                 ast_mutex_unlock(&devicelock);
1590                                 if (!d) {
1591                                         ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
1592                                         pte->state = STATE_AUTHDENY;
1593                                 }
1594                         }
1595                         break;
1596                 case AUTOPROVISIONING_TN:
1597                         pte->state = STATE_AUTHDENY;
1598                         break;
1599                 case AUTOPROVISIONING_DB:
1600                         ast_log(LOG_WARNING,
1601                                         "Autoprovisioning with database is not yet functional\n");
1602                         break;
1603                 default:
1604                         ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %d\n",
1605                                         autoprovisioning);
1606                 }
1607         }
1608         if (pte->state != STATE_AUTHDENY) {
1609                 if (option_verbose > 2)
1610                         ast_verbose(VERBOSE_PREFIX_3 "Device '%s' successfuly registered\n",
1611                                                 pte->device->name);
1612                 switch (pte->device->extension) {
1613                 case EXTENSION_NONE:
1614                         pte->state = STATE_MAINPAGE;
1615                         break;
1616                 case EXTENSION_ASK:
1617                         /* Checking if we already have an extension number */
1618                         if (ast_strlen_zero(pte->device->extension_number))
1619                                 pte->state = STATE_EXTENSION;
1620                         else {
1621                                 /* Yes, because of a phone reboot. We don't ask again for the TN */
1622                                 if (RegisterExtension(pte))
1623                                         pte->state = STATE_EXTENSION;
1624                                 else
1625                                         pte->state = STATE_MAINPAGE;
1626                         }
1627                         break;
1628                 case EXTENSION_LINE:
1629                         ast_copy_string(pte->device->extension_number, pte->device->lines->name,
1630                                                         sizeof(pte->device->extension_number));
1631                         if (RegisterExtension(pte))
1632                                 pte->state = STATE_EXTENSION;
1633                         else
1634                                 pte->state = STATE_MAINPAGE;
1635                         break;
1636                 case EXTENSION_TN:
1637                         /* If we are here, it's because of a phone reboot */
1638                         pte->state = STATE_MAINPAGE;
1639                         break;
1640                 default:
1641                         ast_log(LOG_WARNING, "Internal error, extension value unknown : %d\n",
1642                                         pte->device->extension);
1643                         pte->state = STATE_AUTHDENY;
1644                         break;
1645                 }
1646         }
1647         if (pte->state == STATE_EXTENSION) {
1648                 if (pte->device->extension != EXTENSION_TN)
1649                         pte->device->extension = EXTENSION_ASK;
1650                 pte->device->extension_number[0] = '\0';
1651         }
1652         if (unistimdebug)
1653                 ast_verbose("\nSending S1\n");
1654         memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
1655         send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
1656
1657         if (unistimdebug)
1658                 ast_verbose("Sending query_basic_manager_04\n");
1659         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
1660                    sizeof(packet_send_query_basic_manager_04));
1661         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
1662
1663         if (unistimdebug)
1664                 ast_verbose("Sending query_basic_manager_10\n");
1665         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
1666                    sizeof(packet_send_query_basic_manager_10));
1667         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
1668
1669         send_date_time(pte);
1670         return;
1671 }
1672
1673 static int write_entry_history(struct unistimsession *pte, FILE * f, char c, char *line1)
1674 {
1675         if (fwrite(&c, 1, 1, f) != 1) {
1676                 display_last_error("Unable to write history log header.");
1677                 return -1;
1678         }
1679         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
1680                 display_last_error("Unable to write history entry - date.");
1681                 return -1;
1682         }
1683         if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
1684                 display_last_error("Unable to write history entry - callerid.");
1685                 return -1;
1686         }
1687         if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
1688                 display_last_error("Unable to write history entry - callername.");
1689                 return -1;
1690         }
1691         return 0;
1692 }
1693
1694 static int write_history(struct unistimsession *pte, char way, char ismissed)
1695 {
1696         char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
1697         char line1[TEXT_LENGTH_MAX + 1];
1698         char count = 0, *histbuf;
1699         int size;
1700         FILE *f, *f2;
1701         struct timeval tv = ast_tvnow();
1702         struct ast_tm atm = { 0, };
1703
1704         if (!pte->device)
1705                 return -1;
1706         if (!pte->device->callhistory)
1707                 return 0;
1708         if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
1709                 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
1710                                 pte->device->name);
1711                 return -1;
1712         }
1713
1714         snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
1715         if (ast_mkdir(tmp, 0770)) {
1716                 if (errno != EEXIST) {
1717                         display_last_error("Unable to create directory for history");
1718                         return -1;
1719                 }
1720         }
1721
1722         ast_localtime(&tv, &atm, NULL);
1723         if (ismissed) {
1724                 if (way == 'i')
1725                         strcpy(tmp2, "Miss");
1726                 else
1727                         strcpy(tmp2, "Fail");
1728         } else
1729                 strcpy(tmp2, "Answ");
1730         snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
1731                          atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
1732                          atm.tm_min, atm.tm_sec, tmp2);
1733
1734         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
1735                          USTM_LOG_DIR, pte->device->name, way);
1736         if ((f = fopen(tmp, "r"))) {
1737                 struct stat bufstat;
1738
1739                 if (stat(tmp, &bufstat)) {
1740                         display_last_error("Unable to stat history log.");
1741                         fclose(f);
1742                         return -1;
1743                 }
1744                 size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
1745                 if (bufstat.st_size != size) {
1746                         ast_log(LOG_WARNING,
1747                                         "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
1748                                         tmp, (int) bufstat.st_size, size);
1749                         fclose(f);
1750                         f = NULL;
1751                         count = 1;
1752                 }
1753         }
1754
1755         /* If we can't open the log file, we create a brand new one */
1756         if (!f) {
1757                 char c = 1;
1758                 int i;
1759
1760                 if ((errno != ENOENT) && (count == 0)) {
1761                         display_last_error("Unable to open history log.");
1762                         return -1;
1763                 }
1764                 f = fopen(tmp, "w");
1765                 if (!f) {
1766                         display_last_error("Unable to create history log.");
1767                         return -1;
1768                 }
1769                 if (write_entry_history(pte, f, c, line1)) {
1770                         fclose(f);
1771                         return -1;
1772                 }
1773                 memset(line1, ' ', TEXT_LENGTH_MAX);
1774                 for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
1775                         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
1776                                 display_last_error("Unable to write history entry - stuffing.");
1777                                 fclose(f);
1778                                 return -1;
1779                         }
1780                 }
1781                 if (fclose(f))
1782                         display_last_error("Unable to close history - creation.");
1783                 return 0;
1784         }
1785         /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
1786         if (fread(&count, 1, 1, f) != 1) {
1787                 display_last_error("Unable to read history header.");
1788                 fclose(f);
1789                 return -1;
1790         }
1791         if (count > MAX_ENTRY_LOG) {
1792                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
1793                                 count, MAX_ENTRY_LOG);
1794                 fclose(f);
1795                 return -1;
1796         }
1797         snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
1798                          USTM_LOG_DIR, pte->device->name, way);
1799         if (!(f2 = fopen(tmp2, "w"))) {
1800                 display_last_error("Unable to create temporary history log.");
1801                 fclose(f);
1802                 return -1;
1803         }
1804
1805         if (++count > MAX_ENTRY_LOG)
1806                 count = MAX_ENTRY_LOG;
1807
1808         if (write_entry_history(pte, f2, count, line1)) {
1809                 fclose(f);
1810                 fclose(f2);
1811                 return -1;
1812         }
1813
1814         size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
1815         if (!(histbuf = ast_malloc(size))) {
1816                 fclose(f);
1817                 fclose(f2);
1818                 return -1;
1819         }
1820
1821         if (fread(histbuf, size, 1, f) != 1) {
1822                 ast_free(histbuf);
1823                 fclose(f);
1824                 fclose(f2);
1825                 display_last_error("Unable to read previous history entries.");
1826                 return -1;
1827         }
1828         if (fwrite(histbuf, size, 1, f2) != 1) {
1829                 ast_free(histbuf);
1830                 fclose(f);
1831                 fclose(f2);
1832                 display_last_error("Unable to write previous history entries.");
1833                 return -1;
1834         }
1835         ast_free(histbuf);
1836         if (fclose(f))
1837                 display_last_error("Unable to close history log.");
1838         if (fclose(f2))
1839                 display_last_error("Unable to close temporary history log.");
1840         if (unlink(tmp))
1841                 display_last_error("Unable to remove old history log.");
1842         if (rename(tmp2, tmp))
1843                 display_last_error("Unable to rename new history log.");
1844         return 0;
1845 }
1846
1847 static void cancel_dial(struct unistimsession *pte)
1848 {
1849         send_no_ring(pte);
1850         pte->device->missed_call++;
1851         write_history(pte, 'i', 1);
1852         show_main_page(pte);
1853         return;
1854 }
1855
1856 static void swap_subs(struct unistim_line *p, int a, int b)
1857 {
1858 /*  struct ast_channel *towner; */
1859         struct ast_rtp *rtp;
1860         int fds;
1861
1862         if (unistimdebug)
1863                 ast_verbose("Swapping %d and %d\n", a, b);
1864
1865         if ((!p->subs[a]->owner) || (!p->subs[b]->owner)) {
1866                 ast_log(LOG_WARNING,
1867                                 "Attempted to swap subchannels with a null owner : sub #%d=%p sub #%d=%p\n",
1868                                 a, p->subs[a]->owner, b, p->subs[b]->owner);
1869                 return;
1870         }
1871         rtp = p->subs[a]->rtp;
1872         p->subs[a]->rtp = p->subs[b]->rtp;
1873         p->subs[b]->rtp = rtp;
1874
1875         fds = p->subs[a]->owner->fds[0];
1876         p->subs[a]->owner->fds[0] = p->subs[b]->owner->fds[0];
1877         p->subs[b]->owner->fds[0] = fds;
1878
1879         fds = p->subs[a]->owner->fds[1];
1880         p->subs[a]->owner->fds[1] = p->subs[b]->owner->fds[1];
1881         p->subs[b]->owner->fds[1] = fds;
1882 }
1883
1884 static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
1885 {
1886         int res = 0;
1887         struct ast_channel
1888          *chana = NULL, *chanb = NULL, *bridgea = NULL, *bridgeb = NULL, *peera =
1889                 NULL, *peerb = NULL, *peerc = NULL, *peerd = NULL;
1890
1891         if (!p1->owner || !p2->owner) {
1892                 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
1893                 return -1;
1894         }
1895         chana = p1->owner;
1896         chanb = p2->owner;
1897         bridgea = ast_bridged_channel(chana);
1898         bridgeb = ast_bridged_channel(chanb);
1899
1900         if (bridgea) {
1901                 peera = chana;
1902                 peerb = chanb;
1903                 peerc = bridgea;
1904                 peerd = bridgeb;
1905         } else if (bridgeb) {
1906                 peera = chanb;
1907                 peerb = chana;
1908                 peerc = bridgeb;
1909                 peerd = bridgea;
1910         }
1911
1912         if (peera && peerb && peerc && (peerb != peerc)) {
1913                 /*ast_quiet_chan(peera);
1914                    ast_quiet_chan(peerb);
1915                    ast_quiet_chan(peerc);
1916                    ast_quiet_chan(peerd); */
1917
1918                 if (peera->cdr && peerb->cdr) {
1919                         peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
1920                 } else if (peera->cdr) {
1921                         peerb->cdr = peera->cdr;
1922                 }
1923                 peera->cdr = NULL;
1924
1925                 if (peerb->cdr && peerc->cdr) {
1926                         peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
1927                 } else if (peerc->cdr) {
1928                         peerb->cdr = peerc->cdr;
1929                 }
1930                 peerc->cdr = NULL;
1931
1932                 if (ast_channel_masquerade(peerb, peerc)) {
1933                         ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name,
1934                                         peerc->name);
1935                         res = -1;
1936                 }
1937                 return res;
1938         } else {
1939                 ast_log(LOG_NOTICE,
1940                                 "Transfer attempted with no appropriate bridged calls to transfer\n");
1941                 if (chana)
1942                         ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
1943                 if (chanb)
1944                         ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
1945                 return -1;
1946         }
1947         return 0;
1948 }
1949
1950 void change_callerid(struct unistimsession *pte, int type, char *callerid)
1951 {
1952         char *data;
1953         int size;
1954
1955         if (type)
1956                 data = pte->device->lst_cnm;
1957         else
1958                 data = pte->device->lst_cid;
1959
1960         /* This is very nearly strncpy(), except that the remaining buffer
1961          * is padded with ' ', instead of '\0' */
1962         memset(data, ' ', TEXT_LENGTH_MAX);
1963         size = strlen(callerid);
1964         if (size > TEXT_LENGTH_MAX)
1965                 size = TEXT_LENGTH_MAX;
1966         memcpy(data, callerid, size);
1967 }
1968
1969 static void close_call(struct unistimsession *pte)
1970 {
1971         struct unistim_subchannel *sub;
1972         struct unistim_line *l = pte->device->lines;
1973
1974         sub = pte->device->lines->subs[SUB_REAL];
1975         send_stop_timer(pte);
1976         if (sub->owner) {
1977                 sub->alreadygone = 1;
1978                 if (l->subs[SUB_THREEWAY]) {
1979                         l->subs[SUB_THREEWAY]->alreadygone = 1;
1980                         if (attempt_transfer(sub, l->subs[SUB_THREEWAY]) < 0)
1981                                 ast_verbose("attempt_transfer failed.\n");
1982                 } else
1983                         ast_queue_hangup(sub->owner);
1984         } else {
1985                 if (l->subs[SUB_THREEWAY]) {
1986                         if (l->subs[SUB_THREEWAY]->owner)
1987                                 ast_queue_hangup(l->subs[SUB_THREEWAY]->owner);
1988                         else
1989                                 ast_log(LOG_WARNING, "threeway sub without owner\n");
1990                 } else
1991                         ast_verbose("USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
1992                                                 sub->parent->parent->name, sub->subtype);
1993         }
1994         change_callerid(pte, 0, pte->device->redial_number);
1995         change_callerid(pte, 1, "");
1996         write_history(pte, 'o', pte->device->missed_call);
1997         pte->device->missed_call = 0;
1998         show_main_page(pte);
1999         return;
2000 }
2001
2002 static void IgnoreCall(struct unistimsession *pte)
2003 {
2004         send_no_ring(pte);
2005         return;
2006 }
2007
2008 static void *unistim_ss(void *data)
2009 {
2010         struct ast_channel *chan = data;
2011         struct unistim_subchannel *sub = chan->tech_pvt;
2012         struct unistim_line *l = sub->parent;
2013         struct unistimsession *s = l->parent->session;
2014         int res;
2015
2016         if (option_verbose > 2)
2017                 ast_verbose(VERBOSE_PREFIX_3 "Starting switch on '%s@%s-%d' to %s\n",
2018                                         l->name, l->parent->name, sub->subtype, s->device->phone_number);
2019         ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten));
2020         ast_copy_string(s->device->redial_number, s->device->phone_number,
2021                                         sizeof(s->device->redial_number));
2022         ast_setstate(chan, AST_STATE_RING);
2023         res = ast_pbx_run(chan);
2024         if (res) {
2025                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2026                 send_tone(s, 1000, 0);;
2027         }
2028         return NULL;
2029 }
2030
2031 static void start_rtp(struct unistim_subchannel *sub)
2032 {
2033         BUFFSEND;
2034         struct sockaddr_in us;
2035         struct sockaddr_in public;
2036         struct sockaddr_in sin;
2037         int codec;
2038         struct sockaddr_in sout;
2039
2040         /* Sanity checks */
2041         if (!sub) {
2042                 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2043                 return;
2044         }
2045         if (!sub->parent) {
2046                 ast_log(LOG_WARNING, "start_rtp with a null line !\n");
2047                 return;
2048         }
2049         if (!sub->parent->parent) {
2050                 ast_log(LOG_WARNING, "start_rtp with a null device !\n");
2051                 return;
2052         }
2053         if (!sub->parent->parent->session) {
2054                 ast_log(LOG_WARNING, "start_rtp with a null session !\n");
2055                 return;
2056         }
2057         sout = sub->parent->parent->session->sout;
2058
2059         ast_mutex_lock(&sub->lock);
2060         /* Allocate the RTP */
2061         if (unistimdebug)
2062                 ast_verbose("Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2063         sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, sout.sin_addr);
2064         if (!sub->rtp) {
2065                 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2066                                 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2067                 ast_mutex_unlock(&sub->lock);
2068                 return;
2069         }
2070         if (sub->rtp && sub->owner) {
2071                 sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
2072                 sub->owner->fds[1] = ast_rtcp_fd(sub->rtp);
2073         }
2074         if (sub->rtp) {
2075                 ast_rtp_setqos(sub->rtp, tos_audio, cos_audio, "UNISTIM RTP");
2076                 ast_rtp_setnat(sub->rtp, sub->parent->parent->nat);
2077         }
2078
2079         /* Create the RTP connection */
2080         ast_rtp_get_us(sub->rtp, &us);
2081         sin.sin_family = AF_INET;
2082         /* Setting up RTP for our side */
2083         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2084                    sizeof(sin.sin_addr));
2085         sin.sin_port = htons(sub->parent->parent->rtp_port);
2086         ast_rtp_set_peer(sub->rtp, &sin);
2087         if (!(sub->owner->nativeformats & sub->owner->readformat)) {
2088                 int fmt;
2089                 fmt = ast_best_codec(sub->owner->nativeformats);
2090                 ast_log(LOG_WARNING,
2091                                 "Our read/writeformat has been changed to something incompatible : %s (%d), using %s (%d) best codec from %d\n",
2092                                 ast_getformatname(sub->owner->readformat),
2093                                 sub->owner->readformat, ast_getformatname(fmt), fmt,
2094                                 sub->owner->nativeformats);
2095                 sub->owner->readformat = fmt;
2096                 sub->owner->writeformat = fmt;
2097         }
2098         codec = ast_rtp_lookup_code(sub->rtp, 1, sub->owner->readformat);
2099         /* Setting up RTP of the phone */
2100         if (public_ip.sin_family == 0)  /* NAT IP override ?   */
2101                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2102         else
2103                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2104         if (unistimdebug) {
2105                 ast_verbose
2106                         ("RTP started : Our IP/port is : %s:%hd with codec %s (%d)\n",
2107                          ast_inet_ntoa(us.sin_addr),
2108                          htons(us.sin_port), ast_getformatname(sub->owner->readformat),
2109                          sub->owner->readformat);
2110                 ast_verbose("Starting phone RTP stack. Our public IP is %s\n",
2111                                         ast_inet_ntoa(public.sin_addr));
2112         }
2113         if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
2114                 (sub->owner->readformat == AST_FORMAT_ALAW)) {
2115                 if (unistimdebug)
2116                         ast_verbose("Sending packet_send_rtp_packet_size for codec %d\n", codec);
2117                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2118                            sizeof(packet_send_rtp_packet_size));
2119                 buffsend[10] = codec;
2120                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend,
2121                                    sub->parent->parent->session);
2122         }
2123         if (unistimdebug)
2124                 ast_verbose("Sending Jitter Buffer Parameters Configuration\n");
2125         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2126                    sizeof(packet_send_jitter_buffer_conf));
2127         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend,
2128                            sub->parent->parent->session);
2129         if (sub->parent->parent->rtp_method != 0) {
2130                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2131
2132                 if (unistimdebug)
2133                         ast_verbose("Sending OpenAudioStreamTX using method #%d\n",
2134                                                 sub->parent->parent->rtp_method);
2135                 if (sub->parent->parent->rtp_method == 3)
2136                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2137                                    sizeof(packet_send_open_audio_stream_tx3));
2138                 else
2139                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2140                                    sizeof(packet_send_open_audio_stream_tx));
2141                 if (sub->parent->parent->rtp_method != 2) {
2142                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2143                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2144                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2145                         buffsend[23] = (rtcpsin_port & 0x00ff);
2146                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2147                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2148                         buffsend[24] = (us.sin_port & 0x00ff);
2149                         buffsend[27] = (rtcpsin_port & 0x00ff);
2150                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2151                 } else {
2152                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2153                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2154                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2155                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2156                         buffsend[19] = (us.sin_port & 0x00ff);
2157                         buffsend[11] = codec;
2158                 }
2159                 buffsend[12] = codec;
2160                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend,
2161                                    sub->parent->parent->session);
2162
2163                 if (unistimdebug)
2164                         ast_verbose("Sending OpenAudioStreamRX\n");
2165                 if (sub->parent->parent->rtp_method == 3)
2166                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2167                                    sizeof(packet_send_open_audio_stream_rx3));
2168                 else
2169                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2170                                    sizeof(packet_send_open_audio_stream_rx));
2171                 if (sub->parent->parent->rtp_method != 2) {
2172                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2173                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2174                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2175                         buffsend[23] = (rtcpsin_port & 0x00ff);
2176                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2177                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2178                         buffsend[24] = (us.sin_port & 0x00ff);
2179                         buffsend[27] = (rtcpsin_port & 0x00ff);
2180                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2181                 } else {
2182                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2183                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2184                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2185                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2186                         buffsend[19] = (us.sin_port & 0x00ff);
2187                         buffsend[12] = codec;
2188                 }
2189                 buffsend[11] = codec;
2190                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend,
2191                                    sub->parent->parent->session);
2192         } else {
2193                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2194
2195                 if (unistimdebug)
2196                         ast_verbose("Sending packet_send_call default method\n");
2197
2198                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2199                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2200                 /* Destination port when sending RTP */
2201                 buffsend[49] = (us.sin_port & 0x00ff);
2202                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2203                 /* Destination port when sending RTCP */
2204                 buffsend[52] = (rtcpsin_port & 0x00ff);
2205                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2206                 /* Codec */
2207                 buffsend[40] = codec;
2208                 buffsend[41] = codec;
2209                 if (sub->owner->readformat == AST_FORMAT_ULAW)
2210                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2211                 else if (sub->owner->readformat == AST_FORMAT_ALAW)
2212                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2213                 else if (sub->owner->readformat == AST_FORMAT_G723_1)
2214                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2215                 else if (sub->owner->readformat == AST_FORMAT_G729A)
2216                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2217                 else
2218                         ast_log(LOG_WARNING, "Unsupported codec %s (%d) !\n",
2219                                         ast_getformatname(sub->owner->readformat), sub->owner->readformat);
2220                 /* Source port for transmit RTP and Destination port for receiving RTP */
2221                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2222                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2223                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2224                 buffsend[48] = (rtcpsin_port & 0x00ff);
2225                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend,
2226                                    sub->parent->parent->session);
2227         }
2228         ast_mutex_unlock(&sub->lock);
2229 }
2230
2231 static void SendDialTone(struct unistimsession *pte)
2232 {
2233         int i;
2234         /* No country defined ? Using US tone */
2235         if (ast_strlen_zero(pte->device->country)) {
2236                 if (unistimdebug)
2237                         ast_verbose("No country defined, using US tone\n");
2238                 send_tone(pte, 350, 440);
2239                 return;
2240         }
2241         if (strlen(pte->device->country) != 2) {
2242                 if (unistimdebug)
2243                         ast_verbose("Country code != 2 char, using US tone\n");
2244                 send_tone(pte, 350, 440);
2245                 return;
2246         }
2247         i = 0;
2248         while (frequency[i].freq1) {
2249                 if ((frequency[i].country[0] == pte->device->country[0]) &&
2250                         (frequency[i].country[1] == pte->device->country[1])) {
2251                         if (unistimdebug)
2252                                 ast_verbose("Country code found (%s), freq1=%d freq2=%d\n",
2253                                                         frequency[i].country, frequency[i].freq1, frequency[i].freq2);
2254                         send_tone(pte, frequency[i].freq1, frequency[i].freq2);
2255                 }
2256                 i++;
2257         }
2258 }
2259
2260 static void handle_dial_page(struct unistimsession *pte)
2261 {
2262         pte->state = STATE_DIALPAGE;
2263         if (pte->device->call_forward[0] == -1) {
2264                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2265                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
2266                 send_text_status(pte, "ForwardCancel BackSpcErase");
2267                 if (pte->device->call_forward[1] != 0) {
2268                         char tmp[TEXT_LENGTH_MAX + 1];
2269
2270                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2271                                                         sizeof(pte->device->phone_number));
2272                         pte->device->size_phone_number = strlen(pte->device->phone_number);
2273                         if (pte->device->size_phone_number > 15)
2274                                 pte->device->size_phone_number = 15;
2275                         strcpy(tmp, "Number : ...............");
2276                         memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
2277                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
2278                         send_blink_cursor(pte);
2279                         send_cursor_pos(pte,
2280                                                   (unsigned char) (TEXT_LINE2 + 0x09 +
2281                                                                                    pte->device->size_phone_number));
2282                         send_led_update(pte, 0);
2283                         return;
2284                 }
2285         } else {
2286                 if ((pte->device->output == OUTPUT_HANDSET) &&
2287                         (pte->device->receiver_state == STATE_ONHOOK))
2288                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2289                 else
2290                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2291                 SendDialTone(pte);
2292                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
2293                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
2294                 send_text_status(pte, "Call   Redial BackSpcErase");
2295         }
2296         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2297         send_blink_cursor(pte);
2298         send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2299         pte->device->size_phone_number = 0;
2300         pte->device->phone_number[0] = 0;
2301         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
2302         Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
2303         pte->device->missed_call = 0;
2304         send_led_update(pte, 0);
2305         return;
2306 }
2307
2308 /* Step 1 : Music On Hold for peer, Dialing screen for us */
2309 static void TransferCallStep1(struct unistimsession *pte)
2310 {
2311         struct unistim_subchannel *sub;
2312         struct unistim_line *p = pte->device->lines;
2313
2314         sub = p->subs[SUB_REAL];
2315
2316         if (!sub->owner) {
2317                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2318                 return;
2319         }
2320         if (p->subs[SUB_THREEWAY]) {
2321                 if (unistimdebug)
2322                         ast_verbose("Transfer canceled, hangup our threeway channel\n");
2323                 if (p->subs[SUB_THREEWAY]->owner)
2324                         ast_queue_hangup(p->subs[SUB_THREEWAY]->owner);
2325                 else
2326                         ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
2327                 return;
2328         }
2329         /* Start music on hold if appropriate */
2330         if (pte->device->moh)
2331                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
2332         else {
2333                 if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
2334                         ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
2335                                                   pte->device->lines->musicclass, NULL);
2336                         pte->device->moh = 1;
2337                 } else {
2338                         ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
2339                         return;
2340                 }
2341         }
2342         /* Silence our channel */
2343         if (!pte->device->silence_generator) {
2344                 pte->device->silence_generator =
2345                         ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
2346                 if (pte->device->silence_generator == NULL)
2347                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2348                 else if (unistimdebug)
2349                         ast_verbose("Starting silence generator\n");
2350         }
2351         handle_dial_page(pte);
2352 }
2353
2354 /* From phone to PBX */
2355 static void HandleCallOutgoing(struct unistimsession *s)
2356 {
2357         struct ast_channel *c;
2358         struct unistim_subchannel *sub;
2359         pthread_t t;
2360         s->state = STATE_CALL;
2361         sub = s->device->lines->subs[SUB_REAL];
2362         if (!sub) {
2363                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2364                 return;
2365         }
2366         if (!sub->owner) {                    /* A call is already in progress ? */
2367                 c = unistim_new(sub, AST_STATE_DOWN);   /* No, starting a new one */
2368                 if (c) {
2369                         /* Need to start RTP before calling ast_pbx_run */
2370                         if (!sub->rtp)
2371                                 start_rtp(sub);
2372                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2373                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
2374                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2375                         send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2376                         send_text_status(s, "Hangup");
2377                         /* start switch */
2378                         if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
2379                                 display_last_error("Unable to create switch thread");
2380                                 ast_queue_hangup(c);
2381                         }
2382                 } else
2383                         ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
2384                                         sub->parent->name, s->device->name);
2385         } else {                                        /* We already have a call, so we switch in a threeway call */
2386
2387                 if (s->device->moh) {
2388                         struct unistim_subchannel *sub;
2389                         struct unistim_line *p = s->device->lines;
2390                         sub = p->subs[SUB_REAL];
2391
2392                         if (!sub->owner) {
2393                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2394                                 return;
2395                         }
2396                         if (p->subs[SUB_THREEWAY]) {
2397                                 ast_log(LOG_WARNING,
2398                                                 "Can't transfer while an another transfer is taking place\n");
2399                                 return;
2400                         }
2401                         if (!alloc_sub(p, SUB_THREEWAY)) {
2402                                 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
2403                                 return;
2404                         }
2405                         /* Stop the silence generator */
2406                         if (s->device->silence_generator) {
2407                                 if (unistimdebug)
2408                                         ast_verbose("Stopping silence generator\n");
2409                                 ast_channel_stop_silence_generator(sub->owner,
2410                                                                                                    s->device->silence_generator);
2411                                 s->device->silence_generator = NULL;
2412                         }
2413                         send_tone(s, 0, 0);
2414                         /* Make new channel */
2415                         c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN);
2416                         if (!c) {
2417                                 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
2418                                 return;
2419                         }
2420                         /* Swap things around between the three-way and real call */
2421                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
2422                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2423                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
2424                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2425                         send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2426                         send_text_status(s, "TransfrCancel");
2427
2428                         if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
2429                                 ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
2430                                 ast_hangup(c);
2431                                 return;
2432                         }
2433                         if (unistimdebug)
2434                                 ast_verbose
2435                                         ("Started three way call on channel %p (%s) subchan %d\n",
2436                                          p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name,
2437                                          p->subs[SUB_THREEWAY]->subtype);
2438                 } else
2439                         ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
2440         }
2441         return;
2442 }
2443
2444 /* From PBX to phone */
2445 static void HandleCallIncoming(struct unistimsession *s)
2446 {
2447         struct unistim_subchannel *sub;
2448         s->state = STATE_CALL;
2449         s->device->missed_call = 0;
2450         send_no_ring(s);
2451         sub = s->device->lines->subs[SUB_REAL];
2452         if (!sub) {
2453                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2454                 return;
2455         } else if (unistimdebug)
2456                 ast_verbose("Handle Call Incoming for %s@%s\n", sub->parent->name,
2457                                         s->device->name);
2458         start_rtp(sub);
2459         if (!sub->rtp)
2460                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
2461                                 s->device->name);
2462         ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
2463         send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
2464         send_text_status(s, "Hangup Transf");
2465         send_start_timer(s);
2466
2467         if ((s->device->output == OUTPUT_HANDSET) &&
2468                 (s->device->receiver_state == STATE_ONHOOK))
2469                 send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
2470         else
2471                 send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2472         s->device->start_call_timestamp = time(0);
2473         write_history(s, 'i', 0);
2474         return;
2475 }
2476
2477 static int unistim_do_senddigit(struct unistimsession *pte, char digit)
2478 {
2479
2480         struct ast_frame f = { 0, };
2481         struct unistim_subchannel *sub;
2482         sub = pte->device->lines->subs[SUB_REAL];
2483         if (!sub->owner) {
2484                 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
2485                 return -1;
2486         }
2487         if (unistimdebug)
2488                 ast_verbose("Send Digit %c\n", digit);
2489         switch (digit) {
2490         case '0':
2491                 send_tone(pte, 941, 1336);
2492                 break;
2493         case '1':
2494                 send_tone(pte, 697, 1209);
2495                 break;
2496         case '2':
2497                 send_tone(pte, 697, 1336);
2498                 break;
2499         case '3':
2500                 send_tone(pte, 697, 1477);
2501                 break;
2502         case '4':
2503                 send_tone(pte, 770, 1209);
2504                 break;
2505         case '5':
2506                 send_tone(pte, 770, 1336);
2507                 break;
2508         case '6':
2509                 send_tone(pte, 770, 1477);
2510                 break;
2511         case '7':
2512                 send_tone(pte, 852, 1209);
2513                 break;
2514         case '8':
2515                 send_tone(pte, 852, 1336);
2516                 break;
2517         case '9':
2518                 send_tone(pte, 852, 1477);
2519                 break;
2520         case 'A':
2521                 send_tone(pte, 697, 1633);
2522                 break;
2523         case 'B':
2524                 send_tone(pte, 770, 1633);
2525                 break;
2526         case 'C':
2527                 send_tone(pte, 852, 1633);
2528                 break;
2529         case 'D':
2530                 send_tone(pte, 941, 1633);
2531                 break;
2532         case '*':
2533                 send_tone(pte, 941, 1209);
2534                 break;
2535         case '#':
2536                 send_tone(pte, 941, 1477);
2537                 break;
2538         default:
2539                 send_tone(pte, 500, 2000);
2540         }
2541         usleep(150000);                  /* XXX Less than perfect, blocking an important thread is not a good idea */
2542         send_tone(pte, 0, 0);
2543         f.frametype = AST_FRAME_DTMF;
2544         f.subclass = digit;
2545         f.src = "unistim";
2546         ast_queue_frame(sub->owner, &f);
2547         return 0;
2548 }
2549
2550 static void key_call(struct unistimsession *pte, char keycode)
2551 {
2552         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2553                 if (keycode == KEY_SHARP)
2554                         keycode = '#';
2555                 else if (keycode == KEY_STAR)
2556                         keycode = '*';
2557                 else
2558                         keycode -= 0x10;
2559                 unistim_do_senddigit(pte, keycode);
2560                 return;
2561         }
2562         switch (keycode) {
2563         case KEY_HANGUP:
2564         case KEY_FUNC1:
2565                 close_call(pte);
2566                 break;
2567         case KEY_FUNC2:
2568                 TransferCallStep1(pte);
2569                 break;
2570         case KEY_HEADPHN:
2571                 if (pte->device->output == OUTPUT_HEADPHONE)
2572                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2573                 else
2574                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2575                 break;
2576         case KEY_LOUDSPK:
2577                 if (pte->device->output != OUTPUT_SPEAKER)
2578                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2579                 else
2580                         send_select_output(pte, pte->device->previous_output, pte->device->volume,
2581                                                          MUTE_OFF);
2582                 break;
2583         case KEY_MUTE:
2584                 if (!pte->device->moh) {
2585                         if (pte->device->mute == MUTE_ON)
2586                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2587                         else
2588                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2589                         break;
2590                 }
2591         case KEY_ONHOLD:
2592                 {
2593                         struct unistim_subchannel *sub;
2594                         struct ast_channel *bridgepeer = NULL;
2595                         sub = pte->device->lines->subs[SUB_REAL];
2596                         if (!sub->owner) {
2597                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2598                                 return;
2599                         }
2600                         if ((bridgepeer = ast_bridged_channel(sub->owner))) {
2601                                 if (pte->device->moh) {
2602                                         ast_moh_stop(bridgepeer);
2603                                         pte->device->moh = 0;
2604                                         send_select_output(pte, pte->device->output, pte->device->volume,
2605                                                                          MUTE_OFF);
2606                                 } else {
2607                                         ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
2608                                         pte->device->moh = 1;
2609                                         send_select_output(pte, pte->device->output, pte->device->volume,
2610                                                                          MUTE_ON);
2611                                 }
2612                         } else
2613                                 ast_log(LOG_WARNING,
2614                                                 "Unable to find peer subchannel for music on hold\n");
2615                         break;
2616                 }
2617         }
2618         return;
2619 }
2620
2621 static void key_ringing(struct unistimsession *pte, char keycode)
2622 {
2623         if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
2624                 HandleCallIncoming(pte);
2625                 return;
2626         }
2627         switch (keycode) {
2628         case KEY_HANGUP:
2629         case KEY_FUNC4:
2630                 IgnoreCall(pte);
2631                 break;
2632         case KEY_FUNC1:
2633                 HandleCallIncoming(pte);
2634                 break;
2635         }
2636         return;
2637 }
2638
2639 static void Keyfavorite(struct unistimsession *pte, char keycode)
2640 {
2641         int fav;
2642
2643         if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
2644                 ast_log(LOG_WARNING, "It's not a favorite key\n");
2645                 return;
2646         }
2647         if (keycode == KEY_FAV0)
2648                 return;
2649         fav = keycode - KEY_FAV0;
2650         if (pte->device->softkeyicon[fav] == 0)
2651                 return;
2652         ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
2653                                         sizeof(pte->device->phone_number));
2654         HandleCallOutgoing(pte);
2655         return;
2656 }
2657
2658 static void key_dial_page(struct unistimsession *pte, char keycode)
2659 {
2660         if (keycode == KEY_FUNC3) {
2661                 if (pte->device->size_phone_number <= 1)
2662                         keycode = KEY_FUNC4;
2663                 else {
2664                         pte->device->size_phone_number -= 2;
2665                         keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
2666                 }
2667         }
2668         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2669                 char tmpbuf[] = "Number : ...............";
2670                 int i = 0;
2671
2672                 if (pte->device->size_phone_number >= 15)
2673                         return;
2674                 if (pte->device->size_phone_number == 0)
2675                         send_tone(pte, 0, 0);
2676                 while (i < pte->device->size_phone_number) {
2677                         tmpbuf[i + 9] = pte->device->phone_number[i];
2678                         i++;
2679                 }
2680                 if (keycode == KEY_SHARP)
2681                         keycode = '#';
2682                 else if (keycode == KEY_STAR)
2683                         keycode = '*';
2684                 else
2685                         keycode -= 0x10;
2686                 tmpbuf[i + 9] = keycode;
2687                 pte->device->phone_number[i] = keycode;
2688                 pte->device->size_phone_number++;
2689                 pte->device->phone_number[i + 1] = 0;
2690                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2691                 send_blink_cursor(pte);
2692                 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
2693                 return;
2694         }
2695         if (keycode == KEY_FUNC4) {
2696
2697                 pte->device->size_phone_number = 0;
2698                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2699                 send_blink_cursor(pte);
2700                 send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2701                 return;
2702         }
2703
2704         if (pte->device->call_forward[0] == -1) {
2705                 if (keycode == KEY_FUNC1) {
2706                         ast_copy_string(pte->device->call_forward, pte->device->phone_number,
2707                                                         sizeof(pte->device->call_forward));
2708                         show_main_page(pte);
2709                 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
2710                         pte->device->call_forward[0] = '\0';
2711                         show_main_page(pte);
2712                 }
2713                 return;
2714         }
2715         switch (keycode) {
2716         case KEY_FUNC2:
2717                 if (ast_strlen_zero(pte->device->redial_number))
2718                         break;
2719                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
2720                                                 sizeof(pte->device->phone_number));
2721         case KEY_FUNC1:
2722                 HandleCallOutgoing(pte);
2723                 break;
2724         case KEY_HANGUP:
2725                 if (pte->device->lines->subs[SUB_REAL]->owner) {
2726                         /* Stop the silence generator */
2727                         if (pte->device->silence_generator) {
2728                                 if (unistimdebug)
2729                                         ast_verbose("Stopping silence generator\n");
2730                                 ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
2731                                                                                                    owner, pte->device->silence_generator);
2732                                 pte->device->silence_generator = NULL;
2733                         }
2734                         send_tone(pte, 0, 0);
2735                         ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
2736                         pte->device->moh = 0;
2737                         pte->state = STATE_CALL;
2738                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
2739                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
2740                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
2741                         send_text_status(pte, "Hangup Transf");
2742                 } else
2743                         show_main_page(pte);
2744                 break;
2745         case KEY_FAV1:
2746         case KEY_FAV2:
2747         case KEY_FAV3:
2748         case KEY_FAV4:
2749         case KEY_FAV5:
2750                 Keyfavorite(pte, keycode);
2751                 break;
2752         case KEY_LOUDSPK:
2753                 if (pte->device->output == OUTPUT_SPEAKER) {
2754                         if (pte->device->receiver_state == STATE_OFFHOOK)
2755                                 send_select_output(pte, pte->device->previous_output, pte->device->volume,
2756                                                                  MUTE_OFF);
2757                         else
2758                                 show_main_page(pte);
2759                 } else
2760                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2761                 break;
2762         case KEY_HEADPHN:
2763                 if (pte->device->output == OUTPUT_HEADPHONE) {
2764                         if (pte->device->receiver_state == STATE_OFFHOOK)
2765                                 send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2766                         else
2767                                 show_main_page(pte);
2768                 } else
2769                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2770                 break;
2771         }
2772         return;
2773 }
2774
2775 #define SELECTCODEC_START_ENTRY_POS 15
2776 #define SELECTCODEC_MAX_LENGTH 2
2777 #define SELECTCODEC_MSG "Codec number : .."
2778 static void HandleSelectCodec(struct unistimsession *pte)
2779 {
2780         char buf[30], buf2[5];
2781
2782         pte->state = STATE_SELECTCODEC;
2783         strcpy(buf, "Using codec ");
2784         sprintf(buf2, "%d", pte->device->codec_number);
2785         strcat(buf, buf2);
2786         strcat(buf, " (G711u=0,");
2787
2788         send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
2789         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
2790         send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2791         send_blink_cursor(pte);
2792         send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2793         pte->size_buff_entry = 0;
2794         send_text_status(pte, "Select BackSpcErase  Cancel");
2795         return;
2796 }
2797
2798 static void key_select_codec(struct unistimsession *pte, char keycode)
2799 {
2800         if (keycode == KEY_FUNC2) {
2801                 if (pte->size_buff_entry <= 1)
2802                         keycode = KEY_FUNC3;
2803                 else {
2804                         pte->size_buff_entry -= 2;
2805                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2806                 }
2807         }
2808         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2809                 char tmpbuf[] = SELECTCODEC_MSG;
2810                 int i = 0;
2811
2812                 if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
2813                         return;
2814
2815                 while (i < pte->size_buff_entry) {
2816                         tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
2817                         i++;
2818                 }
2819                 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
2820                 pte->buff_entry[i] = keycode - 0x10;
2821                 pte->size_buff_entry++;
2822                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
2823                 send_blink_cursor(pte);
2824                 send_cursor_pos(pte,
2825                                           (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
2826                 return;
2827         }
2828
2829         switch (keycode) {
2830         case KEY_FUNC1:
2831                 if (pte->size_buff_entry == 1)
2832                         pte->device->codec_number = pte->buff_entry[0] - 48;
2833                 else if (pte->size_buff_entry == 2)
2834                         pte->device->codec_number =
2835                                 ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
2836                 show_main_page(pte);
2837                 break;
2838         case KEY_FUNC3:
2839                 pte->size_buff_entry = 0;
2840                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2841                 send_blink_cursor(pte);
2842                 send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2843                 break;
2844         case KEY_HANGUP:
2845         case KEY_FUNC4:
2846                 show_main_page(pte);
2847                 break;
2848         }
2849         return;
2850 }
2851
2852 #define SELECTEXTENSION_START_ENTRY_POS 0
2853 #define SELECTEXTENSION_MAX_LENGTH 10
2854 #define SELECTEXTENSION_MSG ".........."
2855 static void ShowExtensionPage(struct unistimsession *pte)
2856 {
2857         pte->state = STATE_EXTENSION;
2858
2859         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
2860         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
2861         send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
2862         send_blink_cursor(pte);
2863         send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
2864         send_text_status(pte, "Enter  BackSpcErase");
2865         pte->size_buff_entry = 0;
2866         return;
2867 }
2868
2869 static void key_select_extension(struct unistimsession *pte, char keycode)
2870 {
2871         if (keycode == KEY_FUNC2) {
2872                 if (pte->size_buff_entry <= 1)
2873                         keycode = KEY_FUNC3;
2874                 else {
2875                         pte->size_buff_entry -= 2;
2876                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2877                 }
2878         }
2879         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2880                 char tmpbuf[] = SELECTEXTENSION_MSG;
2881                 int i = 0;
2882
2883                 if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
2884                         return;
2885
2886                 while (i < pte->size_buff_entry) {
2887                         tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
2888                         i++;
2889                 }
2890                 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
2891                 pte->buff_entry[i] = keycode - 0x10;
2892                 pte->size_buff_entry++;
2893                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2894                 send_blink_cursor(pte);
2895                 send_cursor_pos(pte,
2896                                           (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
2897                                                                            i));
2898                 return;
2899         }
2900
2901         switch (keycode) {
2902         case KEY_FUNC1:
2903                 if (pte->size_buff_entry < 1)
2904                         return;
2905                 if (autoprovisioning == AUTOPROVISIONING_TN) {
2906                         struct unistim_device *d;
2907
2908                         /* First step : looking for this TN in our device list */
2909                         ast_mutex_lock(&devicelock);
2910                         d = devices;
2911                         pte->buff_entry[pte->size_buff_entry] = '\0';
2912                         while (d) {
2913                                 if (d->id[0] == 'T') {  /* It's a TN device ? */
2914                                         /* It's the TN we're looking for ? */
2915                                         if (!strcmp((d->id) + 1, pte->buff_entry)) {
2916                                                 pte->device = d;
2917                                                 d->session = pte;
2918                                                 d->codec_number = DEFAULT_CODEC;
2919                                                 d->pos_fav = 0;
2920                                                 d->missed_call = 0;
2921                                                 d->receiver_state = STATE_ONHOOK;
2922                                                 strcpy(d->id, pte->macaddr);
2923                                                 pte->device->extension_number[0] = 'T';
2924                                                 pte->device->extension = EXTENSION_TN;
2925                                                 ast_copy_string((pte->device->extension_number) + 1,
2926                                                                                 pte->buff_entry, pte->size_buff_entry + 1);
2927                                                 ast_mutex_unlock(&devicelock);
2928                                                 show_main_page(pte);
2929                                                 refresh_all_favorite(pte);
2930                                                 return;
2931                                         }
2932                                 }
2933                                 d = d->next;
2934                         }
2935                         ast_mutex_unlock(&devicelock);
2936                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number.");
2937                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
2938                         send_cursor_pos(pte,
2939                                                   (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
2940                                                                                    pte->size_buff_entry));
2941                         send_blink_cursor(pte);
2942                 } else {
2943                         ast_copy_string(pte->device->extension_number, pte->buff_entry,
2944                                                         pte->size_buff_entry + 1);
2945                         if (RegisterExtension(pte)) {
2946                                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension.");
2947                                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
2948                                 send_cursor_pos(pte,
2949                                                           (unsigned char) (TEXT_LINE2 +
2950                                                                                            SELECTEXTENSION_START_ENTRY_POS +
2951                                                                                            pte->size_buff_entry));
2952                                 send_blink_cursor(pte);
2953                         } else
2954                                 show_main_page(pte);
2955                 }
2956                 break;
2957         case KEY_FUNC3:
2958                 pte->size_buff_entry = 0;
2959                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
2960                 send_blink_cursor(pte);
2961                 send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
2962                 break;
2963         }
2964         return;
2965 }
2966
2967 static int ReformatNumber(char *number)
2968 {
2969         int pos = 0, i = 0, size = strlen(number);
2970
2971         for (; i < size; i++) {
2972                 if ((number[i] >= '0') && (number[i] <= '9')) {
2973                         if (i == pos) {
2974                                 pos++;
2975                                 continue;
2976                         }
2977                         number[pos] = number[i];
2978                         pos++;
2979                 }
2980         }
2981         number[pos] = 0;
2982         return pos;
2983 }
2984
2985 static void show_entry_history(struct unistimsession *pte, FILE ** f)
2986 {
2987         char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
2988                 func3[10];
2989
2990         if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
2991                 display_last_error("Can't read history date entry");
2992                 fclose(*f);
2993                 return;
2994         }
2995         line[sizeof(line) - 1] = '\0';
2996         send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
2997         if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
2998                 display_last_error("Can't read callerid entry");
2999                 fclose(*f);
3000                 return;
3001         }
3002         line[sizeof(line) - 1] = '\0';
3003         ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
3004         send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
3005         if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
3006                 display_last_error("Can't read callername entry");
3007                 fclose(*f);
3008                 return;
3009         }
3010         line[sizeof(line) - 1] = '\0';
3011         send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
3012         fclose(*f);
3013
3014         snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2],
3015                          pte->buff_entry[1]);
3016         send_texttitle(pte, line);
3017
3018         if (pte->buff_entry[2] == 1)
3019                 strcpy(func1, "       ");
3020         else
3021                 strcpy(func1, "Prvious");
3022         if (pte->buff_entry[2] >= pte->buff_entry[1])
3023                 strcpy(func2, "       ");
3024         else
3025                 strcpy(func2, "Next   ");
3026         if (ReformatNumber(pte->device->lst_cid))
3027                 strcpy(func3, "Redial ");
3028         else
3029                 strcpy(func3, "       ");
3030         snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3);
3031         send_text_status(pte, status);
3032 }
3033
3034 static char OpenHistory(struct unistimsession *pte, char way, FILE ** f)
3035 {
3036         char tmp[AST_CONFIG_MAX_PATH];
3037         char count;
3038
3039         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
3040                          USTM_LOG_DIR, pte->device->name, way);
3041         *f = fopen(tmp, "r");
3042         if (!*f) {
3043                 display_last_error("Unable to open history file");
3044                 return 0;
3045         }
3046         if (fread(&count, 1, 1, *f) != 1) {
3047                 display_last_error("Unable to read history header - display.");
3048                 fclose(*f);
3049                 return 0;
3050         }
3051         if (count > MAX_ENTRY_LOG) {
3052                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
3053                                 count, MAX_ENTRY_LOG);
3054                 fclose(*f);
3055                 return 0;
3056         }
3057         return count;
3058 }
3059
3060 static void show_history(struct unistimsession *pte, char way)
3061 {
3062         FILE *f;
3063         char count;
3064
3065         if (!pte->device)
3066                 return;
3067         if (!pte->device->callhistory)
3068                 return;
3069         count = OpenHistory(pte, way, &f);
3070         if (!count)
3071                 return;
3072         pte->buff_entry[0] = way;
3073         pte->buff_entry[1] = count;
3074         pte->buff_entry[2] = 1;
3075         show_entry_history(pte, &f);
3076         pte->state = STATE_HISTORY;
3077 }
3078
3079 static void show_main_page(struct unistimsession *pte)
3080 {
3081         char tmpbuf[TEXT_LENGTH_MAX + 1];
3082
3083
3084         if ((pte->device->extension == EXTENSION_ASK) &&
3085                 (ast_strlen_zero(pte->device->extension_number))) {
3086                 ShowExtensionPage(pte);
3087                 return;
3088         }
3089
3090         pte->state = STATE_MAINPAGE;
3091
3092         send_tone(pte, 0, 0);
3093         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET);
3094         pte->device->lines->lastmsgssent = 0;
3095         send_favorite(pte->device->softkeylinepos, FAV_ICON_ONHOOK_BLACK, pte,
3096                                  pte->device->softkeylabel[pte->device->softkeylinepos]);
3097         if (!ast_strlen_zero(pte->device->call_forward)) {
3098                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Call forwarded to :");
3099                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward);
3100                 Sendicon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte);
3101                 send_text_status(pte, "Dial   Redial NoForwd");
3102         } else {
3103                 if ((pte->device->extension == EXTENSION_ASK) ||
3104                         (pte->device->extension == EXTENSION_TN))
3105                         send_text_status(pte, "Dial   Redial ForwardUnregis");
3106                 else
3107                         send_text_status(pte, "Dial   Redial Forward");
3108
3109                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1);
3110                 if (pte->device->missed_call == 0)
3111                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0);
3112                 else {
3113                         sprintf(tmpbuf, "%d unanswered call(s)", pte->device->missed_call);
3114                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
3115                         Sendicon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte);
3116                 }
3117         }
3118         if (ast_strlen_zero(pte->device->maintext2)) {
3119                 strcpy(tmpbuf, "IP : ");
3120                 strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
3121                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
3122         } else
3123                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2);
3124         send_texttitle(pte, pte->device->titledefault);
3125         change_favorite_icon(pte, FAV_ICON_ONHOOK_BLACK);
3126 }
3127
3128 static void key_main_page(struct unistimsession *pte, char keycode)
3129 {
3130         if (pte->device->missed_call) {
3131                 Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
3132                 pte->device->missed_call = 0;
3133         }
3134         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3135                 handle_dial_page(pte);
3136                 key_dial_page(pte, keycode);
3137                 return;
3138         }
3139         switch (keycode) {
3140         case KEY_FUNC1:
3141                 handle_dial_page(pte);
3142                 break;
3143         case KEY_FUNC2:
3144                 if (ast_strlen_zero(pte->device->redial_number))
3145                         break;
3146                 if ((pte->device->output == OUTPUT_HANDSET) &&
3147                         (pte->device->receiver_state == STATE_ONHOOK))
3148                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3149                 else
3150                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3151
3152                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
3153                                                 sizeof(pte->device->phone_number));
3154                 HandleCallOutgoing(pte);
3155                 break;
3156         case KEY_FUNC3:
3157                 if (!ast_strlen_zero(pte->device->call_forward)) {
3158                         /* Cancel call forwarding */
3159                         memmove(pte->device->call_forward + 1, pte->device->call_forward,
3160                                         sizeof(pte->device->call_forward));
3161                         pte->device->call_forward[0] = '\0';
3162                         Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
3163                         pte->device->output = OUTPUT_HANDSET;   /* Seems to be reseted somewhere */
3164                         show_main_page(pte);
3165                         break;
3166                 }
3167                 pte->device->call_forward[0] = -1;
3168                 handle_dial_page(pte);
3169                 break;
3170         case KEY_FUNC4:
3171                 if (pte->device->extension == EXTENSION_ASK) {
3172                         UnregisterExtension(pte);
3173                         pte->device->extension_number[0] = '\0';
3174                         ShowExtensionPage(pte);
3175                 } else if (pte->device->extension == EXTENSION_TN) {
3176                         ast_mutex_lock(&devicelock);
3177                         strcpy(pte->device->id, pte->device->extension_number);
3178                         pte->buff_entry[0] = '\0';
3179                         pte->size_buff_entry = 0;
3180                         pte->device->session = NULL;
3181                         pte->device = NULL;
3182                         ast_mutex_unlock(&devicelock);
3183                         ShowExtensionPage(pte);
3184                 }
3185                 break;
3186         case KEY_FAV0:
3187                 handle_dial_page(pte);
3188                 break;
3189         case KEY_FAV1:
3190         case KEY_FAV2:
3191         case KEY_FAV3:
3192         case KEY_FAV4:
3193         case KEY_FAV5:
3194                 if ((pte->device->output == OUTPUT_HANDSET) &&
3195                         (pte->device->receiver_state == STATE_ONHOOK))
3196                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3197                 else
3198                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3199                 Keyfavorite(pte, keycode);
3200                 break;
3201         case KEY_CONF:
3202                 HandleSelectCodec(pte);
3203                 break;
3204         case KEY_LOUDSPK:
3205                 send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3206                 handle_dial_page(pte);
3207                 break;
3208         case KEY_HEADPHN:
3209                 send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
3210                 handle_dial_page(pte);
3211                 break;
3212         case KEY_SNDHIST:
3213                 show_history(pte, 'o');
3214                 break;
3215         case KEY_RCVHIST:
3216                 show_history(pte, 'i');
3217                 break;
3218         }
3219         return;
3220 }
3221
3222 static void key_history(struct unistimsession *pte, char keycode)
3223 {
3224         FILE *f;
3225         char count;
3226         long offset;
3227
3228         switch (keycode) {
3229         case KEY_UP:
3230         case KEY_LEFT:
3231         case KEY_FUNC1:
3232                 if (pte->buff_entry[2] <= 1)
3233                         return;
3234                 pte->buff_entry[2]--;
3235                 count = OpenHistory(pte, pte->buff_entry[0], &f);
3236                 if (!count)
3237                         return;
3238                 offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
3239                 if (fseek(f, offset, SEEK_CUR)) {
3240                         display_last_error("Unable to seek history entry.");
3241                         fclose(f);
3242                         return;
3243                 }
3244                 show_entry_history(pte, &f);
3245                 break;
3246         case KEY_DOWN:
3247         case KEY_RIGHT:
3248         case KEY_FUNC2:
3249                 if (pte->buff_entry[2] >= pte->buff_entry[1])
3250                         return;
3251                 pte->buff_entry[2]++;
3252                 count = OpenHistory(pte, pte->buff_entry[0], &f);
3253                 if (!count)
3254                         return;
3255                 offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
3256                 if (fseek(f, offset, SEEK_CUR)) {
3257                         display_last_error("Unable to seek history entry.");
3258                         fclose(f);
3259                         return;
3260                 }
3261                 show_entry_history(pte, &f);
3262                 break;
3263         case KEY_FUNC3:
3264                 if (!ReformatNumber(pte->device->lst_cid))
3265                         break;
3266                 ast_copy_string(pte->device->redial_number, pte->device->lst_cid,
3267                                                 sizeof(pte->device->redial_number));
3268                 key_main_page(pte, KEY_FUNC2);
3269                 break;
3270         case KEY_FUNC4:
3271         case KEY_HANGUP:
3272                 show_main_page(pte);
3273                 break;
3274         case KEY_SNDHIST:
3275                 if (pte->buff_entry[0] == 'i')
3276                         show_history(pte, 'o');
3277                 else
3278                         show_main_page(pte);
3279                 break;
3280         case KEY_RCVHIST:
3281                 if (pte->buff_entry[0] == 'i')
3282                         show_main_page(pte);
3283                 else
3284                         show_history(pte, 'i');
3285                 break;
3286         }
3287         return;
3288 }
3289
3290 static void init_phone_step2(struct unistimsession *pte)
3291 {
3292         BUFFSEND;
3293         if (unistimdebug)
3294                 ast_verbose("Sending S4\n");
3295         memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
3296         send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
3297         send_date_time2(pte);
3298         send_date_time3(pte);
3299         if (unistimdebug)
3300                 ast_verbose("Sending S7\n");
3301         memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
3302         send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
3303         if (unistimdebug)
3304                 ast_verbose("Sending Contrast\n");
3305         memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
3306         if (pte->device != NULL)
3307                 buffsend[9] = pte->device->contrast;
3308         send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
3309
3310         if (unistimdebug)
3311                 ast_verbose("Sending S9\n");
3312         memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
3313         send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
3314         send_no_ring(pte);
3315
3316         if (unistimdebug)
3317                 ast_verbose("Sending S7\n");
3318         memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
3319         send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
3320         send_led_update(pte, 0);
3321         send_ping(pte);
3322         if (pte->state < STATE_MAINPAGE) {
3323                 if (autoprovisioning == AUTOPROVISIONING_TN) {
3324                         ShowExtensionPage(pte);
3325                         return;
3326                 } else {
3327                         int i;
3328                         char tmp[30];
3329
3330                         for (i = 1; i < 6; i++)
3331                                 send_favorite(i, 0, pte, "");
3332                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Sorry, this phone is not");
3333                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "registred in unistim.cfg");
3334                         strcpy(tmp, "MAC = ");
3335                         strcat(tmp, pte->macaddr);
3336                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
3337                         send_text_status(pte, "");
3338                         send_texttitle(pte, "UNISTIM for*");
3339                         return;
3340                 }
3341         }
3342         show_main_page(pte);
3343         refresh_all_favorite(pte);
3344         if (unistimdebug)
3345                 ast_verbose("Sending arrow\n");
3346         memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
3347         send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
3348         return;
3349 }
3350
3351 static void process_request(int size, unsigned char *buf, struct unistimsession *pte)
3352 {
3353         char tmpbuf[255];
3354         if (memcmp
3355                 (buf + SIZE_HEADER, packet_recv_resume_connection_with_server,
3356                  sizeof(packet_recv_resume_connection_with_server)) == 0) {
3357                 rcv_resume_connection_with_server(pte);
3358                 return;
3359         }
3360         if (memcmp(buf + SIZE_HEADER, packet_recv_firm_version, sizeof(packet_recv_firm_version)) ==
3361                 0) {
3362                 buf[size] = 0;
3363                 if (unistimdebug)
3364                         ast_verbose("Got the firmware version : '%s'\n", buf + 13);
3365                 init_phone_step2(pte);
3366                 return;
3367         }
3368         if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
3369                 rcv_mac_addr(pte, buf);
3370                 return;
3371         }
3372         if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
3373                 if (unistimdebug)
3374                         ast_verbose("R2 received\n");
3375                 return;
3376         }
3377
3378         if (pte->state < STATE_MAINPAGE) {
3379                 if (unistimdebug)
3380                         ast_verbose("Request not authorized in this state\n");
3381                 return;
3382         }
3383         if (!memcmp(buf + SIZE_HEADER, packet_recv_pressed_key, sizeof(packet_recv_pressed_key))) {
3384                 char keycode = buf[13];
3385
3386                 if (unistimdebug)
3387                         ast_verbose("Key pressed : keycode = 0x%.2x - current state : %d\n", keycode,
3388                                                 pte->state);
3389
3390                 switch (pte->state) {
3391                 case STATE_INIT:
3392                         if (unistimdebug)
3393                                 ast_verbose("No keys allowed in the init state\n");
3394                         break;
3395                 case STATE_AUTHDENY:
3396                         if (unistimdebug)
3397                                 ast_verbose("No keys allowed in authdeny state\n");
3398                         break;
3399                 case STATE_MAINPAGE:
3400                         key_main_page(pte, keycode);
3401                         break;
3402                 case STATE_DIALPAGE:
3403                         key_dial_page(pte, keycode);
3404                         break;
3405                 case STATE_RINGING:
3406                         key_ringing(pte, keycode);
3407                         break;
3408                 case STATE_CALL:
3409                         key_call(pte, keycode);
3410                         break;
3411                 case STATE_EXTENSION:
3412                         key_select_extension(pte, keycode);
3413                         break;
3414                 case STATE_SELECTCODEC:
3415                         key_select_codec(pte, keycode);
3416                         break;
3417                 case STATE_HISTORY:
3418                         key_history(pte, keycode);
3419                         break;
3420                 default:
3421                         ast_log(LOG_WARNING, "Key : Unknown state\n");
3422                 }
3423                 return;
3424         }
3425         if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
3426                 if (unistimdebug)
3427                         ast_verbose("Handset off hook\n");
3428                 if (!pte->device)              /* We are not yet registred (asking for a TN in AUTOPROVISIONING_TN) */
3429                         return;
3430                 pte->device->receiver_state = STATE_OFFHOOK;
3431                 if (pte->device->output == OUTPUT_HEADPHONE)
3432                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
3433                 else
3434                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
3435                 if (pte->state == STATE_RINGING)
3436