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