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