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