723500e4539e299c154a0c5be8cf67a9f0143ff5
[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                 char iabuf[INET_ADDRSTRLEN];
895                 char iabuf2[INET_ADDRSTRLEN];
896                 ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
897                                         ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
898                                         ast_inet_ntoa(addr_to->sin_addr));
899                 for (tmp = 0; tmp < size; tmp++)
900                         ast_verb(0, "%.2x ", (unsigned char) data[tmp]);
901                 ast_verb(0, "\n******************************************\n");
902
903         }
904 #endif
905
906         if (sendmsg(unistimsock, &msg, 0) == -1) {
907                 display_last_error("Error sending datas");
908         }
909 #else
910         if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
911                 == -1)
912                 display_last_error("Error sending datas");
913 #endif
914 }
915
916 static void send_client(int size, const unsigned char *data, struct unistimsession *pte)
917 {
918         unsigned int tick;
919         int buf_pos;
920         unsigned short seq = ntohs(++pte->seq_server);
921
922         ast_mutex_lock(&pte->lock);
923         buf_pos = pte->last_buf_available;
924
925         if (buf_pos >= MAX_BUF_NUMBER) {
926                 ast_log(LOG_WARNING, "Error : send queue overflow\n");
927                 ast_mutex_unlock(&pte->lock);
928                 return;
929         }
930         memcpy((void *)data + sizeof(unsigned short), (void *)&seq, sizeof(unsigned short));
931         pte->wsabufsend[buf_pos].len = size;
932         memcpy(pte->wsabufsend[buf_pos].buf, data, size);
933
934         tick = get_tick_count();
935         pte->timeout = tick + RETRANSMIT_TIMER;
936
937 /*#ifdef DUMP_PACKET */
938         if (unistimdebug) {
939                 ast_verb(6, "Sending datas with seq #0x%.4x Using slot #%d :\n", pte->seq_server, buf_pos);
940         }
941 /*#endif */
942         send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
943                                   &(pte->sout));
944         pte->last_buf_available++;
945         ast_mutex_unlock(&pte->lock);
946 }
947
948 static void send_ping(struct unistimsession *pte)
949 {
950         BUFFSEND;
951         if (unistimdebug) {
952                 ast_verb(6, "Sending ping\n");
953         }
954         pte->tick_next_ping = get_tick_count() + unistim_keepalive;
955         memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
956         send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
957 }
958
959 static int get_to_address(int fd, struct sockaddr_in *toAddr)
960 {
961 #ifdef HAVE_PKTINFO
962         int err;
963         struct msghdr msg;
964         struct {
965                 struct cmsghdr cm;
966                 int len;
967                 struct in_addr address;
968         } ip_msg;
969
970         /* Zero out the structures before we use them */
971         /* This sets several key values to NULL */
972         memset(&msg, 0, sizeof(msg));
973         memset(&ip_msg, 0, sizeof(ip_msg));
974
975         /* Initialize the message structure */
976         msg.msg_control = &ip_msg;
977         msg.msg_controllen = sizeof(ip_msg);
978         /* Get info about the incoming packet */
979         err = recvmsg(fd, &msg, MSG_PEEK);
980         if (err == -1) {
981                 ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
982         }
983         memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
984         return err;
985 #else
986         memcpy(&toAddr, &public_ip, sizeof(&toAddr));
987         return 0;
988 #endif
989 }
990
991 /* Allocate memory & initialize structures for a new phone */
992 /* addr_from : ip address of the phone */
993 static struct unistimsession *create_client(const struct sockaddr_in *addr_from)
994 {
995         int tmp;
996         struct unistimsession *s;
997
998         if (!(s = ast_calloc(1, sizeof(*s))))
999                 return NULL;
1000
1001         memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
1002         get_to_address(unistimsock, &s->sout);
1003         s->sout.sin_family = AF_INET;
1004         if (unistimdebug) {
1005                 ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
1006                          ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
1007         }
1008         ast_mutex_init(&s->lock);
1009         ast_mutex_lock(&sessionlock);
1010         s->next = sessions;
1011         sessions = s;
1012
1013         s->timeout = get_tick_count() + RETRANSMIT_TIMER;
1014         s->state = STATE_INIT;
1015         s->tick_next_ping = get_tick_count() + unistim_keepalive;
1016         /* Initialize struct wsabuf  */
1017         for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
1018                 s->wsabufsend[tmp].buf = s->buf[tmp];
1019         }
1020         ast_mutex_unlock(&sessionlock);
1021         return s;
1022 }
1023
1024 static void send_end_call(struct unistimsession *pte)
1025 {
1026         BUFFSEND;
1027         if (unistimdebug) {
1028                 ast_verb(0, "Sending end call\n");
1029         }
1030         memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
1031         send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
1032 }
1033
1034 static void set_ping_timer(struct unistimsession *pte)
1035 {
1036         unsigned int tick = 0;  /* XXX what is this for, anyways */
1037
1038         pte->timeout = pte->tick_next_ping;
1039         DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
1040         return;
1041 }
1042
1043 /* Checking if our send queue is empty,
1044  * if true, setting up a timer for keepalive */
1045 static void check_send_queue(struct unistimsession *pte)
1046 {
1047         /* Check if our send queue contained only one element */
1048         if (pte->last_buf_available == 1) {
1049                 if (unistimdebug) {
1050                         ast_verb(6, "Our single packet was ACKed.\n");
1051                 }
1052                 pte->last_buf_available--;
1053                 set_ping_timer(pte);
1054                 return;
1055         }
1056         /* Check if this ACK catch up our latest packet */
1057         else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
1058                 if (unistimdebug) {
1059                         ast_verb(6, "Our send queue is completely ACKed.\n");
1060                 }
1061                 pte->last_buf_available = 0;    /* Purge the send queue */
1062                 set_ping_timer(pte);
1063                 return;
1064         }
1065         if (unistimdebug) {
1066                 ast_verb(6, "We still have packets in our send queue\n");
1067         }
1068         return;
1069 }
1070
1071 static void send_start_timer(struct unistimsession *pte)
1072 {
1073         BUFFSEND;
1074         if (unistimdebug) {
1075                 ast_verb(0, "Sending start timer\n");
1076         }
1077         memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer));
1078         send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte);
1079 }
1080
1081 static void send_stop_timer(struct unistimsession *pte)
1082 {
1083         BUFFSEND;
1084         if (unistimdebug) {
1085                 ast_verb(0, "Sending stop timer\n");
1086         }
1087         memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
1088         send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
1089 }
1090
1091 static void send_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
1092 {
1093         BUFFSEND;
1094         if (unistimdebug) {
1095                 ast_verb(0, "Sending icon pos %d with status 0x%.2x\n", pos, status);
1096         }
1097         memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
1098         buffsend[9] = pos;
1099         buffsend[10] = status;
1100         send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
1101 }
1102
1103 static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
1104 {
1105         BUFFSEND;
1106         if (!tone1) {
1107                 if (unistimdebug) {
1108                         ast_verb(0, "Sending Stream Based Tone Off\n");
1109                 }
1110                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
1111                            sizeof(packet_send_stream_based_tone_off));
1112                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
1113                 return;
1114         }
1115         /* Since most of the world use a continuous tone, it's useless
1116            if (unistimdebug)
1117            ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
1118            memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
1119            send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
1120         if (unistimdebug) {
1121                 ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
1122         }
1123         tone1 *= 8;
1124         if (!tone2) {
1125                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
1126                            sizeof(packet_send_stream_based_tone_single_freq));
1127                 buffsend[10] = (tone1 & 0xff00) >> 8;
1128                 buffsend[11] = (tone1 & 0x00ff);
1129                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
1130                                    pte);
1131         } else {
1132                 tone2 *= 8;
1133                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
1134                            sizeof(packet_send_stream_based_tone_dial_freq));
1135                 buffsend[10] = (tone1 & 0xff00) >> 8;
1136                 buffsend[11] = (tone1 & 0x00ff);
1137                 buffsend[12] = (tone2 & 0xff00) >> 8;
1138                 buffsend[13] = (tone2 & 0x00ff);
1139                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
1140                                    pte);
1141         }
1142
1143         if (unistimdebug) {
1144                 ast_verb(0, "Sending Stream Based Tone On\n");
1145         }
1146         memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
1147                    sizeof(packet_send_stream_based_tone_on));
1148         send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
1149 }
1150
1151 /* Positions for favorites
1152  |--------------------|
1153  |  5            2    | <-- not on screen in i2002
1154  |  4            1    |
1155  |  3            0    |
1156 */
1157
1158 /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */
1159 static void
1160 send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte,
1161                          const char *text)
1162 {
1163         BUFFSEND;
1164         int i;
1165
1166         if (unistimdebug) {
1167                 ast_verb(0, "Sending favorite pos %d with status 0x%.2x\n", pos, status);
1168         }
1169         memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1170         buffsend[10] = pos;
1171         buffsend[24] = pos;
1172         buffsend[25] = status;
1173         i = strlen(ustmtext(text, pte));
1174         if (i > FAV_MAX_LENGTH) {
1175                 i = FAV_MAX_LENGTH;
1176         }
1177         memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i);
1178         send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1179 }
1180
1181 static void send_favorite_short(unsigned char pos, unsigned char status, struct unistimsession *pte) {
1182         send_favorite(pos, status, pte, pte->device->softkeylabel[pos]);
1183         return;
1184 }
1185
1186 static void send_favorite_selected(unsigned char status, struct unistimsession *pte) {
1187         if (pte->device->selected != -1) {
1188                 send_favorite(pte->device->selected, status, pte, pte->device->softkeylabel[pte->device->selected]);
1189         }
1190         return;
1191 }
1192
1193 static int soft_key_visible(struct unistim_device* d, unsigned char num)
1194 {
1195         if(d->height == 1 && num % 3 == 2) {
1196                 return 0;
1197         }
1198         return 1;
1199 }
1200
1201 static void refresh_all_favorite(struct unistimsession *pte)
1202 {
1203         unsigned char i = 0;
1204         char data[256];
1205         struct unistim_line *line;
1206         line = AST_LIST_FIRST(&pte->device->lines);
1207
1208         if (unistimdebug) {
1209                 ast_verb(0, "Refreshing all favorite\n");
1210         }
1211         for (i = 0; i < FAVNUM; i++) {
1212                 unsigned char status = pte->device->softkeyicon[i];
1213
1214                 if (!soft_key_visible(pte->device, i)) {
1215                         continue;
1216                 }
1217                 if (!strcasecmp(pte->device->softkeylabel[i], "DND") && line) {
1218                         if (!ast_db_get("DND", line->name, data, sizeof(data))) {
1219                                 status = FAV_ICON_SPEAKER_ONHOOK_WHITE;
1220                         }
1221                 }
1222
1223                 send_favorite_short(i, status, pte);
1224         }
1225 }
1226
1227 static int is_key_favorite(struct unistim_device *d, int fav)
1228 {
1229         if ((fav < 0) && (fav > 5)) {
1230                 return 0;
1231         }
1232         if (d->sline[fav]) {
1233                 return 0;
1234         }
1235         if (d->softkeynumber[fav][0] == '\0') {
1236                 return 0;
1237         }
1238         return 1;
1239 }
1240
1241 static int is_key_line(struct unistim_device *d, int fav)
1242 {
1243         if ((fav < 0) && (fav > 5)) {
1244                 return 0;
1245         }
1246         if (!d->sline[fav]) {
1247                 return 0;
1248         }
1249         if (is_key_favorite(d, fav)) {
1250                 return 0;
1251         }
1252         return 1;
1253 }
1254
1255 static int get_active_softkey(struct unistimsession *pte)
1256 {
1257         return pte->device->selected;
1258 }
1259
1260 static int get_avail_softkey(struct unistimsession *pte, const char* name)
1261 {
1262         int i;
1263
1264         if (!is_key_line(pte->device, pte->device->selected)) {
1265                 pte->device->selected = -1;
1266         }
1267         for (i = 0; i < FAVNUM; i++) {
1268                 if (pte->device->selected != -1 && pte->device->selected != i) {
1269                         continue;
1270                 }
1271                 if (!soft_key_visible(pte->device, i)) {
1272                         continue;
1273                 }
1274                 if (pte->device->ssub[i]) {
1275                         continue;
1276                 }
1277                 if (is_key_line(pte->device, i)) {
1278                         if (name && strcmp(name, pte->device->sline[i]->name)) {
1279                                 continue;
1280                         }
1281                         if (unistimdebug) {
1282                                 ast_verb(0, "Found softkey %d for device %s\n", i, name);
1283                         }
1284                         return i;
1285                 }
1286         }
1287         return -1;
1288 }
1289
1290
1291 /* Change the status for this phone (pte) and update for each phones where pte is bookmarked
1292  * use FAV_ICON_*_BLACK constant in status parameters */
1293 static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
1294 {
1295         struct unistim_device *d = devices;
1296         int i;
1297         /* Update the current phone line softkey icon */
1298         if (pte->state != STATE_CLEANING) {
1299                 int softkeylinepos = get_active_softkey(pte);
1300                 if (softkeylinepos != -1) {
1301                         send_favorite_short(softkeylinepos, status, pte);
1302                 }
1303         }
1304         /* Notify other phones if we're in their bookmark */
1305         while (d) {
1306                 for (i = 0; i < FAVNUM; i++) {
1307                         if (d->sp[i] == pte->device) {  /* It's us ? */
1308                                 if (d->softkeyicon[i] != status) {      /* Avoid resending the same icon */
1309                                         d->softkeyicon[i] = status;
1310                                         if (d->session) {
1311                                                 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1312                                         }
1313                                 }
1314                         }
1315                 }
1316                 d = d->next;
1317         }
1318 }
1319
1320 static int register_extension(const struct unistimsession *pte)
1321 {
1322         struct unistim_line *line;
1323         line = AST_LIST_FIRST(&pte->device->lines);
1324         if (unistimdebug) {
1325                 ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
1326                                         pte->device->extension_number, pte->device->context,
1327                                         line->fullname);
1328         }
1329         return ast_add_extension(pte->device->context, 0,
1330                                                          pte->device->extension_number, 1, NULL, NULL, "Dial",
1331                                                          line->fullname, 0, "Unistim");
1332 }
1333
1334 static int unregister_extension(const struct unistimsession *pte)
1335 {
1336         if (unistimdebug) {
1337                 ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
1338                                         pte->device->extension_number, pte->device->context);
1339         }
1340         return ast_context_remove_extension(pte->device->context,
1341                                                                                 pte->device->extension_number, 1, "Unistim");
1342 }
1343
1344 /* Free memory allocated for a phone */
1345 static void close_client(struct unistimsession *s)
1346 {
1347         struct unistim_subchannel *sub = NULL;
1348         struct unistimsession *cur, *prev = NULL;
1349         ast_mutex_lock(&sessionlock);
1350         cur = sessions;
1351         /* Looking for the session in the linked chain */
1352         while (cur) {
1353                 if (cur == s) {
1354                         break;
1355                 }
1356                 prev = cur;
1357                 cur = cur->next;
1358         }
1359         if (cur) {                                    /* Session found ? */
1360                 if (cur->device) {            /* This session was registered ? */
1361                         s->state = STATE_CLEANING;
1362                         if (unistimdebug) {
1363                                 ast_verb(0, "close_client session %p device %p\n", s, s->device);
1364                         }
1365                         change_favorite_icon(s, FAV_ICON_NONE);
1366                         ast_mutex_lock(&s->device->lock);
1367                         AST_LIST_LOCK(&s->device->subs);
1368                         AST_LIST_TRAVERSE_SAFE_BEGIN(&s->device->subs, sub, list) {
1369                                 if (!sub) {
1370                                         continue;
1371                                 }
1372                                 if (sub->owner) {       /* Call in progress ? */
1373                                         if (unistimdebug) {
1374                                                 ast_verb(0, "Aborting call\n");
1375                                         }
1376                                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NETWORK_OUT_OF_ORDER);
1377                                 } else {
1378                                         if (unistimdebug) {
1379                                                 ast_debug(1, "Released sub %d of channel %s@%s\n", sub->subtype, sub->parent->name, s->device->name);
1380                                         }
1381                                         AST_LIST_REMOVE_CURRENT(list);
1382                                         unistim_free_sub(sub);
1383                                 }
1384                         }
1385                         AST_LIST_TRAVERSE_SAFE_END;
1386                         AST_LIST_UNLOCK(&s->device->subs);
1387
1388                         if (!ast_strlen_zero(s->device->extension_number)) {
1389                                 unregister_extension(s);
1390                         }
1391                         cur->device->session = NULL;
1392                         ast_mutex_unlock(&s->device->lock);
1393                 } else {
1394                         if (unistimdebug) {
1395                                 ast_verb(0, "Freeing an unregistered client\n");
1396                         }
1397                 }
1398                 if (prev) {
1399                         prev->next = cur->next;
1400                 } else {
1401                         sessions = cur->next;
1402                 }
1403                 ast_mutex_destroy(&s->lock);
1404                 ast_free(s);
1405         } else {
1406                 ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
1407         }
1408         ast_mutex_unlock(&sessionlock);
1409         return;
1410 }
1411
1412 /* Return 1 if the session chained link was modified */
1413 static int send_retransmit(struct unistimsession *pte)
1414 {
1415         int i;
1416
1417         ast_mutex_lock(&pte->lock);
1418         if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
1419                 if (unistimdebug) {
1420                         ast_verb(0, "Too many retransmit - freeing client\n");
1421                 }
1422                 ast_mutex_unlock(&pte->lock);
1423                 close_client(pte);
1424                 return 1;
1425         }
1426         pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
1427
1428         for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
1429                  i < pte->last_buf_available; i++) {
1430                 if (i < 0) {
1431                         ast_log(LOG_WARNING,
1432                                         "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%.4x last_seq_ack = #0x%.4x\n",
1433                                         pte->last_buf_available, pte->seq_server, pte->last_seq_ack);
1434                         continue;
1435                 }
1436
1437                 if (unistimdebug) {
1438                         unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
1439                         unsigned short seq;
1440
1441                         seq = ntohs(sbuf[1]);
1442                         ast_verb(0, "Retransmit slot #%d (seq=#0x%.4x), last ack was #0x%.4x\n", i,
1443                                                 seq, pte->last_seq_ack);
1444                 }
1445                 send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
1446                                           &pte->sout);
1447         }
1448         ast_mutex_unlock(&pte->lock);
1449         return 0;
1450 }
1451
1452 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1453 static void
1454 send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte,
1455                  const char *text)
1456 {
1457         int i;
1458         BUFFSEND;
1459         if (!text) {
1460                 ast_log(LOG_ERROR, "Asked to display NULL text (pos %d, inverse flag %d)\n", pos, inverse);
1461                 return;
1462         }
1463         if (pte->device && pte->device->height == 1 && pos != TEXT_LINE0) {
1464                 return;
1465         }
1466         if (unistimdebug) {
1467                 ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
1468         }
1469         memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
1470         buffsend[10] = pos;
1471         buffsend[11] = inverse;
1472         i = strlen(text);
1473         if (i > TEXT_LENGTH_MAX) {
1474                 i = TEXT_LENGTH_MAX;
1475         }
1476         memcpy(buffsend + 12, text, i);
1477         send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
1478 }
1479
1480 static void send_text_status(struct unistimsession *pte, const char *text)
1481 {
1482         BUFFSEND;
1483         int i;
1484         if (unistimdebug) {
1485                 ast_verb(0, "Sending status text\n");
1486         }
1487         if (pte->device) {
1488                 if (pte->device->status_method == 1) {  /* For new firmware and i2050 soft phone */
1489                         int n = strlen(text);
1490                         /* Must send individual button separately */
1491                         int j;
1492                         for (i = 0, j = 0; i < 4; i++, j += 7) {
1493                                 int pos = 0x08 + (i * 0x20);
1494                                 memcpy(buffsend + SIZE_HEADER, packet_send_status2,
1495                                            sizeof(packet_send_status2));
1496
1497                                 buffsend[9] = pos;
1498                                 memcpy(buffsend + 10, (j < n) ? (text + j) : "       ", 7);
1499                                 send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
1500                         }
1501                         return;
1502                 }
1503         }
1504
1505
1506         memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
1507         i = strlen(text);
1508         if (i > STATUS_LENGTH_MAX) {
1509                 i = STATUS_LENGTH_MAX;
1510         }
1511         memcpy(buffsend + 10, text, i);
1512         send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
1513
1514 }
1515
1516 /* led values in hexa : 0 = bar off, 1 = bar on, 2 = bar 1s on/1s off, 3 = bar 2.5s on/0.5s off
1517  * 4 = bar 0.6s on/0.3s off, 5 = bar 0.5s on/0.5s off, 6 = bar 2s on/0.5s off
1518  * 7 = bar off, 8 = speaker off, 9 = speaker on, 10 = headphone off, 11 = headphone on
1519  * 18 = mute off, 19 mute on */
1520 static void send_led_update(struct unistimsession *pte, unsigned char led)
1521 {
1522         BUFFSEND;
1523         if (unistimdebug) {
1524                 ast_verb(0, "Sending led_update (%x)\n", led);
1525         }
1526         memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1527         buffsend[9] = led;
1528         send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1529 }
1530
1531 /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
1532  * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
1533  * mute = MUTE_OFF, MUTE_ON */
1534 static void
1535 send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume,
1536                                  unsigned char mute)
1537 {
1538         BUFFSEND;
1539         if (unistimdebug) {
1540                 ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n", output,
1541                                         volume, mute);
1542         }
1543         memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1544                    sizeof(packet_send_select_output));
1545         buffsend[9] = output;
1546         if (output == OUTPUT_SPEAKER) {
1547                 volume = VOLUME_LOW_SPEAKER;
1548         } else {
1549                 volume = VOLUME_LOW;
1550         }
1551         buffsend[10] = volume;
1552         if (mute == MUTE_ON_DISCRET) {
1553                 buffsend[11] = MUTE_ON;
1554         } else {
1555                 buffsend[11] = mute;
1556         }
1557         send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1558         if (mute == MUTE_OFF) {
1559                 send_led_update(pte, 0x18);
1560         } else if (mute == MUTE_ON) {
1561                 send_led_update(pte, 0x19);
1562         }
1563         pte->device->mute = mute;
1564         if (output == OUTPUT_HANDSET) {
1565                 if (mute == MUTE_ON) {
1566                         change_favorite_icon(pte, FAV_ICON_ONHOLD_BLACK);
1567                 } else {
1568                         change_favorite_icon(pte, FAV_ICON_OFFHOOK_BLACK);
1569                 }
1570                 send_led_update(pte, 0x08);
1571                 send_led_update(pte, 0x10);
1572         } else if (output == OUTPUT_HEADPHONE) {
1573                 if (mute == MUTE_ON) {
1574                         change_favorite_icon(pte, FAV_ICON_HEADPHONES_ONHOLD);
1575                 } else {
1576                         change_favorite_icon(pte, FAV_ICON_HEADPHONES);
1577                 }
1578                 send_led_update(pte, 0x08);
1579                 send_led_update(pte, 0x11);
1580         } else if (output == OUTPUT_SPEAKER) {
1581                 send_led_update(pte, 0x10);
1582                 send_led_update(pte, 0x09);
1583                 if (pte->device->receiver_state == STATE_OFFHOOK) {
1584                         if (mute == MUTE_ON) {
1585                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
1586                         } else {
1587                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOOK_BLACK);
1588                         }
1589                 } else {
1590                         if (mute == MUTE_ON) {
1591                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
1592                         } else {
1593                                 change_favorite_icon(pte, FAV_ICON_SPEAKER_OFFHOOK_BLACK);
1594                         }
1595                 }
1596         } else {
1597                 ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
1598         }
1599         if (output != pte->device->output) {
1600                 pte->device->previous_output = pte->device->output;
1601         }
1602         pte->device->output = output;
1603 }
1604
1605 static void send_ring(struct unistimsession *pte, char volume, char style)
1606 {
1607         BUFFSEND;
1608         if (unistimdebug) {
1609                 ast_verb(0, "Sending ring packet\n");
1610         }
1611         memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1612         buffsend[24] = style + 0x10;
1613         buffsend[29] = volume * 0x10;
1614         send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1615 }
1616
1617 static void send_no_ring(struct unistimsession *pte)
1618 {
1619         BUFFSEND;
1620         if (unistimdebug) {
1621                 ast_verb(0, "Sending no ring packet\n");
1622         }
1623         memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1624         send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1625 }
1626
1627 static void send_texttitle(struct unistimsession *pte, const char *text)
1628 {
1629         BUFFSEND;
1630         int i;
1631         if (unistimdebug) {
1632                 ast_verb(0, "Sending title text\n");
1633         }
1634         memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1635         i = strlen(text);
1636         if (i > 12) {
1637                 i = 12;
1638         }
1639         memcpy(buffsend + 10, text, i);
1640         send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1641
1642 }
1643
1644 static void send_idle_clock(struct unistimsession *pte)
1645 {
1646         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
1647 }
1648
1649 static void send_date_time(struct unistimsession *pte)
1650 {
1651         BUFFSEND;
1652         struct timeval now = ast_tvnow();
1653         struct ast_tm atm = { 0, };
1654
1655         if (unistimdebug) {
1656                 ast_verb(0, "Sending Time & Date\n");
1657         }
1658         memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1659         ast_localtime(&now, &atm, NULL);
1660         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1661         buffsend[11] = (unsigned char) atm.tm_mday;
1662         buffsend[12] = (unsigned char) atm.tm_hour;
1663         buffsend[13] = (unsigned char) atm.tm_min;
1664         send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1665 }
1666
1667 static void send_date_time2(struct unistimsession *pte)
1668 {
1669         BUFFSEND;
1670         struct timeval now = ast_tvnow();
1671         struct ast_tm atm = { 0, };
1672
1673         if (unistimdebug) {
1674                 ast_verb(0, "Sending Time & Date #2\n");
1675         }
1676         memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1677         ast_localtime(&now, &atm, NULL);
1678         if (pte->device) {
1679                 buffsend[9] = pte->device->datetimeformat;
1680         } else {
1681                 buffsend[9] = 61;
1682         }
1683         buffsend[14] = (unsigned char) atm.tm_mon + 1;
1684         buffsend[15] = (unsigned char) atm.tm_mday;
1685         buffsend[16] = (unsigned char) atm.tm_hour;
1686         buffsend[17] = (unsigned char) atm.tm_min;
1687         send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1688 }
1689
1690 static void send_date_time3(struct unistimsession *pte)
1691 {
1692         BUFFSEND;
1693         struct timeval now = ast_tvnow();
1694         struct ast_tm atm = { 0, };
1695
1696         if (unistimdebug) {
1697                 ast_verb(0, "Sending Time & Date #3\n");
1698         }
1699         memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1700         ast_localtime(&now, &atm, NULL);
1701         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1702         buffsend[11] = (unsigned char) atm.tm_mday;
1703         buffsend[12] = (unsigned char) atm.tm_hour;
1704         buffsend[13] = (unsigned char) atm.tm_min;
1705         send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1706 }
1707
1708 static void send_blink_cursor(struct unistimsession *pte)
1709 {
1710         BUFFSEND;
1711         if (unistimdebug) {
1712                 ast_verb(0, "Sending set blink\n");
1713         }
1714         memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
1715         send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1716         return;
1717 }
1718
1719 /* pos : 0xab (a=0/2/4 = line ; b = row) */
1720 static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
1721 {
1722         BUFFSEND;
1723         if (unistimdebug) {
1724                 ast_verb(0, "Sending set cursor position\n");
1725         }
1726         memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1727                    sizeof(packet_send_set_pos_cursor));
1728         buffsend[11] = pos;
1729         send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1730         return;
1731 }
1732
1733 static void send_charset_update(struct unistimsession *pte, int charset)
1734 {
1735         const unsigned char* packet_send_charset;
1736         int packet_size;
1737         BUFFSEND;
1738         if (unistimdebug) {
1739                 ast_verb(0, "Sending set default charset\n");
1740         }
1741         if (charset == LANG_DEFAULT) {
1742                 charset = options_languages[find_language(pte->device->language)].encoding;
1743         }
1744         switch (charset) {
1745         case ISO_8859_2:
1746                 packet_send_charset = packet_send_charset_iso_8859_2;
1747                 packet_size = sizeof(packet_send_charset_iso_8859_2);
1748                 break;
1749         case ISO_8859_4:
1750                 packet_send_charset = packet_send_charset_iso_8859_4;
1751                 packet_size = sizeof(packet_send_charset_iso_8859_4);
1752                 break;
1753         case ISO_8859_5:
1754                 packet_send_charset = packet_send_charset_iso_8859_5;
1755                 packet_size = sizeof(packet_send_charset_iso_8859_5);
1756                 break;
1757         case ISO_2022_JP:
1758                 packet_send_charset = packet_send_charset_iso_2022_jp;
1759                 packet_size = sizeof(packet_send_charset_iso_2022_jp);
1760                 break;
1761         case ISO_8859_1:
1762         default:
1763                 packet_send_charset = packet_send_charset_iso_8859_1;
1764                 packet_size = sizeof(packet_send_charset_iso_8859_1);
1765         }
1766         memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size);
1767         send_client(SIZE_HEADER + packet_size, buffsend, pte);
1768         return;
1769 }
1770
1771 static void rcv_resume_connection_with_server(struct unistimsession *pte)
1772 {
1773         BUFFSEND;
1774         if (unistimdebug) {
1775                 ast_verb(0, "ResumeConnectionWithServer received\n");
1776                 ast_verb(0, "Sending packet_send_query_mac_address\n");
1777         }
1778         memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1779                    sizeof(packet_send_query_mac_address));
1780         send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1781         return;
1782 }
1783
1784 static int unistim_register(struct unistimsession *s)
1785 {
1786         struct unistim_device *d;
1787
1788         ast_mutex_lock(&devicelock);
1789         d = devices;
1790         while (d) {
1791                 if (!strcasecmp(s->macaddr, d->id)) {
1792                         /* XXX Deal with IP authentication */
1793                         s->device = d;
1794                         d->session = s;
1795                         d->codec_number = DEFAULT_CODEC;
1796                         d->missed_call = 0;
1797                         d->receiver_state = STATE_ONHOOK;
1798                         break;
1799                 }
1800                 d = d->next;
1801         }
1802         ast_mutex_unlock(&devicelock);
1803
1804         if (!d) {
1805                 return 0;
1806         }
1807
1808         return 1;
1809 }
1810
1811 static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
1812 {
1813         struct ast_format_cap *tmp = src->cap;
1814         memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
1815         src->cap = tmp;
1816         ast_format_cap_copy(src->cap, dst->cap);
1817 }
1818
1819 static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
1820 {
1821         if (!l) {
1822                 return NULL;
1823         }
1824         l->cap = ast_format_cap_destroy(l->cap);
1825         ast_free(l);
1826         return NULL;
1827 }
1828
1829 static struct unistim_line *unistim_line_alloc(void)
1830 {
1831         struct unistim_line *l;
1832         if (!(l = ast_calloc(1, sizeof(*l)))) {
1833                 return NULL;
1834         }
1835
1836         if (!(l->cap = ast_format_cap_alloc_nolock())) {
1837                 ast_free(l);
1838                 return NULL;
1839         }
1840         return l;
1841 }
1842
1843 static int unistim_free_sub(struct unistim_subchannel *sub) {
1844         if (unistimdebug) {
1845                 ast_debug(1, "Released sub %d of channel %s@%s\n", sub->subtype, sub->parent->name, sub->parent->parent->name);
1846         }
1847         ast_mutex_destroy(&sub->lock);
1848         ast_free(sub);
1849         return 0;
1850 }
1851
1852 static struct unistim_subchannel *unistim_alloc_sub(struct unistim_device *d, int x)
1853 {
1854         struct unistim_subchannel *sub;
1855         if (!(sub = ast_calloc(1, sizeof(*sub)))) {
1856                 return NULL;
1857         }
1858
1859         if (unistimdebug) {
1860                 ast_verb(3, "Allocating UNISTIM subchannel #%d on %s ptr=%p\n", x, d->name, sub);
1861         }
1862         sub->ss_thread = AST_PTHREADT_NULL;
1863         sub->subtype = x;
1864         AST_LIST_LOCK(&d->subs);
1865         AST_LIST_INSERT_TAIL(&d->subs, sub, list);
1866         AST_LIST_UNLOCK(&d->subs);
1867         ast_mutex_init(&sub->lock);
1868         return sub;
1869 }
1870
1871 static int unistim_unalloc_sub(struct unistim_device *d, struct unistim_subchannel *sub)
1872 {
1873         struct unistim_subchannel *s;
1874
1875         AST_LIST_LOCK(&d->subs);
1876         AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, s, list) {
1877                 if (!s) {
1878                         continue;
1879                 }
1880                 if (s != sub) {
1881                         continue;
1882                 }
1883                 AST_LIST_REMOVE_CURRENT(list);
1884                 unistim_free_sub(sub);
1885         }
1886         AST_LIST_TRAVERSE_SAFE_END;
1887         AST_LIST_UNLOCK(&d->subs);
1888         return 0;
1889 }
1890
1891 static const char *subtype_tostr(const int type)
1892 {
1893         switch (type) {
1894         case SUB_REAL:
1895                 return "REAL";
1896         case SUB_ONHOLD:
1897                 return "ONHOLD";
1898         case SUB_RING:
1899                 return "RINGING";
1900         case SUB_THREEWAY:
1901                 return "THREEWAY";
1902         }
1903         return "UNKNOWN";
1904 }
1905
1906 static const char *ptestate_tostr(const int type)
1907 {
1908         switch (type) {
1909         case STATE_INIT:
1910                 return "INIT";
1911         case STATE_AUTHDENY:
1912                 return "AUTHDENY";
1913         case STATE_MAINPAGE:
1914                 return "MAINPAGE";
1915         case STATE_EXTENSION:
1916                 return "EXTENSION";
1917         case STATE_DIALPAGE:
1918                 return "DIALPAGE";
1919         case STATE_RINGING:
1920                 return "RINGING";
1921         case STATE_CALL:
1922                 return "CALL";
1923         case STATE_SELECTOPTION:
1924                 return "SELECTOPTION";
1925         case STATE_SELECTCODEC:
1926                 return "SELECTCODEC";
1927         case STATE_SELECTLANGUAGE:
1928                 return "SELECTLANGUAGE";
1929         case STATE_CLEANING:
1930                 return "CLEARING";
1931         case STATE_HISTORY:
1932                 return "HISTORY";
1933         }
1934         return "UNKNOWN";
1935 }
1936
1937 static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
1938 {
1939         BUFFSEND;
1940         int tmp, i = 0;
1941         char addrmac[19];
1942         int res = 0;
1943         for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
1944                 sprintf(&addrmac[i], "%.2x", (unsigned char) buf[tmp]);
1945                 i += 2;
1946         }
1947         if (unistimdebug) {
1948                 ast_verb(0, "MAC Address received: %s\n", addrmac);
1949         }
1950         strcpy(pte->macaddr, addrmac);
1951         res = unistim_register(pte);
1952         if (!res) {
1953                 switch (autoprovisioning) {
1954                 case AUTOPROVISIONING_NO:
1955                         ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
1956                         pte->state = STATE_AUTHDENY;
1957                         break;
1958                 case AUTOPROVISIONING_YES:
1959                         {
1960                                 struct unistim_device *d = NULL, *newd = NULL;
1961                                 struct unistim_line *newl = NULL, *l = NULL;
1962                                 if (unistimdebug) {
1963                                         ast_verb(0, "New phone, autoprovisioning on\n");
1964                                 }
1965                                 /* First : locate the [template] section */
1966                                 ast_mutex_lock(&devicelock);
1967                                 d = devices;
1968                                 while (d) {
1969                                         if (strcasecmp(d->name, "template")) {
1970                                                 d = d->next;
1971                                                 continue;
1972                                         }
1973                                         /* Found, cloning this entry */
1974                                         if (!(newd = ast_malloc(sizeof(*newd)))) {
1975                                                 ast_mutex_unlock(&devicelock);
1976                                                 return;
1977                                         }
1978                                         memcpy(newd, d, sizeof(*newd));
1979                                         ast_mutex_init(&newd->lock);
1980                                         newd->lines.first = NULL;
1981                                         newd->lines.last = NULL;
1982                                         AST_LIST_LOCK(&d->lines);
1983                                         AST_LIST_TRAVERSE(&d->lines, l, list) {
1984                                                 if (!(newl = unistim_line_alloc())) {
1985                                                         break;
1986                                                 }
1987                                                 unistim_line_copy(l, newl);
1988                                                 newl->parent = newd;
1989                                                 ast_copy_string(newl->name, l->name, sizeof(newl->name));
1990                                                 snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
1991                                                                  newl->name, newd->name);
1992                                                 snprintf(l->name, sizeof(l->name), "%d", atoi(l->name) + 1);
1993
1994                                                 AST_LIST_LOCK(&newd->lines);
1995                                                 AST_LIST_INSERT_TAIL(&newd->lines, newl, list);
1996                                                 AST_LIST_UNLOCK(&newd->lines);
1997                                         }
1998                                         AST_LIST_UNLOCK(&d->lines);
1999                                         if (!newl) {
2000                                                 ast_free(newd);
2001                                                 ast_mutex_unlock(&devicelock);
2002                                         }
2003
2004                                         /* Ok, now updating some fields */
2005                                         ast_copy_string(newd->id, addrmac, sizeof(newd->id));
2006                                         ast_copy_string(newd->name, addrmac, sizeof(newd->name));
2007                                         if (newd->extension == EXTENSION_NONE) {
2008                                                 newd->extension = EXTENSION_ASK;
2009                                         }
2010
2011                                         newd->receiver_state = STATE_ONHOOK;
2012                                         newd->session = pte;
2013                                         newd->language[0] = '\0';
2014                                         newd->to_delete = -1;
2015                                         newd->next = NULL;
2016                                         pte->device = newd;
2017
2018                                         /* Go to the end of the linked chain */
2019                                         while (d->next) {
2020                                                 d = d->next;
2021                                         }
2022                                         d->next = newd;
2023                                         d = newd;
2024                                         break;
2025                                 }
2026                                 ast_mutex_unlock(&devicelock);
2027                                 if (!d) {
2028                                         ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
2029                                         pte->state = STATE_AUTHDENY;
2030                                 }
2031                         }
2032                         break;
2033                 case AUTOPROVISIONING_TN:
2034                         pte->state = STATE_AUTHDENY;
2035                         break;
2036                 default:
2037                         ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %d\n",
2038                                         autoprovisioning);
2039                 }
2040         }
2041         if (pte->state != STATE_AUTHDENY) {
2042                 struct unistim_line *line;
2043                 struct unistim_subchannel *sub;
2044
2045                 ast_verb(3, "Device '%s' successfuly registered\n", pte->device->name);
2046
2047                 AST_LIST_LOCK(&pte->device->subs);
2048                 AST_LIST_TRAVERSE_SAFE_BEGIN(&pte->device->subs, sub, list) {
2049                         if (sub) {
2050                                 ast_log(LOG_ERROR, "Subchannel lost sice reboot. Hanged channel may apear!\n");
2051                                 AST_LIST_REMOVE_CURRENT(list);
2052                                 ast_free(sub);
2053                         }
2054                 }
2055                 AST_LIST_TRAVERSE_SAFE_END;
2056                 AST_LIST_UNLOCK(&pte->device->subs);
2057
2058                 switch (pte->device->extension) {
2059                 case EXTENSION_NONE:
2060                         pte->state = STATE_MAINPAGE;
2061                         break;
2062                 case EXTENSION_ASK:
2063                         /* Checking if we already have an extension number */
2064                         if (ast_strlen_zero(pte->device->extension_number)) {
2065                                 pte->state = STATE_EXTENSION;
2066                         } else {
2067                                 /* Yes, because of a phone reboot. We don't ask again for the TN */
2068                                 if (register_extension(pte)) {
2069                                         pte->state = STATE_EXTENSION;
2070                                 } else {
2071                                         pte->state = STATE_MAINPAGE;
2072                                 }
2073                         }
2074                         break;
2075                 case EXTENSION_LINE:
2076                         line = AST_LIST_FIRST(&pte->device->lines);
2077                         ast_copy_string(pte->device->extension_number, line->name,
2078                                                         sizeof(pte->device->extension_number));
2079                         if (register_extension(pte)) {
2080                                 pte->state = STATE_EXTENSION;
2081                         } else {
2082                                 pte->state = STATE_MAINPAGE;
2083                         }
2084                         break;
2085                 case EXTENSION_TN:
2086                         /* If we are here, it's because of a phone reboot */
2087                         pte->state = STATE_MAINPAGE;
2088                         break;
2089                 default:
2090                         ast_log(LOG_WARNING, "Internal error, extension value unknown : %d\n",
2091                                         pte->device->extension);
2092                         pte->state = STATE_AUTHDENY;
2093                         break;
2094                 }
2095         }
2096         if (pte->state == STATE_EXTENSION) {
2097                 if (pte->device->extension != EXTENSION_TN) {
2098                         pte->device->extension = EXTENSION_ASK;
2099                 }
2100                 pte->device->extension_number[0] = '\0';
2101         }
2102         if (unistimdebug) {
2103                 ast_verb(0, "\nSending S1\n");
2104         }
2105         memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
2106         send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
2107
2108         if (unistimdebug) {
2109                 ast_verb(0, "Sending query_basic_manager_04\n");
2110         }
2111         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
2112                    sizeof(packet_send_query_basic_manager_04));
2113         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
2114
2115         if (unistimdebug) {
2116                 ast_verb(0, "Sending query_basic_manager_10\n");
2117         }
2118         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
2119                    sizeof(packet_send_query_basic_manager_10));
2120         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
2121
2122         send_date_time(pte);
2123         return;
2124 }
2125
2126 static int write_entry_history(struct unistimsession *pte, FILE * f, char c, char *line1)
2127 {
2128         if (fwrite(&c, 1, 1, f) != 1) {
2129                 display_last_error("Unable to write history log header.");
2130                 return -1;
2131         }
2132         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
2133                 display_last_error("Unable to write history entry - date.");
2134                 return -1;
2135         }
2136         if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
2137                 display_last_error("Unable to write history entry - callerid.");
2138                 return -1;
2139         }
2140         if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
2141                 display_last_error("Unable to write history entry - callername.");
2142                 return -1;
2143         }
2144         return 0;
2145 }
2146
2147 static int write_history(struct unistimsession *pte, char way, char ismissed)
2148 {
2149         char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
2150         char line1[TEXT_LENGTH_MAX + 1];
2151         char count = 0, *histbuf;
2152         int size;
2153         FILE *f, *f2;
2154         struct timeval now = ast_tvnow();
2155         struct ast_tm atm = { 0, };
2156
2157         if (!pte->device) {
2158                 return -1;
2159         }
2160         if (!pte->device->callhistory) {
2161                 return 0;
2162         }
2163         if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
2164                 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
2165                                 pte->device->name);
2166                 return -1;
2167         }
2168
2169         snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
2170         if (ast_mkdir(tmp, 0770)) {
2171                 ast_log(LOG_WARNING, "Unable to create directory for history\n");
2172                 return -1;
2173         }
2174
2175         ast_localtime(&now, &atm, NULL);
2176         if (ismissed) {
2177                 if (way == 'i') {
2178                         ast_copy_string(tmp2, ustmtext("Miss", pte), sizeof(tmp2));
2179                 } else {
2180                         ast_copy_string(tmp2, ustmtext("Fail", pte), sizeof(tmp2));
2181                 }
2182         } else {
2183                 ast_copy_string(tmp2, ustmtext("Answ", pte), sizeof(tmp2));
2184         }
2185         snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
2186                          atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
2187                          atm.tm_min, atm.tm_sec, tmp2);
2188
2189         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
2190                          USTM_LOG_DIR, pte->device->name, way);
2191         if ((f = fopen(tmp, "r"))) {
2192                 struct stat bufstat;
2193
2194                 if (stat(tmp, &bufstat)) {
2195                         display_last_error("Unable to stat history log.");
2196                         fclose(f);
2197                         return -1;
2198                 }
2199                 size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
2200                 if (bufstat.st_size != size) {
2201                         ast_log(LOG_WARNING,
2202                                         "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
2203                                         tmp, (int) bufstat.st_size, size);
2204                         fclose(f);
2205                         f = NULL;
2206                         count = 1;
2207                 }
2208         }
2209
2210         /* If we can't open the log file, we create a brand new one */
2211         if (!f) {
2212                 char c = 1;
2213                 int i;
2214
2215                 if ((errno != ENOENT) && (count == 0)) {
2216                         display_last_error("Unable to open history log.");
2217                         return -1;
2218                 }
2219                 f = fopen(tmp, "w");
2220                 if (!f) {
2221                         display_last_error("Unable to create history log.");
2222                         return -1;
2223                 }
2224                 if (write_entry_history(pte, f, c, line1)) {
2225                         fclose(f);
2226                         return -1;
2227                 }
2228                 memset(line1, ' ', TEXT_LENGTH_MAX);
2229                 for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
2230                         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
2231                                 display_last_error("Unable to write history entry - stuffing.");
2232                                 fclose(f);
2233                                 return -1;
2234                         }
2235                 }
2236                 if (fclose(f)) {
2237                         display_last_error("Unable to close history - creation.");
2238                 }
2239                 return 0;
2240         }
2241         /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
2242         if (fread(&count, 1, 1, f) != 1) {
2243                 display_last_error("Unable to read history header.");
2244                 fclose(f);
2245                 return -1;
2246         }
2247         if (count > MAX_ENTRY_LOG) {
2248                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
2249                                 count, MAX_ENTRY_LOG);
2250                 fclose(f);
2251                 return -1;
2252         }
2253         snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
2254                          USTM_LOG_DIR, pte->device->name, way);
2255         if (!(f2 = fopen(tmp2, "w"))) {
2256                 display_last_error("Unable to create temporary history log.");
2257                 fclose(f);
2258                 return -1;
2259         }
2260
2261         if (++count > MAX_ENTRY_LOG) {
2262                 count = MAX_ENTRY_LOG;
2263         }
2264         if (write_entry_history(pte, f2, count, line1)) {
2265                 fclose(f);
2266                 fclose(f2);
2267                 return -1;
2268         }
2269         size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
2270         if (!(histbuf = ast_malloc(size))) {
2271                 fclose(f);
2272                 fclose(f2);
2273                 return -1;
2274         }
2275
2276         if (fread(histbuf, size, 1, f) != 1) {
2277                 ast_free(histbuf);
2278                 fclose(f);
2279                 fclose(f2);
2280                 display_last_error("Unable to read previous history entries.");
2281                 return -1;
2282         }
2283         if (fwrite(histbuf, size, 1, f2) != 1) {
2284                 ast_free(histbuf);
2285                 fclose(f);
2286                 fclose(f2);
2287                 display_last_error("Unable to write previous history entries.");
2288                 return -1;
2289         }
2290         ast_free(histbuf);
2291         if (fclose(f)) {
2292                 display_last_error("Unable to close history log.");
2293         }
2294         if (fclose(f2)) {
2295                 display_last_error("Unable to close temporary history log.");
2296         }
2297         if (unlink(tmp)) {
2298                 display_last_error("Unable to remove old history log.");
2299         }
2300         if (rename(tmp2, tmp)) {
2301                 display_last_error("Unable to rename new history log.");
2302         }
2303         return 0;
2304 }
2305
2306 static void unistim_quiet_chan(struct ast_channel *chan)
2307 {
2308         if (chan && ast_channel_state(chan) == AST_STATE_UP) {
2309                 if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_MOH)) {
2310                         ast_moh_stop(chan);
2311                 } else if (ast_channel_generatordata(chan)) {
2312                         ast_deactivate_generator(chan);
2313                 }
2314         }
2315 }
2316
2317 static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
2318 {
2319         int res = 0;
2320         struct ast_channel
2321          *chana = NULL, *chanb = NULL, *bridgea = NULL, *bridgeb = NULL, *peera =
2322                 NULL, *peerb = NULL, *peerc = NULL, *peerd = NULL;
2323
2324         if (!p1->owner || !p2->owner) {
2325                 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
2326                 return -1;
2327         }
2328         chana = p1->owner;
2329         chanb = p2->owner;
2330         bridgea = ast_bridged_channel(chana);
2331         bridgeb = ast_bridged_channel(chanb);
2332
2333         if (bridgea) {
2334                 peera = chana;
2335                 peerb = chanb;
2336                 peerc = bridgea;
2337                 peerd = bridgeb;
2338         } else if (bridgeb) {
2339                 peera = chanb;
2340                 peerb = chana;
2341                 peerc = bridgeb;
2342                 peerd = bridgea;
2343         }
2344
2345         if (peera && peerb && peerc && (peerb != peerc)) {
2346                 unistim_quiet_chan(peera);
2347                 unistim_quiet_chan(peerb);
2348                 unistim_quiet_chan(peerc);
2349                 if (peerd) {
2350                         unistim_quiet_chan(peerd);
2351                 }
2352
2353                 if (ast_channel_cdr(peera) && ast_channel_cdr(peerb)) {
2354                         ast_channel_cdr_set(peerb, ast_cdr_append(ast_channel_cdr(peerb), ast_channel_cdr(peera)));
2355                 } else if (ast_channel_cdr(peera)) {
2356                         ast_channel_cdr_set(peerb, ast_channel_cdr(peera));
2357                 }
2358                 ast_channel_cdr_set(peera, NULL);
2359
2360                 if (ast_channel_cdr(peerb) && ast_channel_cdr(peerc)) {
2361                         ast_channel_cdr_set(peerb, ast_cdr_append(ast_channel_cdr(peerb), ast_channel_cdr(peerc)));
2362                 } else if (ast_channel_cdr(peerc)) {
2363                         ast_channel_cdr_set(peerb, ast_channel_cdr(peerc));
2364                 }
2365                 ast_channel_cdr_set(peerc, NULL);
2366
2367                 ast_log(LOG_NOTICE, "UNISTIM transfer: trying to masquerade %s into %s\n", ast_channel_name(peerc), ast_channel_name(peerb));
2368                 if (ast_channel_masquerade(peerb, peerc)) {
2369                         ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", ast_channel_name(peerb),
2370                                         ast_channel_name(peerc));
2371                         res = -1;
2372                 }
2373                 return res;
2374         } else {
2375                 ast_log(LOG_NOTICE,
2376                                 "Transfer attempted with no appropriate bridged calls to transfer\n");
2377                 if (chana) {
2378                         ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
2379                 }
2380                 if (chanb) {
2381                         ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
2382                 }
2383                 return -1;
2384         }
2385         return 0;
2386 }
2387
2388 void change_callerid(struct unistimsession *pte, int type, char *callerid)
2389 {
2390         char *data;
2391         int size;
2392
2393         if (type) {
2394                 data = pte->device->lst_cnm;
2395         } else {
2396                 data = pte->device->lst_cid;
2397         }
2398
2399         /* This is very nearly strncpy(), except that the remaining buffer
2400          * is padded with ' ', instead of '\0' */
2401         memset(data, ' ', TEXT_LENGTH_MAX);
2402         size = strlen(callerid);
2403         if (size > TEXT_LENGTH_MAX) {
2404                 size = TEXT_LENGTH_MAX;
2405         }
2406         memcpy(data, callerid, size);
2407 }
2408
2409 static struct unistim_subchannel* get_sub(struct unistim_device *device, int type)
2410 {
2411         struct unistim_subchannel *sub = NULL;
2412
2413         AST_LIST_LOCK(&device->subs);
2414         AST_LIST_TRAVERSE(&device->subs, sub, list) {
2415                 if (!sub) {
2416                         continue;
2417                 }
2418                 if (sub->subtype == type) {
2419                         break;
2420                 }
2421         }
2422         AST_LIST_UNLOCK(&device->subs);
2423
2424         return sub;
2425 }
2426
2427 static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
2428 {
2429         /* Silence our channel */
2430         if (!pte->device->silence_generator) {
2431                 pte->device->silence_generator =
2432                         ast_channel_start_silence_generator(sub->owner);
2433                 if (pte->device->silence_generator == NULL) {
2434                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2435                 } else if (unistimdebug) {
2436                         ast_verb(0, "Starting silence generator\n");
2437                 }
2438         }
2439
2440 }
2441
2442 static void sub_stop_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
2443 {
2444         /* Stop the silence generator */
2445         if (pte->device->silence_generator) {
2446                 if (unistimdebug) {
2447                         ast_verb(0, "Stopping silence generator\n");
2448                 }
2449                 if (sub->owner) {
2450                         ast_channel_stop_silence_generator(sub->owner, pte->device->silence_generator);
2451                 } else {
2452                         ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel!\n");
2453                 }
2454                 pte->device->silence_generator = NULL;
2455         }
2456 }
2457
2458 static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub)
2459 {
2460         if (!sub) {
2461                 return;
2462         }
2463         sub->moh = 1;
2464         sub->subtype = SUB_ONHOLD;
2465         send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte);
2466         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2467         send_stop_timer(pte);
2468         if (sub->owner) {
2469                 ast_queue_control_data(sub->owner, AST_CONTROL_HOLD, NULL, 0);
2470                 send_end_call(pte);
2471         }
2472         return;
2473 }
2474
2475 static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *sub)
2476 {
2477         struct unistim_subchannel *sub_real;
2478
2479         sub_real = get_sub(pte->device, SUB_REAL);
2480         if (sub_real) {
2481             sub_hold(pte, sub_real);
2482         }
2483
2484         sub->moh = 0;
2485         sub->subtype = SUB_REAL;
2486         send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte);
2487         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2488         send_start_timer(pte);
2489         if (sub->owner) {
2490                 ast_queue_control_data(sub->owner, AST_CONTROL_UNHOLD, NULL, 0);
2491                 if (sub->rtp) {
2492                         send_start_rtp(sub);
2493                 }
2494         }
2495         return;
2496 }
2497
2498 static void close_call(struct unistimsession *pte)
2499 {
2500         struct unistim_subchannel *sub, *sub_transf;
2501
2502         sub = get_sub(pte->device, SUB_REAL);
2503         sub_transf = get_sub(pte->device, SUB_THREEWAY);
2504         send_stop_timer(pte);
2505         if (!sub) {
2506                 ast_log(LOG_WARNING, "Close call without sub\n");
2507                 return;
2508         }
2509         send_favorite_short(sub->softkey, FAV_LINE_ICON, pte);
2510         if (sub->owner) {
2511                 sub->alreadygone = 1;
2512                 if (sub_transf) {
2513                         sub_transf->alreadygone = 1;
2514                         if (attempt_transfer(sub, sub_transf) < 0) {
2515                                 ast_verb(0, "attempt_transfer failed.\n");
2516                         }
2517                 } else {
2518                         ast_queue_hangup(sub->owner);
2519                 }
2520         } else {
2521                 if (sub_transf) {
2522                         if (sub_transf->owner) {
2523                                 ast_queue_hangup_with_cause(sub_transf->owner, AST_CAUSE_NORMAL_CLEARING);
2524                         } else {
2525                                 ast_log(LOG_WARNING, "threeway sub without owner\n");
2526                         }
2527                 } else {
2528                         ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2529                                                 pte->device->name, sub->softkey);
2530                 }
2531         }
2532         change_callerid(pte, 0, pte->device->redial_number);
2533         change_callerid(pte, 1, "");
2534         write_history(pte, 'o', pte->device->missed_call);
2535         pte->device->missed_call = 0;
2536         show_main_page(pte);
2537         return;
2538 }
2539
2540 static void ignore_call(struct unistimsession *pte)
2541 {
2542         send_no_ring(pte);
2543         return;
2544 }
2545
2546 static void discard_call(struct unistimsession *pte)
2547 {
2548         struct unistim_subchannel* sub;
2549         sub = get_sub(pte->device, SUB_RING);
2550         if (!sub) {
2551             return;
2552         }
2553
2554         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
2555         return;
2556 }
2557
2558 static void *unistim_ss(void *data)
2559 {
2560         struct ast_channel *chan = data;
2561         struct unistim_subchannel *sub = ast_channel_tech_pvt(chan);
2562         struct unistim_line *l = sub->parent;
2563         struct unistimsession *s = l->parent->session;
2564         int res;
2565
2566         ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
2567         ast_channel_exten_set(chan, s->device->phone_number);
2568         ast_copy_string(s->device->redial_number, s->device->phone_number,
2569                                         sizeof(s->device->redial_number));
2570         ast_setstate(chan, AST_STATE_RING);
2571         res = ast_pbx_run(chan);
2572         if (res) {
2573                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2574                 send_tone(s, 1000, 0);
2575         }
2576         return NULL;
2577 }
2578
2579 static int find_rtp_port(struct unistim_subchannel *s)
2580 {
2581         struct unistim_subchannel *sub = NULL;
2582         int rtp_start = s->parent->parent->rtp_port;
2583         struct ast_sockaddr us_tmp;
2584         struct sockaddr_in us = { 0, };
2585
2586         AST_LIST_LOCK(&s->parent->parent->subs);
2587         AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) {
2588                 if (!sub) {
2589                         continue;
2590                 }
2591                 if (sub->rtp) {
2592                         ast_rtp_instance_get_remote_address(sub->rtp, &us_tmp);
2593                         ast_sockaddr_to_sin(&us_tmp, &us);
2594                         if (htons(us.sin_port)) {
2595                                 rtp_start = htons(us.sin_port) + 1;
2596                                 break;
2597                         }
2598                 }
2599         }
2600         AST_LIST_UNLOCK(&s->parent->parent->subs);
2601         return rtp_start;
2602 }
2603
2604 static void send_start_rtp(struct unistim_subchannel *sub)
2605 {
2606         BUFFSEND;
2607
2608         int codec;
2609         struct sockaddr_in public = { 0, };
2610         struct sockaddr_in us = { 0, };
2611         struct sockaddr_in sin = { 0, };
2612         struct ast_sockaddr us_tmp;
2613         struct ast_sockaddr sin_tmp;
2614         struct unistimsession *pte;
2615
2616         ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
2617         ast_sockaddr_to_sin(&us_tmp, &us);
2618         ast_rtp_instance_get_remote_address(sub->rtp, &sin_tmp);
2619         ast_sockaddr_to_sin(&sin_tmp, &sin);
2620
2621         /* Setting up RTP of the phone */
2622         if (public_ip.sin_family == 0) {  /* NAT IP override ?   */
2623                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2624         } else {
2625                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2626         }
2627         if (unistimdebug) {
2628                 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
2629                          ast_inet_ntoa(us.sin_addr),
2630                          htons(us.sin_port), ast_getformatname(ast_channel_readformat(sub->owner)));
2631                 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2632                                         ast_inet_ntoa(public.sin_addr));
2633         }
2634
2635         pte = sub->parent->parent->session;
2636         codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, ast_channel_readformat(sub->owner), 0);
2637         if ((ast_channel_readformat(sub->owner)->id == AST_FORMAT_ULAW) ||
2638                 (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ALAW)) {
2639                 if (unistimdebug) {
2640                         ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2641                 }
2642                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2643                            sizeof(packet_send_rtp_packet_size));
2644                 buffsend[10] = (int) codec & 0xffffffffLL;
2645                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte);
2646         }
2647         if (unistimdebug) {
2648                 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2649         }
2650         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2651                    sizeof(packet_send_jitter_buffer_conf));
2652         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte);
2653         if (pte->device->rtp_method != 0) {
2654                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2655
2656                 if (unistimdebug) {
2657                         ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method);
2658                 }
2659                 if (pte->device->rtp_method == 3) {
2660                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2661                                    sizeof(packet_send_open_audio_stream_tx3));
2662                 } else {
2663                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2664                                    sizeof(packet_send_open_audio_stream_tx));
2665                 }
2666                 if (pte->device->rtp_method != 2) {
2667                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2668                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2669                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2670                         buffsend[23] = (rtcpsin_port & 0x00ff);
2671                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2672                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2673                         buffsend[24] = (us.sin_port & 0x00ff);
2674                         buffsend[27] = (rtcpsin_port & 0x00ff);
2675                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2676                 } else {
2677                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2678                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2679                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2680                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2681                         buffsend[19] = (us.sin_port & 0x00ff);
2682                         buffsend[11] = codec;
2683                 }
2684                 buffsend[12] = codec;
2685                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend, pte);
2686
2687                 if (unistimdebug) {
2688                         ast_verb(0, "Sending OpenAudioStreamRX\n");
2689                 }
2690                 if (pte->device->rtp_method == 3) {
2691                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2692                                    sizeof(packet_send_open_audio_stream_rx3));
2693                 } else {
2694                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2695                                    sizeof(packet_send_open_audio_stream_rx));
2696                 }
2697                 if (pte->device->rtp_method != 2) {
2698                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2699                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2700                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2701                         buffsend[23] = (rtcpsin_port & 0x00ff);
2702                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2703                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2704                         buffsend[24] = (us.sin_port & 0x00ff);
2705                         buffsend[27] = (rtcpsin_port & 0x00ff);
2706                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2707                 } else {
2708                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2709                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2710                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2711                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2712                         buffsend[19] = (us.sin_port & 0x00ff);
2713                         buffsend[12] = codec;
2714                 }
2715                 buffsend[11] = codec;
2716                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend, pte);
2717         } else {
2718                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2719
2720                 if (unistimdebug) {
2721                         ast_verb(0, "Sending packet_send_call default method\n");
2722                 }
2723
2724                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2725                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2726                 /* Destination port when sending RTP */
2727                 buffsend[49] = (us.sin_port & 0x00ff);
2728                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2729                 /* Destination port when sending RTCP */
2730                 buffsend[52] = (rtcpsin_port & 0x00ff);
2731                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2732                 /* Codec */
2733                 buffsend[40] = codec;
2734                 buffsend[41] = codec;
2735                 if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ULAW) {
2736                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2737                 } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ALAW) {
2738                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2739                 } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_G723_1) {
2740                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2741                 } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_G729A) {
2742                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2743                 } else {
2744                         ast_log(LOG_WARNING, "Unsupported codec %s!\n",
2745                                         ast_getformatname(ast_channel_readformat(sub->owner)));
2746                 }
2747                 /* Source port for transmit RTP and Destination port for receiving RTP */
2748                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2749                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2750                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2751                 buffsend[48] = (rtcpsin_port & 0x00ff);
2752                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte);
2753         }
2754 }
2755
2756 static void start_rtp(struct unistim_subchannel *sub)
2757 {
2758         struct sockaddr_in sin = { 0, };
2759         struct sockaddr_in sout = { 0, };
2760         struct ast_sockaddr sin_tmp;
2761         struct ast_sockaddr sout_tmp;
2762
2763         /* Sanity checks */
2764         if (!sub) {
2765                 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2766                 return;
2767         }
2768         if (!sub->parent) {
2769                 ast_log(LOG_WARNING, "start_rtp with a null line!\n");
2770                 return;
2771         }
2772         if (!sub->parent->parent) {
2773                 ast_log(LOG_WARNING, "start_rtp with a null device!\n");
2774                 return;
2775         }
2776         if (!sub->parent->parent->session) {
2777                 ast_log(LOG_WARNING, "start_rtp with a null session!\n");
2778                 return;
2779         }
2780         if (!sub->owner) {
2781                 ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n");
2782                 return;
2783         }
2784         sout = sub->parent->parent->session->sout;
2785         ast_mutex_lock(&sub->lock);
2786         /* Allocate the RTP */
2787         if (unistimdebug) {
2788                 ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2789         }
2790         ast_sockaddr_from_sin(&sout_tmp, &sout);
2791         sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
2792         if (!sub->rtp) {
2793                 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2794                                 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2795                 ast_mutex_unlock(&sub->lock);
2796                 return;
2797         }
2798         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
2799         ast_channel_internal_fd_set(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
2800         ast_channel_internal_fd_set(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
2801         ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2802         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
2803
2804         /* Create the RTP connection */
2805         sin.sin_family = AF_INET;
2806         /* Setting up RTP for our side */
2807         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2808                    sizeof(sin.sin_addr));
2809
2810         sin.sin_port = htons(find_rtp_port(sub));
2811         ast_sockaddr_from_sin(&sin_tmp, &sin);
2812         ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
2813         if (!ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), ast_channel_readformat(sub->owner))) {
2814                 struct ast_format tmpfmt;
2815                 char tmp[256];
2816                 ast_best_codec(ast_channel_nativeformats(sub->owner), &tmpfmt);
2817                 ast_log(LOG_WARNING,
2818                                 "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
2819                                 ast_getformatname(ast_channel_readformat(sub->owner)),
2820                                 ast_getformatname(&tmpfmt),
2821                                 ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(sub->owner)));
2822
2823                 ast_format_copy(ast_channel_readformat(sub->owner), &tmpfmt);
2824                 ast_format_copy(ast_channel_writeformat(sub->owner), &tmpfmt);
2825         }
2826         send_start_rtp(sub);
2827         ast_mutex_unlock(&sub->lock);
2828 }
2829
2830 static void send_dial_tone(struct unistimsession *pte)
2831 {
2832         struct ast_tone_zone_sound *ts = NULL;
2833         struct ast_tone_zone_part tone_data;
2834         char *s = NULL;
2835         char *ind;
2836
2837         if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) {
2838                 ind = ast_strdupa(ts->data);
2839                 s = strsep(&ind, ",");
2840                 ast_tone_zone_part_parse(s, &tone_data);
2841                 if (tone_data.modulate) {
2842                         tone_data.freq2 = 0;
2843                 }
2844                 send_tone(pte, tone_data.freq1, tone_data.freq2);
2845                 if (unistimdebug) {
2846                         ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
2847                                                         pte->device->tz->country, tone_data.freq1, tone_data.freq2);
2848                 }
2849                 ts = ast_tone_zone_sound_unref(ts);
2850         }
2851 }
2852
2853 static void show_phone_number(struct unistimsession *pte)
2854 {
2855         char tmp[TEXT_LENGTH_MAX + 1];
2856         const char *tmp_number = ustmtext("Number:", pte);
2857         int line, tmp_copy, offset = 0, i;
2858
2859         pte->device->phone_number[pte->device->size_phone_number] = '\0';
2860         if  (pte->device->size_phone_number > MAX_SCREEN_NUMBER) {
2861                 offset = pte->device->size_phone_number - MAX_SCREEN_NUMBER - 1;
2862                 if (offset > strlen(tmp_number)) {
2863                         offset = strlen(tmp_number);
2864                 }
2865                 tmp_copy = strlen(tmp_number) - offset + 1;
2866                 if (tmp_copy > sizeof(tmp)) {
2867                         tmp_copy = sizeof(tmp);
2868                 }
2869                 memcpy(tmp, tmp_number + offset, tmp_copy);
2870         } else {
2871                 ast_copy_string(tmp, tmp_number, sizeof(tmp));
2872         }
2873
2874         offset = (pte->device->size_phone_number >= TEXT_LENGTH_MAX) ? (pte->device->size_phone_number - TEXT_LENGTH_MAX +1) : 0;
2875         if (pte->device->size_phone_number) {
2876                 memcpy(tmp + strlen(tmp), pte->device->phone_number + offset, pte->device->size_phone_number - offset + 1);
2877         }
2878         offset = strlen(tmp);
2879
2880         for (i = strlen(tmp); i < TEXT_LENGTH_MAX; i++) {
2881                 tmp[i] = '.';
2882         }
2883         tmp[i] = '\0';
2884
2885         line = (pte->device->height == 1) ? TEXT_LINE0 : TEXT_LINE2;
2886         send_text(line, TEXT_NORMAL, pte, tmp);
2887         send_blink_cursor(pte);
2888         send_cursor_pos(pte, (unsigned char) (line + offset));
2889         send_led_update(pte, 0);
2890 }
2891
2892 static void handle_dial_page(struct unistimsession *pte)
2893 {
2894         pte->state = STATE_DIALPAGE;
2895         if (pte->device->call_forward[0] == -1) {
2896                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2897                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte));
2898                 send_text_status(pte, ustmtext("Fwd    Cancel BackSp Erase", pte));
2899                 if (pte->device->call_forward[1] != 0) {
2900                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2901                                                         sizeof(pte->device->phone_number));
2902                         show_phone_number(pte);
2903                         send_led_update(pte, 0);
2904                         return;
2905                 }
2906         } else {
2907                 if ((pte->device->output == OUTPUT_HANDSET) &&
2908                         (pte->device->receiver_state == STATE_ONHOOK)) {
2909                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2910                 } else {
2911                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2912                 }
2913                 send_dial_tone(pte);
2914
2915                 if (pte->device->height > 1) {
2916                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte));
2917                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte));
2918                 }
2919                 send_text_status(pte, ustmtext("Call   Redial BackSp Erase", pte));
2920         }
2921
2922         pte->device->size_phone_number = 0;
2923         pte->device->phone_number[0] = 0;
2924         show_phone_number(pte);
2925         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
2926         send_icon(TEXT_LINE0, FAV_ICON_NONE, pte);
2927         pte->device->missed_call = 0;
2928         send_led_update(pte, 0);
2929         return;
2930 }
2931
2932 static void swap_subs(struct unistim_subchannel *a, struct unistim_subchannel *b)
2933 {
2934         struct ast_rtp_instance *rtp;
2935         int fds;
2936
2937         if (unistimdebug) {
2938                 ast_verb(0, "Swapping %p and %p\n", a, b);
2939         }
2940         if ((!a->owner) || (!b->owner)) {
2941                 ast_log(LOG_WARNING,
2942                                 "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n",
2943                                 a, a->owner, b, b->owner);
2944                 return;
2945         }
2946         rtp = a->rtp;
2947         a->rtp = b->rtp;
2948         b->rtp = rtp;
2949
2950         fds = ast_channel_fd(a->owner, 0);
2951         ast_channel_internal_fd_set(a->owner, 0, ast_channel_fd(b->owner, 0));
2952         ast_channel_internal_fd_set(b->owner, 0, fds);
2953
2954         fds = ast_channel_fd(a->owner, 1);
2955         ast_channel_internal_fd_set(a->owner, 1, ast_channel_fd(b->owner, 1));
2956         ast_channel_internal_fd_set(b->owner, 1, fds);
2957 }
2958
2959 /* Step 1 : Music On Hold for peer, Dialing screen for us */
2960 static void transfer_call_step1(struct unistimsession *pte)
2961 {
2962         struct unistim_subchannel *sub /*, *sub_trans */;
2963         struct unistim_device *d = pte->device;
2964
2965         sub = get_sub(d, SUB_REAL);
2966         /* sub_trans = get_sub(d, SUB_THREEWAY); */
2967
2968         if (!sub || !sub->owner) {
2969                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2970                 return;
2971         }
2972         /* Start music on hold if appropriate */
2973         if (sub->moh) {
2974                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
2975         } else {
2976                 if (ast_bridged_channel(sub->owner)) {
2977                         ast_moh_start(ast_bridged_channel(sub->owner),
2978                                                   sub->parent->musicclass, NULL);
2979                         sub->moh = 1;
2980                         sub->subtype = SUB_THREEWAY;
2981                 } else {
2982                         ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
2983                         return;
2984                 }
2985         }
2986         sub_start_silence(pte, sub);
2987         handle_dial_page(pte);
2988 }
2989
2990 static void transfer_cancel_step2(struct unistimsession *pte)
2991 {
2992         struct unistim_subchannel *sub, *sub_trans;
2993         struct unistim_device *d = pte->device;
2994
2995         sub = get_sub(d, SUB_REAL);
2996         sub_trans = get_sub(d, SUB_THREEWAY);
2997
2998         if (!sub || !sub->owner) {
2999                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3000                 return;
3001         }
3002         if (sub_trans) {
3003                 if (unistimdebug) {
3004                         ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
3005                 }
3006                 if (sub->owner) {
3007                         swap_subs(sub, sub_trans);
3008                         ast_moh_stop(ast_bridged_channel(sub_trans->owner));
3009                         sub_trans->moh = 0;
3010                         sub_trans->subtype = SUB_REAL;
3011                         sub->subtype = SUB_THREEWAY;
3012                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
3013                 } else {
3014                         ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
3015                 }
3016                 return;
3017         }
3018 }
3019
3020 /* From phone to PBX */
3021 static void handle_call_outgoing(struct unistimsession *s)
3022 {
3023         struct ast_channel *c;
3024         struct unistim_subchannel *sub;
3025         int softkey;
3026
3027         s->state = STATE_CALL;
3028
3029         sub = get_sub(s->device, SUB_THREEWAY);
3030         if (sub) {
3031                 /* If sub for threway call created than we use transfer behaviuor */
3032                 struct unistim_subchannel *sub_trans = NULL;
3033                 struct unistim_device *d = s->device;
3034
3035                 sub_trans = get_sub(d, SUB_REAL);
3036                 if (sub_trans) {
3037                         ast_log(LOG_WARNING, "Can't transfer while active subchannel exists!\n");
3038                         return;
3039                 }
3040                 if (!sub->owner) {
3041                         ast_log(LOG_WARNING, "Unable to find subchannel with music on hold\n");
3042                         return;
3043                 }
3044
3045                 sub_trans = unistim_alloc_sub(d, SUB_REAL);
3046                 if (!sub_trans) {
3047                         ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
3048                         return;
3049                 }
3050                 sub_trans->parent = sub->parent;
3051                 sub_stop_silence(s, sub);
3052                 send_tone(s, 0, 0);
3053                 /* Make new channel */
3054                 c = unistim_new(sub_trans, AST_STATE_DOWN, NULL);
3055                 if (!c) {
3056                         ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", sub->parent);
3057                         return;
3058                 }
3059                 /* Swap things around between the three-way and real call */
3060                 swap_subs(sub, sub_trans);
3061                 send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
3062                 if (s->device->height == 1) {
3063                         send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
3064                 } else {
3065                         send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling (pre-transfer)", s));
3066                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
3067                         send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
3068                 }
3069                 send_text_status(s, ustmtext("TransfrCancel", s));
3070
3071                 if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
3072                         ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", c);
3073                         sub->ss_thread = AST_PTHREADT_NULL;
3074                         ast_hangup(c);
3075                         return;
3076                 }
3077                 if (unistimdebug) {
3078                         ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n",
3079                                  sub_trans->owner, ast_channel_name(sub_trans->owner), sub_trans->subtype);
3080                 }
3081                 return;
3082         }
3083
3084         softkey = get_avail_softkey(s, NULL);
3085         if (softkey == -1) {
3086                 ast_log(LOG_WARNING, "Have no avail softkey for calling\n");
3087                 return;
3088         }
3089         sub = get_sub(s->device, SUB_REAL);
3090         if (sub) { /* have already call assigned */
3091                 sub_hold(s, sub); /* Need to put on hold */
3092         }
3093         if (!(sub = unistim_alloc_sub(s->device, SUB_REAL))) {
3094                 ast_log(LOG_WARNING, "Unable to allocate subchannel!\n");
3095                 return;     
3096         }
3097         sub->parent = s->device->sline[softkey];
3098         s->device->ssub[softkey] = sub;
3099         sub->softkey = softkey;
3100
3101         if (unistimdebug) {
3102                 ast_verb(0, "Using softkey %d, line %p\n", sub->softkey, sub->parent);
3103         }
3104         send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s);
3105         s->device->selected = -1;
3106         if (!sub->owner) {                    /* A call is already in progress ? */
3107                 c = unistim_new(sub, AST_STATE_DOWN, NULL);   /* No, starting a new one */
3108                 if (!sub->rtp) { /* Need to start RTP before calling ast_pbx_run */
3109                         start_rtp(sub);
3110                 }
3111                 if (c && !strcmp(s->device->phone_number, ast_pickup_ext())) {
3112                         if (unistimdebug) {
3113                                 ast_verb(0, "Try to pickup in unistim_new\n");
3114                         }
3115                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "");
3116                         send_text_status(s, ustmtext("       Transf        Hangup", s));
3117                         send_start_timer(s);
3118                         if (ast_pickup_call(c)) {
3119                                 ast_log(LOG_NOTICE, "Nothing to pick up\n");
3120                                 ast_channel_hangupcause_set(c, AST_CAUSE_CALL_REJECTED);
3121                         } else {
3122                                 ast_channel_hangupcause_set(c, AST_CAUSE_NORMAL_CLEARING);
3123                         }
3124                         ast_hangup(c);
3125                         c = NULL;
3126                 } else if (c) {
3127                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
3128                         send_tone(s, 0, 0); /* Dialing empty number should also stop dial tone */
3129                         if (s->device->height == 1) {
3130                                 if (strlen(s->device->phone_number) > 0) {
3131                                         send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
3132                                 } else {
3133                                         send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling...", s));
3134                                 }
3135                         } else {
3136                                 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling :", s));
3137                                 send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
3138                                 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
3139                         }
3140                         send_text_status(s, ustmtext("                     Hangup", s));
3141
3142                         /* start switch */
3143                         if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
3144                                 ast_log(LOG_WARNING, "Unable to create switch thread\n");
3145                                 sub->ss_thread = AST_PTHREADT_NULL;
3146                                 ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
3147                         }
3148                 } else
3149                         ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
3150                                         sub->parent->name, s->device->name);
3151         } else {
3152                 ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
3153         }
3154         return;
3155 }
3156
3157 /* From PBX to phone */
3158 static void handle_call_incoming(struct unistimsession *s)
3159 {
3160         struct unistim_subchannel *sub = NULL;
3161         int i;
3162
3163         s->state = STATE_CALL;
3164         s->device->missed_call = 0;
3165         send_no_ring(s);
3166         sub = get_sub(s->device, SUB_RING); /* Put other SUB_REAL call on hold */
3167         if (!sub) {
3168                 ast_log(LOG_WARNING, "No ringing lines on: %s\n", s->device->name);
3169                 return;
3170         }
3171         /* Change icons for all ringing keys */
3172         for (i = 0; i < FAVNUM; i++) {
3173                 if (!s->device->ssub[i]) { /* No sub assigned - skip */
3174                         continue;
3175                 }
3176                 if (s->device->ssub[i]->subtype == SUB_REAL) {
3177                         sub_hold(s, s->device->ssub[i]);
3178                 }
3179                 if (s->device->ssub[i] != sub) {
3180                         continue;
3181                 }
3182                 if (sub->softkey == i) { /* If softkey assigned at this moment - do not erase */
3183                         continue;
3184                 }
3185                 if (sub->softkey < 0) { /* If softkey not defined - first one used */
3186                         sub->softkey = i;
3187                         continue;
3188                 }
3189                 send_favorite_short(i, FAV_LINE_ICON, s);
3190                 s->device->ssub[i] = NULL;
3191         }
3192         if (sub->softkey < 0) {
3193                 ast_log(LOG_WARNING, "Can not assign softkey for incoming call on: %s\n", s->device->name);
3194                 return;
3195         }
3196         send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s);
3197         sub->parent = s->device->sline[sub->softkey];
3198         sub->subtype = SUB_REAL;
3199         if (unistimdebug) {
3200                 ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
3201                                         s->device->name);
3202         }
3203         start_rtp(sub);
3204         if (!sub->rtp) {
3205                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
3206                                 s->device->name);
3207         }
3208         if (sub->owner) {
3209                 ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
3210         }
3211         send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
3212         send_text_status(s, ustmtext("       Transf        Hangup", s));
3213         send_start_timer(s);
3214
3215         if ((s->device->output == OUTPUT_HANDSET) &&
3216                 (s->device->receiver_state == STATE_ONHOOK)) {
3217                 send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
3218         } else {
3219                 send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
3220         }
3221         write_history(s, 'i', 0);
3222         return;
3223 }
3224
3225 static int unistim_do_senddigit(struct unistimsession *pte, char digit)
3226 {
3227         struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
3228         struct unistim_subchannel *sub;
3229         int row, col;
3230
3231         sub = get_sub(pte->device, SUB_REAL);
3232         if (!sub || !sub->owner || sub->alreadygone) {
3233                 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
3234                 return -1;
3235         }
3236
3237         /* Send DTMF indication _before_ playing sounds */
3238         ast_queue_frame(sub->owner, &f);
3239
3240         if (unistimdebug) {
3241                 ast_verb(0, "Send Digit %c\n", digit);
3242         }
3243         row = (digit - '1') % 3;
3244         col = (digit - '1' - row) / 3;
3245         if (digit >= '1' && digit <='9') {
3246                 send_tone(pte, dtmf_row[row], dtmf_col[col]);
3247         } else if (digit >= 'A' && digit <= 'D') {
3248                 send_tone(pte, dtmf_row[digit-'A'], dtmf_col[3]);
3249         } else if (digit == '*') {
3250                 send_tone(pte, dtmf_row[3], dtmf_col[0]);
3251         } else if (digit == '0') {
3252                 send_tone(pte, dtmf_row[3], dtmf_col[1]);
3253         } else if (digit == '#') {
3254                 send_tone(pte, dtmf_row[3], dtmf_col[2]);
3255         } else {
3256                 send_tone(pte, 500, 2000);
3257         }
3258         usleep(150000);                  /* XXX Less than perfect, blocking an important thread is not a good idea */
3259         send_tone(pte, 0, 0);
3260         return 0;
3261 }
3262
3263 static void handle_key_fav(struct unistimsession *pte, char keycode)
3264 {
3265         int keynum = keycode - KEY_FAV0;
3266         struct unistim_subchannel *sub;
3267
3268         sub = get_sub(pte->device, SUB_REAL);
3269
3270         /* Make an action on selected favorite key */
3271         if (!pte->device->ssub[keynum]) { /* Key have no assigned call */
3272                 send_favorite_selected(FAV_LINE_ICON, pte);
3273                 if (is_key_line(pte->device, keynum)) {
3274                         if (unistimdebug) {
3275                                 ast_verb(0, "Handle line w/o sub - dialpage\n");
3276                         }
3277                         pte->device->selected = keynum;
3278                         sub_hold(pte, sub); /* Put active call on hold */
3279                         send_stop_timer(pte);
3280                         handle_dial_page(pte);
3281                 } else if (is_key_favorite(pte->device, keynum)) {
3282                         /* Put active call on hold in handle_call_outgoing function, after preparation and
3283                          checking if lines available for calling */
3284                         if (unistimdebug) {
3285                                 ast_verb(0, "Handle favorite w/o sub - dialing\n");
3286                         }
3287                         if ((pte->device->output == OUTPUT_HANDSET) &&
3288                                 (pte->device->receiver_state == STATE_ONHOOK)) {
3289                                 send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3290                         } else {
3291                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3292                         }
3293                         key_favorite(pte, keycode);
3294                 }
3295         } else {
3296                 sub = pte->device->ssub[keynum];
3297                 /* Favicon have assigned sub, activate it and put current on hold */
3298                 if (sub->subtype == SUB_REAL) {
3299                         sub_hold(pte, sub);
3300                         show_main_page(pte);
3301                 } else if (sub->subtype == SUB_RING) {
3302                         sub->softkey = keynum;
3303                         handle_call_incoming(pte);
3304                 } else if (sub->subtype == SUB_ONHOLD) {
3305                         if (pte->state == STATE_DIALPAGE){
3306                                 send_tone(pte, 0, 0);
3307                         }
3308                         send_callerid_screen(pte, sub);
3309                         sub_unhold(pte, sub);
3310                         pte->state = STATE_CALL;
3311                 }
3312         }
3313 }
3314
3315 static void key_call(struct unistimsession *pte, char keycode)
3316 {
3317         struct unistim_subchannel *sub = NULL;
3318         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3319                 if (keycode == KEY_SHARP) {
3320                         keycode = '#';
3321                 } else if (keycode == KEY_STAR) {
3322                         keycode = '*';
3323                 } else {
3324                         keycode -= 0x10;
3325                 }
3326                 unistim_do_senddigit(pte, keycode);
3327                 return;
3328         }
3329         switch (keycode) {
3330         case KEY_FUNC1:
3331                 if (get_sub(pte->device, SUB_THREEWAY)) {
3332                         close_call(pte);
3333                 }
3334                 break;
3335         case KEY_FUNC2:
3336                 if (get_sub(pte->device, SUB_THREEWAY)) {
3337                         transfer_cancel_step2(pte);
3338                 } else {
3339                         transfer_call_step1(pte);
3340                 }
3341                 break;
3342         case KEY_HANGUP:
3343         case KEY_FUNC4:
3344                 if (!get_sub(pte->device, SUB_THREEWAY)) {
3345                         close_call(pte);
3346                 }
3347                 break;
3348         case KEY_FAV0:
3349         case KEY_FAV1:
3350         case KEY_FAV2:
3351         case KEY_FAV3:
3352         case KEY_FAV4:
3353         case KEY_FAV5:
3354                 handle_key_fav(pte, keycode);
3355                 break;
3356         case KEY_HEADPHN:
3357                 if (pte->device->output == OUTPUT_HEADPHONE) {
3358                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
3359                 } else {
3360                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
3361                 }
3362                 break;
3363         case KEY_LOUDSPK:
3364                 if (pte->device->output != OUTPUT_SPEAKER)
3365                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3366                 else
3367                         send_select_output(pte, pte->device->previous_output, pte->device->volume,
3368                                                          MUTE_OFF);
3369                 break;
3370         case KEY_MUTE:
3371                 sub = get_sub(pte->device, SUB_REAL);
3372                 if (!sub || !sub->owner) {
3373                         ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3374                         return;
3375                 }
3376                 if (!sub->moh) {
3377                         if (pte->device->mute == MUTE_ON) {
3378                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3379                         } else {
3380                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
3381                         }
3382                         break;
3383                 }
3384                 break;
3385         case KEY_ONHOLD:
3386                 sub = get_sub(pte->device, SUB_REAL);
3387                 if (!sub) {
3388                         if(pte->device->ssub[pte->device->selected]) {
3389                                 sub_hold(pte, pte->device->ssub[pte->device->selected]);
3390                         }
3391                 } else {
3392                         sub_hold(pte, sub);
3393                 }
3394                 break;
3395         }
3396         return;
3397 }
3398
3399 static void key_ringing(struct unistimsession *pte, char keycode)
3400 {
3401         switch (keycode) {
3402         case KEY_FAV0:
3403         case KEY_FAV1:
3404         case KEY_FAV2:
3405         case KEY_FAV3:
3406         case KEY_FAV4:
3407         case KEY_FAV5:
3408                 handle_key_fav(pte, keycode);
3409                 break;
3410         case KEY_FUNC3:
3411                 ignore_call(pte);
3412                 break;
3413         case KEY_HANGUP:
3414         case KEY_FUNC4:
3415                 discard_call(pte);
3416                 break;
3417         case KEY_LOUDSPK:
3418                 pte->device->output = OUTPUT_SPEAKER;
3419                 handle_call_incoming(pte);
3420                 break;
3421         case KEY_HEADPHN:
3422                 pte->device->output = OUTPUT_HEADPHONE;
3423                 handle_call_incoming(pte);
3424                 break;
3425         case KEY_FUNC1:
3426                 handle_call_incoming(pte);
3427                 break;
3428         }
3429         return;
3430 }
3431
3432 static void key_favorite(struct unistimsession *pte, char keycode)
3433 {
3434         int fav = keycode - KEY_FAV0;
3435         if (!is_key_favorite(pte->device, fav)) {
3436                 ast_log(LOG_WARNING, "It's not a favorite key\n");
3437                 return;
3438         }
3439         ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
3440                                         sizeof(pte->device->phone_number));
3441         handle_call_outgoing(pte);
3442         return;
3443 }
3444
3445 static void key_dial_page(struct unistimsession *pte, char keycode)
3446 {
3447         struct unistim_subchannel *sub = get_sub(pte->device, SUB_THREEWAY);
3448
3449         pte->device->nextdial = 0;
3450         if (keycode == KEY_FUNC3) {
3451                 if (pte->device->size_phone_number <= 1) {
3452                         keycode = KEY_FUNC4;
3453                 } else {
3454                         pte->device->size_phone_number -= 2;
3455                         keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
3456                 }
3457         }
3458         if (keycode == KEY_SHARP && pte->device->sharp_dial == 1) {
3459                 keycode = KEY_FUNC1;
3460         }
3461         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3462                 int i = pte->device->size_phone_number;
3463
3464                 if (pte->device->size_phone_number == 0) {
3465                         send_tone(pte, 0, 0);
3466                 }
3467                 if (keycode == KEY_SHARP) {
3468                         keycode = '#';
3469                 } else if (keycode == KEY_STAR) {
3470                         keycode = '*';
3471                 } else {
3472                         keycode -= 0x10;
3473                 }
3474                 pte->device->phone_number[i] = keycode;
3475                 pte->device->size_phone_number++;
3476                 pte->device->phone_number[i + 1] = 0;
3477                 show_phone_number(pte);
3478
3479                 if (ast_exists_extension(NULL, pte->device->context, pte->device->phone_number, 1, NULL) && 
3480                         !ast_matchmore_extension(NULL, pte->device->context, pte->device->phone_number, 1, NULL)) {
3481                     keycode = KEY_FUNC1;
3482                 } else {
3483                     pte->device->nextdial = get_tick_count() + TIMER_DIAL;
3484                 }
3485         }
3486         if (keycode == KEY_FUNC4) {
3487                 pte->device->size_phone_number = 0;
3488                 show_phone_number(pte);
3489                 return;
3490         }
3491
3492         if (pte->device->call_forward[0] == -1) {
3493                 if (keycode == KEY_FUNC1) {
3494                         ast_copy_string(pte->device->call_forward, pte->device->phone_number,
3495                                                         sizeof(pte->device->call_forward));
3496                         show_main_page(pte);
3497                 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
3498                         pte->device->call_forward[0] = '\0';
3499                         send_led_update(pte, 0x08);
3500                         send_led_update(pte, 0x10);
3501                         show_main_page(pte);
3502                 }
3503                 return;
3504         }
3505         switch (keycode) {
3506         case KEY_FUNC2:
3507                 if (ast_strlen_zero(pte->device->redial_number)) {
3508                         break;
3509                 }
3510                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
3511                                                 sizeof(pte->device->phone_number));
3512         case KEY_FUNC1:
3513                 handle_call_outgoing(pte);
3514                 break;
3515         case KEY_HANGUP:
3516                 if (sub && sub->owner) {
3517                         struct ast_channel *bridgepeer = NULL;
3518
3519                         sub_stop_silence(pte, sub);
3520                         send_tone(pte, 0, 0);
3521                         if ((bridgepeer = ast_bridged_channel(sub->owner))) {
3522                                 ast_moh_stop(bridgepeer);
3523                         }
3524                         sub->moh = 0;
3525                         sub->subtype = SUB_REAL;
3526                         pte->state = STATE_CALL;
3527
3528                         send_text_status(pte, ustmtext("       Transf        Hangup", pte));
3529                         send_callerid_screen(pte, sub);