48a41fc7ab8b1c54d7f867d95158b98fadc2b12f
[asterisk/asterisk.git] / channels / chan_unistim.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * UNISTIM channel driver for asterisk
5  *
6  * Copyright (C) 2005 - 2007, Cedric Hans
7  * 
8  * Cedric Hans <cedric.hans@mlkj.net>
9  *
10  * Asterisk 1.4 patch by Peter Be
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20  * at the top of the source tree.
21  */
22
23 /*!
24  * \file
25  *
26  * \brief chan_unistim channel driver for Asterisk
27  * \author Cedric Hans <cedric.hans@mlkj.net>
28  *
29  * Unistim (Unified Networks IP Stimulus) channel driver
30  * for Nortel i2002, i2004 and i2050
31  *
32  * \ingroup channel_drivers
33  */
34
35 #include "asterisk.h"
36
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38
39 #include <sys/stat.h>
40 #include <signal.h>
41
42 #if defined(__CYGWIN__)
43 /*
44  * cygwin headers are partly inconsistent. struct iovec is defined in sys/uio.h
45  * which is not included by default by sys/socket.h - in_pktinfo is defined in
46  * w32api/ws2tcpip.h but this probably has compatibility problems with sys/socket.h
47  * So for the time being we simply disable HAVE_PKTINFO when building under cygwin.
48  *    This should be done in some common header, but for now this is the only file
49  * using iovec and in_pktinfo so it suffices to apply the fix here.
50  */
51 #ifdef HAVE_PKTINFO
52 #undef HAVE_PKTINFO
53 #endif
54 #endif /* __CYGWIN__ */
55
56 #include "asterisk/paths.h"     /* ast_config_AST_LOG_DIR used in (too ?) many places */
57 #include "asterisk/network.h"
58 #include "asterisk/channel.h"
59 #include "asterisk/config.h"
60 #include "asterisk/module.h"
61 #include "asterisk/pbx.h"
62 #include "asterisk/event.h"
63 #include "asterisk/rtp.h"
64 #include "asterisk/netsock.h"
65 #include "asterisk/acl.h"
66 #include "asterisk/callerid.h"
67 #include "asterisk/cli.h"
68 #include "asterisk/app.h"
69 #include "asterisk/musiconhold.h"
70 #include "asterisk/causes.h"
71 #include "asterisk/indications.h"
72
73 /*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */
74 #define CAPABILITY AST_FORMAT_ALAW | AST_FORMAT_ULAW    /* | AST_FORMAT_G729A | AST_FORMAT_G723_1 */
75
76 #define DEFAULTCONTEXT    "default"
77 #define DEFAULTCALLERID  "Unknown"
78 #define DEFAULTCALLERNAME       " "
79 #define USTM_LOG_DIR        "unistimHistory"
80
81 /*! Size of the transmit buffer */
82 #define MAX_BUF_SIZE        64
83 /*! Number of slots for the transmit queue */
84 #define MAX_BUF_NUMBER    50
85 /*! Try x times before removing the phone */
86 #define NB_MAX_RETRANSMIT       8
87 /*! Nb of milliseconds waited when no events are scheduled */
88 #define IDLE_WAIT              1000
89 /*! Wait x milliseconds before resending a packet */
90 #define RETRANSMIT_TIMER        2000
91 /*! How often the mailbox is checked for new messages */
92 #define TIMER_MWI              10000
93 /*! Not used */
94 #define DEFAULT_CODEC      0x00
95 #define SIZE_PAGE              4096
96 #define DEVICE_NAME_LEN  16
97 #define AST_CONFIG_MAX_PATH     255
98 #define MAX_ENTRY_LOG      30
99
100 #define SUB_REAL                0
101 #define SUB_THREEWAY        1
102 #define MAX_SUBS                2
103
104 enum autoprovision {
105         AUTOPROVISIONING_NO = 0,
106         AUTOPROVISIONING_YES,
107         AUTOPROVISIONING_DB,
108         AUTOPROVISIONING_TN
109 };
110
111 enum autoprov_extn {
112         /*! Do not create an extension into the default dialplan */
113         EXTENSION_NONE = 0,
114         /*! Prompt user for an extension number and register it */
115         EXTENSION_ASK,
116         /*! Register an extension with the line=> value */
117         EXTENSION_LINE,
118         /*! Used with AUTOPROVISIONING_TN */
119         EXTENSION_TN
120 };
121 #define OUTPUT_HANDSET    0xC0
122 #define OUTPUT_HEADPHONE        0xC1
123 #define OUTPUT_SPEAKER    0xC2
124
125 #define VOLUME_LOW            0x01
126 #define VOLUME_LOW_SPEAKER      0x03
127 #define VOLUME_NORMAL      0x02
128 #define VOLUME_INSANELY_LOUD    0x07
129
130 #define MUTE_OFF                0x00
131 #define MUTE_ON          0xFF
132 #define MUTE_ON_DISCRET  0xCE
133
134 #define SIZE_HEADER          6
135 #define SIZE_MAC_ADDR      17
136 #define TEXT_LENGTH_MAX  24
137 #define TEXT_LINE0            0x00
138 #define TEXT_LINE1            0x20
139 #define TEXT_LINE2            0x40
140 #define TEXT_NORMAL          0x05
141 #define TEXT_INVERSE        0x25
142 #define STATUS_LENGTH_MAX       28
143
144 #define FAV_ICON_NONE              0x00
145 #define FAV_ICON_ONHOOK_BLACK      0x20
146 #define FAV_ICON_ONHOOK_WHITE      0x21
147 #define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22
148 #define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23
149 #define FAV_ICON_OFFHOOK_BLACK    0x24
150 #define FAV_ICON_OFFHOOK_WHITE    0x25
151 #define FAV_ICON_ONHOLD_BLACK      0x26
152 #define FAV_ICON_ONHOLD_WHITE      0x27
153 #define FAV_ICON_SPEAKER_OFFHOOK_BLACK  0x28
154 #define FAV_ICON_SPEAKER_OFFHOOK_WHITE  0x29
155 #define FAV_ICON_PHONE_BLACK        0x2A
156 #define FAV_ICON_PHONE_WHITE        0x2B
157 #define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C
158 #define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D
159 #define FAV_ICON_HEADPHONES          0x2E
160 #define FAV_ICON_HEADPHONES_ONHOLD      0x2F
161 #define FAV_ICON_HOME              0x30
162 #define FAV_ICON_CITY              0x31
163 #define FAV_ICON_SHARP            0x32
164 #define FAV_ICON_PAGER            0x33
165 #define FAV_ICON_CALL_CENTER        0x34
166 #define FAV_ICON_FAX                0x35
167 #define FAV_ICON_MAILBOX                0x36
168 #define FAV_ICON_REFLECT                0x37
169 #define FAV_ICON_COMPUTER              0x38
170 #define FAV_ICON_FORWARD                0x39
171 #define FAV_ICON_LOCKED          0x3A
172 #define FAV_ICON_TRASH            0x3B
173 #define FAV_ICON_INBOX            0x3C
174 #define FAV_ICON_OUTBOX          0x3D
175 #define FAV_ICON_MEETING                0x3E
176 #define FAV_ICON_BOX                0x3F
177
178 #define FAV_BLINK_FAST            0x20
179 #define FAV_BLINK_SLOW            0x40
180
181 #define FAV_MAX_LENGTH            0x0A
182
183 static void dummy(char *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 *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 ind_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_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 registred ? */
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 *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;
2031         struct sockaddr_in public;
2032         struct sockaddr_in sin;
2033         int codec;
2034         struct sockaddr_in sout;
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_new_with_bindaddr(sched, io, 1, 0, sout.sin_addr);
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         if (sub->rtp && sub->owner) {
2067                 sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
2068                 sub->owner->fds[1] = ast_rtcp_fd(sub->rtp);
2069         }
2070         if (sub->rtp) {
2071                 ast_rtp_setqos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2072                 ast_rtp_setnat(sub->rtp, sub->parent->parent->nat);
2073         }
2074
2075         /* Create the RTP connection */
2076         ast_rtp_get_us(sub->rtp, &us);
2077         sin.sin_family = AF_INET;
2078         /* Setting up RTP for our side */
2079         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2080                    sizeof(sin.sin_addr));
2081         sin.sin_port = htons(sub->parent->parent->rtp_port);
2082         ast_rtp_set_peer(sub->rtp, &sin);
2083         if (!(sub->owner->nativeformats & sub->owner->readformat)) {
2084                 int fmt;
2085                 fmt = ast_best_codec(sub->owner->nativeformats);
2086                 ast_log(LOG_WARNING,
2087                                 "Our read/writeformat has been changed to something incompatible : %s (%d), using %s (%d) best codec from %d\n",
2088                                 ast_getformatname(sub->owner->readformat),
2089                                 sub->owner->readformat, ast_getformatname(fmt), fmt,
2090                                 sub->owner->nativeformats);
2091                 sub->owner->readformat = fmt;
2092                 sub->owner->writeformat = fmt;
2093         }
2094         codec = ast_rtp_lookup_code(sub->rtp, 1, sub->owner->readformat);
2095         /* Setting up RTP of the phone */
2096         if (public_ip.sin_family == 0)  /* NAT IP override ?   */
2097                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2098         else
2099                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2100         if (unistimdebug) {
2101                 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s (%d)\n",
2102                          ast_inet_ntoa(us.sin_addr),
2103                          htons(us.sin_port), ast_getformatname(sub->owner->readformat),
2104                          sub->owner->readformat);
2105                 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2106                                         ast_inet_ntoa(public.sin_addr));
2107         }
2108         if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
2109                 (sub->owner->readformat == AST_FORMAT_ALAW)) {
2110                 if (unistimdebug)
2111                         ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2112                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2113                            sizeof(packet_send_rtp_packet_size));
2114                 buffsend[10] = codec;
2115                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend,
2116                                    sub->parent->parent->session);
2117         }
2118         if (unistimdebug)
2119                 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2120         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2121                    sizeof(packet_send_jitter_buffer_conf));
2122         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend,
2123                            sub->parent->parent->session);
2124         if (sub->parent->parent->rtp_method != 0) {
2125                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2126
2127                 if (unistimdebug)
2128                         ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n",
2129                                                 sub->parent->parent->rtp_method);
2130                 if (sub->parent->parent->rtp_method == 3)
2131                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2132                                    sizeof(packet_send_open_audio_stream_tx3));
2133                 else
2134                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2135                                    sizeof(packet_send_open_audio_stream_tx));
2136                 if (sub->parent->parent->rtp_method != 2) {
2137                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2138                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2139                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2140                         buffsend[23] = (rtcpsin_port & 0x00ff);
2141                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2142                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2143                         buffsend[24] = (us.sin_port & 0x00ff);
2144                         buffsend[27] = (rtcpsin_port & 0x00ff);
2145                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2146                 } else {
2147                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2148                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2149                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2150                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2151                         buffsend[19] = (us.sin_port & 0x00ff);
2152                         buffsend[11] = codec;
2153                 }
2154                 buffsend[12] = codec;
2155                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend,
2156                                    sub->parent->parent->session);
2157
2158                 if (unistimdebug)
2159                         ast_verb(0, "Sending OpenAudioStreamRX\n");
2160                 if (sub->parent->parent->rtp_method == 3)
2161                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2162                                    sizeof(packet_send_open_audio_stream_rx3));
2163                 else
2164                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2165                                    sizeof(packet_send_open_audio_stream_rx));
2166                 if (sub->parent->parent->rtp_method != 2) {
2167                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2168                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2169                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2170                         buffsend[23] = (rtcpsin_port & 0x00ff);
2171                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2172                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2173                         buffsend[24] = (us.sin_port & 0x00ff);
2174                         buffsend[27] = (rtcpsin_port & 0x00ff);
2175                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2176                 } else {
2177                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2178                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2179                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2180                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2181                         buffsend[19] = (us.sin_port & 0x00ff);
2182                         buffsend[12] = codec;
2183                 }
2184                 buffsend[11] = codec;
2185                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend,
2186                                    sub->parent->parent->session);
2187         } else {
2188                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2189
2190                 if (unistimdebug)
2191                         ast_verb(0, "Sending packet_send_call default method\n");
2192
2193                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2194                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2195                 /* Destination port when sending RTP */
2196                 buffsend[49] = (us.sin_port & 0x00ff);
2197                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2198                 /* Destination port when sending RTCP */
2199                 buffsend[52] = (rtcpsin_port & 0x00ff);
2200                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2201                 /* Codec */
2202                 buffsend[40] = codec;
2203                 buffsend[41] = codec;
2204                 if (sub->owner->readformat == AST_FORMAT_ULAW)
2205                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2206                 else if (sub->owner->readformat == AST_FORMAT_ALAW)
2207                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2208                 else if (sub->owner->readformat == AST_FORMAT_G723_1)
2209                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2210                 else if (sub->owner->readformat == AST_FORMAT_G729A)
2211                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2212                 else
2213                         ast_log(LOG_WARNING, "Unsupported codec %s (%d) !\n",
2214                                         ast_getformatname(sub->owner->readformat), sub->owner->readformat);
2215                 /* Source port for transmit RTP and Destination port for receiving RTP */
2216                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2217                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2218                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2219                 buffsend[48] = (rtcpsin_port & 0x00ff);
2220                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend,
2221                                    sub->parent->parent->session);
2222         }
2223         ast_mutex_unlock(&sub->lock);
2224 }
2225
2226 static void SendDialTone(struct unistimsession *pte)
2227 {
2228         int i;
2229         /* No country defined ? Using US tone */
2230         if (ast_strlen_zero(pte->device->country)) {
2231                 if (unistimdebug)
2232                         ast_verb(0, "No country defined, using US tone\n");
2233                 send_tone(pte, 350, 440);
2234                 return;
2235         }
2236         if (strlen(pte->device->country) != 2) {
2237                 if (unistimdebug)
2238                         ast_verb(0, "Country code != 2 char, using US tone\n");
2239                 send_tone(pte, 350, 440);
2240                 return;
2241         }
2242         i = 0;
2243         while (frequency[i].freq1) {
2244                 if ((frequency[i].country[0] == pte->device->country[0]) &&
2245                         (frequency[i].country[1] == pte->device->country[1])) {
2246                         if (unistimdebug)
2247                                 ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
2248                                                         frequency[i].country, frequency[i].freq1, frequency[i].freq2);
2249                         send_tone(pte, frequency[i].freq1, frequency[i].freq2);
2250                 }
2251                 i++;
2252         }
2253 }
2254
2255 static void handle_dial_page(struct unistimsession *pte)
2256 {
2257         pte->state = STATE_DIALPAGE;
2258         if (pte->device->call_forward[0] == -1) {
2259                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2260                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
2261                 send_text_status(pte, "ForwardCancel BackSpcErase");
2262                 if (pte->device->call_forward[1] != 0) {
2263                         char tmp[TEXT_LENGTH_MAX + 1];
2264
2265                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2266                                                         sizeof(pte->device->phone_number));
2267                         pte->device->size_phone_number = strlen(pte->device->phone_number);
2268                         if (pte->device->size_phone_number > 15)
2269                                 pte->device->size_phone_number = 15;
2270                         strcpy(tmp, "Number : ...............");
2271                         memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
2272                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
2273                         send_blink_cursor(pte);
2274                         send_cursor_pos(pte,
2275                                                   (unsigned char) (TEXT_LINE2 + 0x09 +
2276                                                                                    pte->device->size_phone_number));
2277                         send_led_update(pte, 0);
2278                         return;
2279                 }
2280         } else {
2281                 if ((pte->device->output == OUTPUT_HANDSET) &&
2282                         (pte->device->receiver_state == STATE_ONHOOK))
2283                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2284                 else
2285                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2286                 SendDialTone(pte);
2287                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
2288                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
2289                 send_text_status(pte, "Call   Redial BackSpcErase");
2290         }
2291         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2292         send_blink_cursor(pte);
2293         send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2294         pte->device->size_phone_number = 0;
2295         pte->device->phone_number[0] = 0;
2296         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
2297         Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
2298         pte->device->missed_call = 0;
2299         send_led_update(pte, 0);
2300         return;
2301 }
2302
2303 /* Step 1 : Music On Hold for peer, Dialing screen for us */
2304 static void TransferCallStep1(struct unistimsession *pte)
2305 {
2306         struct unistim_subchannel *sub;
2307         struct unistim_line *p = pte->device->lines;
2308
2309         sub = p->subs[SUB_REAL];
2310
2311         if (!sub->owner) {
2312                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2313                 return;
2314         }
2315         if (p->subs[SUB_THREEWAY]) {
2316                 if (unistimdebug)
2317                         ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
2318                 if (p->subs[SUB_THREEWAY]->owner)
2319                         ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
2320                 else
2321                         ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
2322                 return;
2323         }
2324         /* Start music on hold if appropriate */
2325         if (pte->device->moh)
2326                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
2327         else {
2328                 if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
2329                         ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
2330                                                   pte->device->lines->musicclass, NULL);
2331                         pte->device->moh = 1;
2332                 } else {
2333                         ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
2334                         return;
2335                 }
2336         }
2337         /* Silence our channel */
2338         if (!pte->device->silence_generator) {
2339                 pte->device->silence_generator =
2340                         ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
2341                 if (pte->device->silence_generator == NULL)
2342                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2343                 else if (unistimdebug)
2344                         ast_verb(0, "Starting silence generator\n");
2345         }
2346         handle_dial_page(pte);
2347 }
2348
2349 /* From phone to PBX */
2350 static void HandleCallOutgoing(struct unistimsession *s)
2351 {
2352         struct ast_channel *c;
2353         struct unistim_subchannel *sub;
2354         pthread_t t;
2355         s->state = STATE_CALL;
2356         sub = s->device->lines->subs[SUB_REAL];
2357         if (!sub) {
2358                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2359                 return;
2360         }
2361         if (!sub->owner) {                    /* A call is already in progress ? */
2362                 c = unistim_new(sub, AST_STATE_DOWN);   /* No, starting a new one */
2363                 if (c) {
2364                         /* Need to start RTP before calling ast_pbx_run */
2365                         if (!sub->rtp)
2366                                 start_rtp(sub);
2367                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2368                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
2369                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2370                         send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2371                         send_text_status(s, "Hangup");
2372                         /* start switch */
2373                         if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
2374                                 display_last_error("Unable to create switch thread");
2375                                 ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
2376                         }
2377                 } else
2378                         ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
2379                                         sub->parent->name, s->device->name);
2380         } else {                                        /* We already have a call, so we switch in a threeway call */
2381
2382                 if (s->device->moh) {
2383                         struct unistim_subchannel *subchannel;
2384                         struct unistim_line *p = s->device->lines;
2385                         subchannel = p->subs[SUB_REAL];
2386
2387                         if (!subchannel->owner) {
2388                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2389                                 return;
2390                         }
2391                         if (p->subs[SUB_THREEWAY]) {
2392                                 ast_log(LOG_WARNING,
2393                                                 "Can't transfer while an another transfer is taking place\n");
2394                                 return;
2395                         }
2396                         if (!alloc_sub(p, SUB_THREEWAY)) {
2397                                 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
2398                                 return;
2399                         }
2400                         /* Stop the silence generator */
2401                         if (s->device->silence_generator) {
2402                                 if (unistimdebug)
2403                                         ast_verb(0, "Stopping silence generator\n");
2404                                 ast_channel_stop_silence_generator(subchannel->owner,
2405                                                                                                    s->device->silence_generator);
2406                                 s->device->silence_generator = NULL;
2407                         }
2408                         send_tone(s, 0, 0);
2409                         /* Make new channel */
2410                         c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN);
2411                         if (!c) {
2412                                 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
2413                                 return;
2414                         }
2415                         /* Swap things around between the three-way and real call */
2416                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
2417                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2418                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
2419                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2420                         send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2421                         send_text_status(s, "TransfrCancel");
2422
2423                         if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
2424                                 ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
2425                                 ast_hangup(c);
2426                                 return;
2427                         }
2428                         if (unistimdebug)
2429                                 ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n",
2430                                          p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name,
2431                                          p->subs[SUB_THREEWAY]->subtype);
2432                 } else
2433                         ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
2434         }
2435         return;
2436 }
2437
2438 /* From PBX to phone */
2439 static void HandleCallIncoming(struct unistimsession *s)
2440 {
2441         struct unistim_subchannel *sub;
2442         s->state = STATE_CALL;
2443         s->device->missed_call = 0;
2444         send_no_ring(s);
2445         sub = s->device->lines->subs[SUB_REAL];
2446         if (!sub) {
2447                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2448                 return;
2449         } else if (unistimdebug)
2450                 ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
2451                                         s->device->name);
2452         start_rtp(sub);
2453         if (!sub->rtp)
2454                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
2455                                 s->device->name);
2456         ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
2457         send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
2458         send_text_status(s, "Hangup Transf");
2459         send_start_timer(s);
2460
2461         if ((s->device->output == OUTPUT_HANDSET) &&
2462                 (s->device->receiver_state == STATE_ONHOOK))
2463                 send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
2464         else
2465                 send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2466         s->device->start_call_timestamp = time(0);
2467         write_history(s, 'i', 0);
2468         return;
2469 }
2470
2471 static int unistim_do_senddigit(struct unistimsession *pte, char digit)
2472 {
2473
2474         struct ast_frame f = { 0, };
2475         struct unistim_subchannel *sub;
2476         sub = pte->device->lines->subs[SUB_REAL];
2477         if (!sub->owner) {
2478                 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
2479                 return -1;
2480         }
2481         if (unistimdebug)
2482                 ast_verb(0, "Send Digit %c\n", digit);
2483         switch (digit) {
2484         case '0':
2485                 send_tone(pte, 941, 1336);
2486                 break;
2487         case '1':
2488                 send_tone(pte, 697, 1209);
2489                 break;
2490         case '2':
2491                 send_tone(pte, 697, 1336);
2492                 break;
2493         case '3':
2494                 send_tone(pte, 697, 1477);
2495                 break;
2496         case '4':
2497                 send_tone(pte, 770, 1209);
2498                 break;
2499         case '5':
2500                 send_tone(pte, 770, 1336);
2501                 break;
2502         case '6':
2503                 send_tone(pte, 770, 1477);
2504                 break;
2505         case '7':
2506                 send_tone(pte, 852, 1209);
2507                 break;
2508         case '8':
2509                 send_tone(pte, 852, 1336);
2510                 break;
2511         case '9':
2512                 send_tone(pte, 852, 1477);
2513                 break;
2514         case 'A':
2515                 send_tone(pte, 697, 1633);
2516                 break;
2517         case 'B':
2518                 send_tone(pte, 770, 1633);
2519                 break;
2520         case 'C':
2521                 send_tone(pte, 852, 1633);
2522                 break;
2523         case 'D':
2524                 send_tone(pte, 941, 1633);
2525                 break;
2526         case '*':
2527                 send_tone(pte, 941, 1209);
2528                 break;
2529         case '#':
2530                 send_tone(pte, 941, 1477);
2531                 break;
2532         default:
2533                 send_tone(pte, 500, 2000);
2534         }
2535         usleep(150000);                  /* XXX Less than perfect, blocking an important thread is not a good idea */
2536         send_tone(pte, 0, 0);
2537         f.frametype = AST_FRAME_DTMF;
2538         f.subclass = digit;
2539         f.src = "unistim";
2540         ast_queue_frame(sub->owner, &f);
2541         return 0;
2542 }
2543
2544 static void key_call(struct unistimsession *pte, char keycode)
2545 {
2546         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2547                 if (keycode == KEY_SHARP)
2548                         keycode = '#';
2549                 else if (keycode == KEY_STAR)
2550                         keycode = '*';
2551                 else
2552                         keycode -= 0x10;
2553                 unistim_do_senddigit(pte, keycode);
2554                 return;
2555         }
2556         switch (keycode) {
2557         case KEY_HANGUP:
2558         case KEY_FUNC1:
2559                 close_call(pte);
2560                 break;
2561         case KEY_FUNC2:
2562                 TransferCallStep1(pte);
2563                 break;
2564         case KEY_HEADPHN:
2565                 if (pte->device->output == OUTPUT_HEADPHONE)
2566                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2567                 else
2568                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2569                 break;
2570         case KEY_LOUDSPK:
2571                 if (pte->device->output != OUTPUT_SPEAKER)
2572                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2573                 else
2574                         send_select_output(pte, pte->device->previous_output, pte->device->volume,
2575                                                          MUTE_OFF);
2576                 break;
2577         case KEY_MUTE:
2578                 if (!pte->device->moh) {
2579                         if (pte->device->mute == MUTE_ON)
2580                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2581                         else
2582                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2583                         break;
2584                 }
2585         case KEY_ONHOLD:
2586                 {
2587                         struct unistim_subchannel *sub;
2588                         struct ast_channel *bridgepeer = NULL;
2589                         sub = pte->device->lines->subs[SUB_REAL];
2590                         if (!sub->owner) {
2591                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2592                                 return;
2593                         }
2594                         if ((bridgepeer = ast_bridged_channel(sub->owner))) {
2595                                 if (pte->device->moh) {
2596                                         ast_moh_stop(bridgepeer);
2597                                         pte->device->moh = 0;
2598                                         send_select_output(pte, pte->device->output, pte->device->volume,
2599                                                                          MUTE_OFF);
2600                                 } else {
2601                                         ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
2602                                         pte->device->moh = 1;
2603                                         send_select_output(pte, pte->device->output, pte->device->volume,
2604                                                                          MUTE_ON);
2605                                 }
2606                         } else
2607                                 ast_log(LOG_WARNING,
2608                                                 "Unable to find peer subchannel for music on hold\n");
2609                         break;
2610                 }
2611         }
2612         return;
2613 }
2614
2615 static void key_ringing(struct unistimsession *pte, char keycode)
2616 {
2617         if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
2618                 HandleCallIncoming(pte);
2619                 return;
2620         }
2621         switch (keycode) {
2622         case KEY_HANGUP:
2623         case KEY_FUNC4:
2624                 IgnoreCall(pte);
2625                 break;
2626         case KEY_FUNC1:
2627                 HandleCallIncoming(pte);
2628                 break;
2629         }
2630         return;
2631 }
2632
2633 static void Keyfavorite(struct unistimsession *pte, char keycode)
2634 {
2635         int fav;
2636
2637         if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
2638                 ast_log(LOG_WARNING, "It's not a favorite key\n");
2639                 return;
2640         }
2641         if (keycode == KEY_FAV0)
2642                 return;
2643         fav = keycode - KEY_FAV0;
2644         if (pte->device->softkeyicon[fav] == 0)
2645                 return;
2646         ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
2647                                         sizeof(pte->device->phone_number));
2648         HandleCallOutgoing(pte);
2649         return;
2650 }
2651
2652 static void key_dial_page(struct unistimsession *pte, char keycode)
2653 {
2654         if (keycode == KEY_FUNC3) {
2655                 if (pte->device->size_phone_number <= 1)
2656                         keycode = KEY_FUNC4;
2657                 else {
2658                         pte->device->size_phone_number -= 2;
2659                         keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
2660                 }
2661         }
2662         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2663                 char tmpbuf[] = "Number : ...............";
2664                 int i = 0;
2665
2666                 if (pte->device->size_phone_number >= 15)
2667                         return;
2668                 if (pte->device->size_phone_number == 0)
2669                         send_tone(pte, 0, 0);
2670                 while (i < pte->device->size_phone_number) {
2671                         tmpbuf[i + 9] = pte->device->phone_number[i];
2672                         i++;
2673                 }
2674                 if (keycode == KEY_SHARP)
2675                         keycode = '#';
2676                 else if (keycode == KEY_STAR)
2677                         keycode = '*';
2678                 else
2679                         keycode -= 0x10;
2680                 tmpbuf[i + 9] = keycode;
2681                 pte->device->phone_number[i] = keycode;
2682                 pte->device->size_phone_number++;
2683                 pte->device->phone_number[i + 1] = 0;
2684                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2685                 send_blink_cursor(pte);
2686                 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
2687                 return;
2688         }
2689         if (keycode == KEY_FUNC4) {
2690
2691                 pte->device->size_phone_number = 0;
2692                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2693                 send_blink_cursor(pte);
2694                 send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2695                 return;
2696         }
2697
2698         if (pte->device->call_forward[0] == -1) {
2699                 if (keycode == KEY_FUNC1) {
2700                         ast_copy_string(pte->device->call_forward, pte->device->phone_number,
2701                                                         sizeof(pte->device->call_forward));
2702                         show_main_page(pte);
2703                 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
2704                         pte->device->call_forward[0] = '\0';
2705                         show_main_page(pte);
2706                 }
2707                 return;
2708         }
2709         switch (keycode) {
2710         case KEY_FUNC2:
2711                 if (ast_strlen_zero(pte->device->redial_number))
2712                         break;
2713                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
2714                                                 sizeof(pte->device->phone_number));
2715         case KEY_FUNC1:
2716                 HandleCallOutgoing(pte);
2717                 break;
2718         case KEY_HANGUP:
2719                 if (pte->device->lines->subs[SUB_REAL]->owner) {
2720                         /* Stop the silence generator */
2721                         if (pte->device->silence_generator) {
2722                                 if (unistimdebug)
2723                                         ast_verb(0, "Stopping silence generator\n");
2724                                 ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
2725                                                                                                    owner, pte->device->silence_generator);
2726                                 pte->device->silence_generator = NULL;
2727                         }
2728                         send_tone(pte, 0, 0);
2729                         ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
2730                         pte->device->moh = 0;
2731                         pte->state = STATE_CALL;
2732                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
2733                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
2734                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
2735                         send_text_status(pte, "Hangup Transf");
2736                 } else
2737                         show_main_page(pte);
2738                 break;
2739         case KEY_FAV1:
2740         case KEY_FAV2:
2741         case KEY_FAV3:
2742         case KEY_FAV4:
2743         case KEY_FAV5:
2744                 Keyfavorite(pte, keycode);
2745                 break;
2746         case KEY_LOUDSPK:
2747                 if (pte->device->output == OUTPUT_SPEAKER) {
2748                         if (pte->device->receiver_state == STATE_OFFHOOK)
2749                                 send_select_output(pte, pte->device->previous_output, pte->device->volume,
2750                                                                  MUTE_OFF);
2751                         else
2752                                 show_main_page(pte);
2753                 } else
2754                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2755                 break;
2756         case KEY_HEADPHN:
2757                 if (pte->device->output == OUTPUT_HEADPHONE) {
2758                         if (pte->device->receiver_state == STATE_OFFHOOK)
2759                                 send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2760                         else
2761                                 show_main_page(pte);
2762                 } else
2763                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2764                 break;
2765         }
2766         return;
2767 }
2768
2769 #define SELECTCODEC_START_ENTRY_POS 15
2770 #define SELECTCODEC_MAX_LENGTH 2
2771 #define SELECTCODEC_MSG "Codec number : .."
2772 static void HandleSelectCodec(struct unistimsession *pte)
2773 {
2774         char buf[30], buf2[5];
2775
2776         pte->state = STATE_SELECTCODEC;
2777         strcpy(buf, "Using codec ");
2778         sprintf(buf2, "%d", pte->device->codec_number);
2779         strcat(buf, buf2);
2780         strcat(buf, " (G711u=0,");
2781
2782         send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
2783         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
2784         send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2785         send_blink_cursor(pte);
2786         send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2787         pte->size_buff_entry = 0;
2788         send_text_status(pte, "Select BackSpcErase  Cancel");
2789         return;
2790 }
2791
2792 static void key_select_codec(struct unistimsession *pte, char keycode)
2793 {
2794         if (keycode == KEY_FUNC2) {
2795                 if (pte->size_buff_entry <= 1)
2796                         keycode = KEY_FUNC3;
2797                 else {
2798                         pte->size_buff_entry -= 2;
2799                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2800                 }
2801         }
2802         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2803                 char tmpbuf[] = SELECTCODEC_MSG;
2804                 int i = 0;
2805
2806                 if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
2807                         return;
2808
2809                 while (i < pte->size_buff_entry) {
2810                         tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
2811                         i++;
2812                 }
2813                 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
2814                 pte->buff_entry[i] = keycode - 0x10;
2815                 pte->size_buff_entry++;
2816                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
2817                 send_blink_cursor(pte);
2818                 send_cursor_pos(pte,
2819                                           (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
2820                 return;
2821         }
2822
2823         switch (keycode) {
2824         case KEY_FUNC1:
2825                 if (pte->size_buff_entry == 1)
2826                         pte->device->codec_number = pte->buff_entry[0] - 48;
2827                 else if (pte->size_buff_entry == 2)
2828                         pte->device->codec_number =
2829                                 ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
2830                 show_main_page(pte);
2831                 break;
2832         case KEY_FUNC3:
2833                 pte->size_buff_entry = 0;
2834                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2835                 send_blink_cursor(pte);
2836                 send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2837                 break;
2838         case KEY_HANGUP:
2839         case KEY_FUNC4:
2840                 show_main_page(pte);
2841                 break;
2842         }
2843         return;
2844 }
2845
2846 #define SELECTEXTENSION_START_ENTRY_POS 0
2847 #define SELECTEXTENSION_MAX_LENGTH 10
2848 #define SELECTEXTENSION_MSG ".........."
2849 static void ShowExtensionPage(struct unistimsession *pte)
2850 {
2851         pte->state = STATE_EXTENSION;
2852
2853         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
2854         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
2855         send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
2856         send_blink_cursor(pte);
2857         send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
2858         send_text_status(pte, "Enter  BackSpcErase");
2859         pte->size_buff_entry = 0;
2860         return;
2861 }
2862
2863 static void key_select_extension(struct unistimsession *pte, char keycode)
2864 {
2865         if (keycode == KEY_FUNC2) {
2866                 if (pte->size_buff_entry <= 1)
2867                         keycode = KEY_FUNC3;
2868                 else {
2869                         pte->size_buff_entry -= 2;
2870                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2871                 }
2872         }
2873         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2874                 char tmpbuf[] = SELECTEXTENSION_MSG;
2875                 int i = 0;
2876
2877                 if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
2878                         return;
2879
2880                 while (i < pte->size_buff_entry) {
2881                         tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
2882                         i++;
2883                 }
2884                 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
2885                 pte->buff_entry[i] = keycode - 0x10;
2886                 pte->size_buff_entry++;
2887                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2888                 send_blink_cursor(pte);
2889                 send_cursor_pos(pte,
2890                                           (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
2891                                                                            i));
2892                 return;
2893         }
2894
2895         switch (keycode) {
2896         case KEY_FUNC1:
2897                 if (pte->size_buff_entry < 1)
2898                         return;
2899                 if (autoprovisioning == AUTOPROVISIONING_TN) {
2900                         struct unistim_device *d;
2901
2902                         /* First step : looking for this TN in our device list */
2903                         ast_mutex_lock(&devicelock);
2904                         d = devices;
2905                         pte->buff_entry[pte->size_buff_entry] = '\0';
2906                         while (d) {
2907                                 if (d->id[0] == 'T') {  /* It's a TN device ? */
2908                                         /* It's the TN we're looking for ? */
2909                                         if (!strcmp((d->id) + 1, pte->buff_entry)) {
2910                                                 pte->device = d;
2911                                                 d->session = pte;
2912                                                 d->codec_number = DEFAULT_CODEC;
2913                                                 d->pos_fav = 0;
2914                                                 d->missed_call = 0;
2915                                                 d->receiver_state = STATE_ONHOOK;
2916                                                 strcpy(d->id, pte->macaddr);
2917                                                 pte->device->extension_number[0] = 'T';
2918                                                 pte->device->extension = EXTENSION_TN;
2919                                                 ast_copy_string((pte->device->extension_number) + 1,
2920                                                                                 pte->buff_entry, pte->size_buff_entry + 1);
2921                                                 ast_mutex_unlock(&devicelock);
2922                                                 show_main_page(pte);
2923                                                 refresh_all_favorite(pte);
2924                                                 return;
2925                                         }
2926                                 }
2927                                 d = d->next;
2928                         }
2929                         ast_mutex_unlock(&devicelock);
2930                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number.");
2931                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
2932                         send_cursor_pos(pte,
2933                                                   (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
2934                                                                                    pte->size_buff_entry));
2935                         send_blink_cursor(pte);
2936                 } else {
2937                         ast_copy_string(pte->device->extension_number, pte->buff_entry,
2938                                                         pte->size_buff_entry + 1);
2939                         if (RegisterExtension(pte)) {
2940                                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension.");
2941                                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
2942                                 send_cursor_pos(pte,
2943                                                           (unsigned char) (TEXT_LINE2 +
2944                                                                                            SELECTEXTENSION_START_ENTRY_POS +
2945                                                                                            pte->size_buff_entry));
2946                                 send_blink_cursor(pte);
2947                         } else
2948                                 show_main_page(pte);
2949                 }
2950                 break;
2951         case KEY_FUNC3:
2952                 pte->size_buff_entry = 0;
2953                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
2954                 send_blink_cursor(pte);
2955                 send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
2956                 break;
2957         }
2958         return;
2959 }
2960
2961 static int ReformatNumber(char *number)
2962 {
2963         int pos = 0, i = 0, size = strlen(number);
2964
2965         for (; i < size; i++) {
2966                 if ((number[i] >= '0') && (number[i] <= '9')) {
2967                         if (i == pos) {
2968                                 pos++;
2969                                 continue;
2970                         }
2971                         number[pos] = number[i];
2972                         pos++;
2973                 }
2974         }
2975         number[pos] = 0;
2976         return pos;
2977 }
2978
2979 static void show_entry_history(struct unistimsession *pte, FILE ** f)
2980 {
2981         char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
2982                 func3[10];
2983
2984         if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
2985                 display_last_error("Can't read history date entry");
2986                 fclose(*f);
2987                 return;
2988         }
2989         line[sizeof(line) - 1] = '\0';
2990         send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
2991         if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
2992                 display_last_error("Can't read callerid entry");
2993                 fclose(*f);
2994                 return;
2995         }
2996         line[sizeof(line) - 1] = '\0';
2997         ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
2998         send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
2999         if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
3000                 display_last_error("Can't read callername entry");
3001                 fclose(*f);
3002                 return;
3003         }
3004         line[sizeof(line) - 1] = '\0';
3005         send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
3006         fclose(*f);
3007
3008         snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2],
3009                          pte->buff_entry[1]);
3010         send_texttitle(pte, line);
3011
3012         if (pte->buff_entry[2] == 1)
3013                 strcpy(func1, "       ");
3014         else
3015                 strcpy(func1, "Prvious");
3016         if (pte->buff_entry[2] >= pte->buff_entry[1])
3017                 strcpy(func2, "       ");
3018         else
3019                 strcpy(func2, "Next   ");
3020         if (ReformatNumber(pte->device->lst_cid))
3021                 strcpy(func3, "Redial ");
3022         else
3023                 strcpy(func3, "       ");
3024         snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3);
3025         send_text_status(pte, status);
3026 }
3027
3028 static char OpenHistory(struct unistimsession *pte, char way, FILE ** f)
3029 {
3030         char tmp[AST_CONFIG_MAX_PATH];
3031         char count;
3032
3033         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
3034                          USTM_LOG_DIR, pte->device->name, way);
3035         *f = fopen(tmp, "r");
3036         if (!*f) {
3037                 display_last_error("Unable to open history file");
3038                 return 0;
3039         }
3040         if (fread(&count, 1, 1, *f) != 1) {
3041                 display_last_error("Unable to read history header - display.");
3042                 fclose(*f);
3043                 return 0;
3044         }
3045         if (count > MAX_ENTRY_LOG) {
3046                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
3047                                 count, MAX_ENTRY_LOG);
3048                 fclose(*f);
3049                 return 0;
3050         }
3051         return count;
3052 }
3053
3054 static void show_history(struct unistimsession *pte, char way)
3055 {
3056         FILE *f;
3057         char count;
3058
3059         if (!pte->device)
3060                 return;
3061         if (!pte->device->callhistory)
3062                 return;
3063         count = OpenHistory(pte, way, &f);
3064         if (!count)
3065                 return;
3066         pte->buff_entry[0] = way;
3067         pte->buff_entry[1] = count;
3068         pte->buff_entry[2] = 1;
3069         show_entry_history(pte, &f);
3070         pte->state = STATE_HISTORY;
3071 }
3072
3073 static void show_main_page(struct unistimsession *pte)
3074 {
3075         char tmpbuf[TEXT_LENGTH_MAX + 1];
3076
3077
3078         if ((pte->device->extension == EXTENSION_ASK) &&
3079                 (ast_strlen_zero(pte->device->extension_number))) {
3080                 ShowExtensionPage(pte);
3081                 return;
3082         }
3083
3084         pte->state = STATE_MAINPAGE;
3085
3086         send_tone(pte, 0, 0);
3087         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET);
3088         pte->device->lines->lastmsgssent = 0;
3089         send_favorite(pte->device->softkeylinepos, FAV_ICON_ONHOOK_BLACK, pte,
3090                                  pte->device->softkeylabel[pte->device->softkeylinepos]);
3091         if (!ast_strlen_zero(pte->device->call_forward)) {
3092                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Call forwarded to :");
3093                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward);
3094                 Sendicon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte);
3095                 send_text_status(pte, "Dial   Redial NoForwd");
3096         } else {
3097                 if ((pte->device->extension == EXTENSION_ASK) ||
3098                         (pte->device->extension == EXTENSION_TN))
3099                         send_text_status(pte, "Dial   Redial ForwardUnregis");
3100                 else
3101                         send_text_status(pte, "Dial   Redial Forward");
3102
3103                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1);
3104                 if (pte->device->missed_call == 0)
3105                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0);
3106                 else {
3107                         sprintf(tmpbuf, "%d unanswered call(s)", pte->device->missed_call);
3108                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
3109                         Sendicon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte);
3110                 }
3111         }
3112         if (ast_strlen_zero(pte->device->maintext2)) {
3113                 strcpy(tmpbuf, "IP : ");
3114                 strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
3115                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
3116         } else
3117                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2);
3118         send_texttitle(pte, pte->device->titledefault);
3119         change_favorite_icon(pte, FAV_ICON_ONHOOK_BLACK);
3120 }
3121
3122 static void key_main_page(struct unistimsession *pte, char keycode)
3123 {
3124         if (pte->device->missed_call) {
3125                 Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
3126                 pte->device->missed_call = 0;
3127         }
3128         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3129                 handle_dial_page(pte);
3130                 key_dial_page(pte, keycode);
3131                 return;
3132         }
3133         switch (keycode) {
3134         case KEY_FUNC1:
3135                 handle_dial_page(pte);
3136                 break;
3137         case KEY_FUNC2:
3138                 if (ast_strlen_zero(pte->device->redial_number))
3139                         break;
3140                 if ((pte->device->output == OUTPUT_HANDSET) &&
3141                         (pte->device->receiver_state == STATE_ONHOOK))
3142                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3143                 else
3144                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3145
3146                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
3147                                                 sizeof(pte->device->phone_number));
3148                 HandleCallOutgoing(pte);
3149                 break;
3150         case KEY_FUNC3:
3151                 if (!ast_strlen_zero(pte->device->call_forward)) {
3152                         /* Cancel call forwarding */
3153                         memmove(pte->device->call_forward + 1, pte->device->call_forward,
3154                                         sizeof(pte->device->call_forward));
3155                         pte->device->call_forward[0] = '\0';
3156                         Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
3157                         pte->device->output = OUTPUT_HANDSET;   /* Seems to be reseted somewhere */
3158                         show_main_page(pte);
3159                         break;
3160                 }
3161                 pte->device->call_forward[0] = -1;
3162                 handle_dial_page(pte);
3163                 break;
3164         case KEY_FUNC4:
3165                 if (pte->device->extension == EXTENSION_ASK) {
3166                         UnregisterExtension(pte);
3167                         pte->device->extension_number[0] = '\0';
3168                         ShowExtensionPage(pte);
3169                 } else if (pte->device->extension == EXTENSION_TN) {
3170                         ast_mutex_lock(&devicelock);
3171                         strcpy(pte->device->id, pte->device->extension_number);
3172                         pte->buff_entry[0] = '\0';
3173                         pte->size_buff_entry = 0;
3174                         pte->device->session = NULL;
3175                         pte->device = NULL;
3176                         ast_mutex_unlock(&devicelock);
3177                         ShowExtensionPage(pte);
3178                 }
3179                 break;
3180         case KEY_FAV0:
3181                 handle_dial_page(pte);
3182                 break;
3183         case KEY_FAV1:
3184         case KEY_FAV2:
3185         case KEY_FAV3:
3186         case KEY_FAV4:
3187         case KEY_FAV5:
3188                 if ((pte->device->output == OUTPUT_HANDSET) &&
3189                         (pte->device->receiver_state == STATE_ONHOOK))
3190                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3191                 else
3192                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3193                 Keyfavorite(pte, keycode);
3194                 break;
3195         case KEY_CONF:
3196                 HandleSelectCodec(pte);
3197                 break;
3198         case KEY_LOUDSPK:
3199                 send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3200                 handle_dial_page(pte);
3201                 break;
3202         case KEY_HEADPHN:
3203                 send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
3204                 handle_dial_page(pte);
3205                 break;
3206         case KEY_SNDHIST:
3207                 show_history(pte, 'o');
3208                 break;
3209         case KEY_RCVHIST:
3210                 show_history(pte, 'i');
3211                 break;
3212         }
3213         return;
3214 }
3215
3216 static void key_history(struct unistimsession *pte, char keycode)
3217 {
3218         FILE *f;
3219         char count;
3220         long offset;
3221
3222         switch (keycode) {
3223         case KEY_UP:
3224         case KEY_LEFT:
3225         case KEY_FUNC1:
3226                 if (pte->buff_entry[2] <= 1)
3227                         return;
3228                 pte->buff_entry[2]--;
3229                 count = OpenHistory(pte, pte->buff_entry[0], &f);
3230                 if (!count)
3231                         return;
3232                 offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
3233                 if (fseek(f, offset, SEEK_CUR)) {
3234                         display_last_error("Unable to seek history entry.");
3235                         fclose(f);
3236                         return;
3237                 }
3238                 show_entry_history(pte, &f);
3239                 break;
3240         case KEY_DOWN:
3241         case KEY_RIGHT:
3242         case KEY_FUNC2:
3243                 if (pte->buff_entry[2] >= pte->buff_entry[1])
3244                         return;
3245                 pte->buff_entry[2]++;
3246                 count = OpenHistory(pte, pte->buff_entry[0], &f);
3247                 if (!count)
3248                         return;
3249                 offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
3250                 if (fseek(f, offset, SEEK_CUR)) {
3251                         display_last_error("Unable to seek history entry.");
3252                         fclose(f);
3253                         return;
3254                 }
3255                 show_entry_history(pte, &f);
3256                 break;
3257         case KEY_FUNC3:
3258                 if (!ReformatNumber(pte->device->lst_cid))
3259                         break;
3260                 ast_copy_string(pte->device->redial_number, pte->device->lst_cid,
3261                                                 sizeof(pte->device->redial_number));
3262                 key_main_page(pte, KEY_FUNC2);
3263                 break;
3264         case KEY_FUNC4:
3265         case KEY_HANGUP:
3266                 show_main_page(pte);
3267                 break;
3268         case KEY_SNDHIST:
3269                 if (pte->buff_entry[0] == 'i')
3270                         show_history(pte, 'o');
3271                 else
3272                         show_main_page(pte);
3273                 break;
3274         case KEY_RCVHIST:
3275                 if (pte->buff_entry[0] == 'i')
3276                         show_main_page(pte);
3277                 else
3278                         show_history(pte, 'i');
3279                 break;
3280         }
3281         return;
3282 }
3283
3284 static void init_phone_step2(struct unistimsession *pte)
3285 {
3286         BUFFSEND;
3287         if (unistimdebug)
3288                 ast_verb(0, "Sending S4\n");
3289         memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
3290         send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
3291         send_date_time2(pte);
3292         send_date_time3(pte);
3293         if (unistimdebug)
3294                 ast_verb(0, "Sending S7\n");
3295         memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
3296         send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
3297         if (unistimdebug)
3298                 ast_verb(0, "Sending Contrast\n");
3299         memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
3300         if (pte->device != NULL)
3301                 buffsend[9] = pte->device->contrast;
3302         send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
3303
3304         if (unistimdebug)
3305                 ast_verb(0, "Sending S9\n");
3306         memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
3307         send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
3308         send_no_ring(pte);
3309
3310         if (unistimdebug)
3311                 ast_verb(0, "Sending S7\n");
3312         memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
3313         send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
3314         send_led_update(pte, 0);
3315         send_ping(pte);
3316         if (pte->state < STATE_MAINPAGE) {
3317                 if (autoprovisioning == AUTOPROVISIONING_TN) {
3318                         ShowExtensionPage(pte);
3319                         return;
3320                 } else {
3321                         int i;
3322                         char tmp[30];
3323
3324                         for (i = 1; i < 6; i++)
3325                                 send_favorite(i, 0, pte, "");
3326                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Sorry, this phone is not");
3327                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "registred in unistim.cfg");
3328                         strcpy(tmp, "MAC = ");
3329                         strcat(tmp, pte->macaddr);
3330                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
3331                         send_text_status(pte, "");
3332                         send_texttitle(pte, "UNISTIM for*");
3333                         return;
3334                 }
3335         }
3336         show_main_page(pte);
3337         refresh_all_favorite(pte);
3338         if (unistimdebug)
3339                 ast_verb(0, "Sending arrow\n");
3340         memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
3341         send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
3342         return;
3343 }
3344
3345 static void process_request(int size, unsigned char *buf, struct unistimsession *pte)
3346 {
3347         char tmpbuf[255];
3348         if (memcmp
3349                 (buf + SIZE_HEADER, packet_recv_resume_connection_with_server,
3350                  sizeof(packet_recv_resume_connection_with_server)) == 0) {
3351                 rcv_resume_connection_with_server(pte);
3352                 return;
3353         }
3354         if (memcmp(buf + SIZE_HEADER, packet_recv_firm_version, sizeof(packet_recv_firm_version)) ==
3355                 0) {
3356                 buf[size] = 0;
3357                 if (unistimdebug)
3358                         ast_verb(0, "Got the firmware version : '%s'\n", buf + 13);
3359                 init_phone_step2(pte);
3360                 return;
3361         }
3362         if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
3363                 rcv_mac_addr(pte, buf);
3364                 return;
3365         }
3366         if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
3367                 if (unistimdebug)
3368                         ast_verb(0, "R2 received\n");
3369                 return;
3370         }
3371
3372         if (pte->state < STATE_MAINPAGE) {
3373                 if (unistimdebug)
3374                         ast_verb(0, "Request not authorized in this state\n");
3375                 return;
3376         }
3377         if (!memcmp(buf + SIZE_HEADER, packet_recv_pressed_key, sizeof(packet_recv_pressed_key))) {
3378                 char keycode = buf[13];
3379
3380                 if (unistimdebug)
3381                         ast_verb(0, "Key pressed : keycode = 0x%.2x - current state : %d\n", keycode,
3382                                                 pte->state);
3383
3384                 switch (pte->state) {
3385                 case STATE_INIT:
3386                         if (unistimdebug)
3387                                 ast_verb(0, "No keys allowed in the init state\n");
3388                         break;
3389                 case STATE_AUTHDENY:
3390                         if (unistimdebug)
3391                                 ast_verb(0, "No keys allowed in authdeny state\n");
3392                         break;
3393                 case STATE_MAINPAGE:
3394                         key_main_page(pte, keycode);
3395                         break;
3396                 case STATE_DIALPAGE:
3397                         key_dial_page(pte, keycode);
3398                         break;
3399                 case STATE_RINGING:
3400                         key_ringing(pte, keycode);
3401                         break;
3402                 case STATE_CALL:
3403                         key_call(pte, keycode);
3404                         break;
3405                 case STATE_EXTENSION:
3406                         key_select_extension(pte, keycode);
3407                         break;
3408                 case STATE_SELECTCODEC:
3409                         key_select_codec(pte, keycode);
3410                         break;
3411                 case STATE_HISTORY:
3412                         key_history(pte, keycode);
3413                         break;
3414                 default:
3415                         ast_log(LOG_WARNING, "Key : Unknown state\n");
3416                 }
3417                 return;
3418         }
3419         if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
3420                 if (unistimdebug)
3421                         ast_verb(0, "Handset off hook\n");
3422                 if (!pte->device)              /* We are not yet registred (asking for a TN in AUTOPROVISIONING_TN) */
3423                         return;
3424                 pte->device->receiver_state = STATE_OFFHOOK;
3425                 if (pte->device->output == OUTPUT_HEADPHONE)
3426                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
3427                 else
3428                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
3429                 if (pte->state == STATE_RINGING)
3430                         HandleCallIncoming(pte);
3431                 else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL))
3432                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
3433                 else if (pte->state == STATE_EXTENSION) /* We must have a TN before calling */
3434                         return;
3435                 else {
3436                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
3437                         handle_dial_page(pte);