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