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