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