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