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