stasic.c: Fix printf format type mismatches with arguments.
[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__) || defined(__NetBSD__)
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__ || __NetBSD__ */
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
118 struct ast_format_cap *global_cap;
119
120 enum autoprovision {
121         AUTOPROVISIONING_NO = 0,
122         AUTOPROVISIONING_YES,
123         AUTOPROVISIONING_TN
124 };
125
126 enum autoprov_extn {
127         /*! Do not create an extension into the default dialplan */
128         EXTENSION_NONE = 0,
129         /*! Prompt user for an extension number and register it */
130         EXTENSION_ASK,
131         /*! Register an extension with the line=> value */
132         EXTENSION_LINE,
133         /*! Used with AUTOPROVISIONING_TN */
134         EXTENSION_TN
135 };
136 #define OUTPUT_HANDSET    0xC0
137 #define OUTPUT_HEADPHONE        0xC1
138 #define OUTPUT_SPEAKER    0xC2
139
140 #define VOLUME_LOW            0x01
141 #define VOLUME_LOW_SPEAKER      0x03
142 #define VOLUME_NORMAL      0x02
143 #define VOLUME_INSANELY_LOUD    0x07
144
145 #define MUTE_OFF                0x00
146 #define MUTE_ON          0xFF
147 #define MUTE_ON_DISCRET  0xCE
148
149 #define LED_BAR_OFF                     0x00 /* bar off */
150 #define LED_BAR_ON                      0x01 /* bar on */
151 #define LED_BAR_P2                      0x02 /* bar 1s on/1s */
152 #define LED_BAR_P3                      0x03 /* bar 2.5s on/0.5s off */
153 #define LED_BAR_P4                      0x04 /* bar 0.6s on/0.3s off */
154 #define LED_BAR_P5                      0x05 /* bar 0.5s on/0.5s off */
155 #define LED_BAR_P6                      0x06 /* bar 2s on/0.5s off */
156 #define LED_BAR_P7                      0x07 /* bar off */
157 #define LED_SPEAKER_OFF                 0x08
158 #define LED_SPEAKER_ON                  0x09
159 #define LED_HEADPHONE_OFF               0x010
160 #define LED_HEADPHONE_ON                0x011
161 #define LED_MUTE_OFF                    0x018
162 #define LED_MUTE_ON                     0x019
163 #define LED_MUTE_BLINK                  0x1A
164
165 #define SIZE_HEADER          6
166 #define SIZE_MAC_ADDR      17
167 #define TEXT_LENGTH_MAX  24
168 #define TEXT_LINE0            0x00
169 #define TEXT_LINE1            0x20
170 #define TEXT_LINE2            0x40
171 #define TEXT_NORMAL          0x05
172 #define TEXT_INVERSE        0x25
173 #define STATUS_LENGTH_MAX       28
174
175 #define FAV_ICON_NONE              0x00
176 #define FAV_ICON_ONHOOK_BLACK      0x20
177 #define FAV_ICON_ONHOOK_WHITE      0x21
178 #define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22
179 #define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23
180 #define FAV_ICON_OFFHOOK_BLACK    0x24
181 #define FAV_ICON_OFFHOOK_WHITE    0x25
182 #define FAV_ICON_ONHOLD_BLACK      0x26
183 #define FAV_ICON_ONHOLD_WHITE      0x27
184 #define FAV_ICON_SPEAKER_OFFHOOK_BLACK  0x28
185 #define FAV_ICON_SPEAKER_OFFHOOK_WHITE  0x29
186 #define FAV_ICON_PHONE_BLACK        0x2A
187 #define FAV_ICON_PHONE_WHITE        0x2B
188 #define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C
189 #define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D
190 #define FAV_ICON_HEADPHONES          0x2E
191 #define FAV_ICON_HEADPHONES_ONHOLD      0x2F
192 #define FAV_ICON_HOME              0x30
193 #define FAV_ICON_CITY              0x31
194 #define FAV_ICON_SHARP            0x32
195 #define FAV_ICON_PAGER            0x33
196 #define FAV_ICON_CALL_CENTER        0x34
197 #define FAV_ICON_FAX                0x35
198 #define FAV_ICON_MAILBOX                0x36
199 #define FAV_ICON_REFLECT                0x37
200 #define FAV_ICON_COMPUTER              0x38
201 #define FAV_ICON_FORWARD                0x39
202 #define FAV_ICON_LOCKED          0x3A
203 #define FAV_ICON_TRASH            0x3B
204 #define FAV_ICON_INBOX            0x3C
205 #define FAV_ICON_OUTBOX          0x3D
206 #define FAV_ICON_MEETING                0x3E
207 #define FAV_ICON_BOX                0x3F
208
209 #define FAV_BLINK_FAST            0x20
210 #define FAV_BLINK_SLOW            0x40
211
212 #define FAV_MAX_LENGTH            0x0A
213
214 #define FAVNUM                    6
215 #define EXPNUM                    24
216 #define FAV_LINE_ICON         FAV_ICON_ONHOOK_BLACK
217
218 static void dummy(char *unused, ...)
219 {
220         return;
221 }
222
223 /*! \brief Global jitterbuffer configuration - by default, jb is disabled
224  *  \note Values shown here match the defaults shown in unistim.conf.sample */
225 static struct ast_jb_conf default_jbconf =
226 {
227         .flags = 0,
228         .max_size = 200,
229         .resync_threshold = 1000,
230         .impl = "fixed",
231         .target_extra = 40,
232 };
233 static struct ast_jb_conf global_jbconf;
234
235
236 /* #define DUMP_PACKET 1 */
237 /* #define DEBUG_TIMER ast_verbose */
238
239 #define DEBUG_TIMER dummy
240 /*! Enable verbose output. can also be set with the CLI */
241 static int unistimdebug = 0;
242 static int unistim_port;
243 static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO;
244 static int unistim_keepalive;
245 static int unistimsock = -1;
246
247 static struct {
248         unsigned int tos;
249         unsigned int tos_audio;
250         unsigned int cos;
251         unsigned int cos_audio;
252 } qos = { 0, 0, 0, 0 };
253
254 static struct io_context *io;
255 static struct ast_sched_context *sched;
256 static struct sockaddr_in public_ip = { 0, };
257 static unsigned char *buff; /*! Receive buffer address */
258 static int unistim_reloading = 0;
259 AST_MUTEX_DEFINE_STATIC(unistim_reload_lock);
260
261 /*! This is the thread for the monitor which checks for input on the channels
262  * which are not currently in use.  */
263 static pthread_t monitor_thread = AST_PTHREADT_NULL;
264
265 /*! Protect the monitoring thread, so only one process can kill or start it, and not
266  *    when it's doing something critical. */
267 AST_MUTEX_DEFINE_STATIC(monlock);
268 /*! Protect the session list */
269 AST_MUTEX_DEFINE_STATIC(sessionlock);
270 /*! Protect the device list */
271 AST_MUTEX_DEFINE_STATIC(devicelock);
272
273 enum phone_state {
274         STATE_INIT,
275         STATE_AUTHDENY,
276         STATE_MAINPAGE,
277         STATE_EXTENSION,
278         STATE_DIALPAGE,
279         STATE_RINGING,
280         STATE_CALL,
281         STATE_SELECTOPTION,
282         STATE_SELECTCODEC,
283         STATE_SELECTLANGUAGE,
284         STATE_CLEANING,
285         STATE_HISTORY
286 };
287
288 enum handset_state {
289         STATE_ONHOOK,
290         STATE_OFFHOOK,
291 };
292
293 enum phone_key {
294         KEY_0 = 0x40,
295         KEY_1 = 0x41,
296         KEY_2 = 0x42,
297         KEY_3 = 0x43,
298         KEY_4 = 0x44,
299         KEY_5 = 0x45,
300         KEY_6 = 0x46,
301         KEY_7 = 0x47,
302         KEY_8 = 0x48,
303         KEY_9 = 0x49,
304         KEY_STAR = 0x4a,
305         KEY_SHARP = 0x4b,
306         KEY_UP = 0x4c,
307         KEY_DOWN = 0x4d,
308         KEY_RIGHT = 0x4e,
309         KEY_LEFT = 0x4f,
310         KEY_QUIT = 0x50,
311         KEY_COPY = 0x51,
312         KEY_FUNC1 = 0x54,
313         KEY_FUNC2 = 0x55,
314         KEY_FUNC3 = 0x56,
315         KEY_FUNC4 = 0x57,
316         KEY_ONHOLD = 0x5b,
317         KEY_HANGUP = 0x5c,
318         KEY_MUTE = 0x5d,
319         KEY_HEADPHN = 0x5e,
320         KEY_LOUDSPK = 0x5f,
321         KEY_FAV0 = 0x60,
322         KEY_FAV1 = 0x61,
323         KEY_FAV2 = 0x62,
324         KEY_FAV3 = 0x63,
325         KEY_FAV4 = 0x64,
326         KEY_FAV5 = 0x65,
327         KEY_COMPUTR = 0x7b,
328         KEY_CONF = 0x7c,
329         KEY_SNDHIST = 0x7d,
330         KEY_RCVHIST = 0x7e,
331         KEY_INDEX = 0x7f
332 };
333
334 enum charset {
335         LANG_DEFAULT,
336         ISO_8859_1,
337         ISO_8859_2,
338         ISO_8859_4,
339         ISO_8859_5,
340         ISO_2022_JP,
341 };
342
343 static const int dtmf_row[] = { 697,  770,  852,  941 };
344 static const float dtmf_col[] = { 1209, 1336, 1477, 1633 };
345
346 struct wsabuf {
347         u_long len;
348         unsigned char *buf;
349 };
350
351 struct unistim_subchannel {
352         ast_mutex_t lock;
353         unsigned int subtype;           /*! SUB_REAL, SUB_RING or SUB_THREEWAY */
354         struct ast_channel *owner;      /*! Asterisk channel used by the subchannel */
355         struct unistim_line *parent;    /*! Unistim line */
356         struct ast_rtp_instance *rtp;   /*! RTP handle */
357         int softkey;                    /*! Softkey assigned */
358         pthread_t ss_thread;            /*! unistim_ss thread handle */
359         int alreadygone;
360         int holding;                    /*! this subchannel holds someone */
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                 lang->trans = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, 8,
817                         lang_hash_fn, NULL, lang_cmp_fn);
818                 if (!lang->trans) {
819                         ast_log(LOG_ERROR, "Unable to allocate container for translation!\n");
820                         return str;
821                 }
822                 snprintf(tmp, sizeof(tmp), "%s/%s/%s.po", ast_config_AST_VAR_DIR,
823                          USTM_LANG_DIR, lang->lang_short);
824                 f = fopen(tmp, "r");
825                 if (!f) {
826                         ast_log(LOG_WARNING, "There is no translation file for '%s'\n", lang->lang_short);
827                         return str;
828                 }
829                 while (fgets(tmp, sizeof(tmp), f)) {
830                         if (!(p = strchr(tmp, '\n'))) {
831                                 ast_log(LOG_ERROR, "Too long line found in language file - truncated!\n");
832                                 continue;
833                         }
834                         *p = '\0';
835                         if (!(p = strchr(tmp, '"'))) {
836                                 continue;
837                         }
838                         if (tmp == strstr(tmp, "msgid")) {
839                                 p_orig = ast_strdup(p + 1);
840                                 p = strchr(p_orig, '"');
841                         } else if (tmp == strstr(tmp, "msgstr")) {
842                                 p_trans = ast_strdup(p + 1);
843                                 p = strchr(p_trans, '"');
844                         } else {
845                                 continue;
846                         }
847                         *p = '\0';
848                         if (!p_trans || !p_orig) {
849                                 continue;
850                         }
851                         if (ast_strlen_zero(p_trans)) {
852                                 ast_free(p_trans);
853                                 ast_free(p_orig);
854                                 p_trans = NULL;
855                                 p_orig = NULL;
856                                 continue;
857                         }
858                         if (!(lang_entry = ao2_alloc(sizeof(*lang_entry), NULL))) {
859                                 fclose(f);
860                                 return str;
861                         }
862
863                         lang_entry->str_trans = p_trans;
864                         lang_entry->str_orig = p_orig;
865                         ao2_link(lang->trans, lang_entry);
866                         p_trans = NULL;
867                         p_orig = NULL;
868                 }
869
870                 fclose(f);
871         }
872
873         le_search.str_orig = str;
874         if ((lang_entry = ao2_find(lang->trans, &le_search, OBJ_POINTER))) {
875                 size = strlen(lang_entry->str_trans)+1;
876                 if (size > 1024) {
877                         size = 1024;
878                 }
879                 memcpy(ustm_strcopy, lang_entry->str_trans, size);
880                 ao2_ref(lang_entry, -1);
881                 return ustm_strcopy;
882         }
883
884         return str;
885 }
886
887 static void display_last_error(const char *sz_msg)
888 {
889         /* Display the error message */
890         ast_log(LOG_WARNING, "%s : (%d) %s\n", sz_msg, errno, strerror(errno));
891 }
892
893 static unsigned int get_tick_count(void)
894 {
895         struct timeval now = ast_tvnow();
896
897         return (now.tv_sec * 1000) + (now.tv_usec / 1000);
898 }
899
900 /* Send data to a phone without retransmit nor buffering */
901 static void send_raw_client(int size, const unsigned char *data, struct sockaddr_in *addr_to,
902                             const struct sockaddr_in *addr_ourip)
903 {
904 #ifdef HAVE_PKTINFO
905         struct iovec msg_iov;
906         struct msghdr msg;
907         char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
908         struct cmsghdr *ip_msg = (struct cmsghdr *) buffer;
909         struct in_pktinfo *pki = (struct in_pktinfo *) CMSG_DATA(ip_msg);
910
911         /* cast this to a non-const pointer, since the sendmsg() API
912          * does not provide read-only and write-only flavors of the
913          * structures used for its arguments, but in this case we know
914          * the data will not be modified
915          */
916         msg_iov.iov_base = (char *) data;
917         msg_iov.iov_len = size;
918
919         msg.msg_name = addr_to;  /* optional address */
920         msg.msg_namelen = sizeof(struct sockaddr_in);   /* size of address */
921         msg.msg_iov = &msg_iov;  /* scatter/gather array */
922         msg.msg_iovlen = 1;                  /* # elements in msg_iov */
923         msg.msg_control = ip_msg;       /* ancillary data */
924         msg.msg_controllen = sizeof(buffer);    /* ancillary data buffer len */
925         msg.msg_flags = 0;                    /* flags on received message */
926
927         ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
928         ip_msg->cmsg_level = IPPROTO_IP;
929         ip_msg->cmsg_type = IP_PKTINFO;
930         pki->ipi_ifindex = 0;      /* Interface index, 0 = use interface specified in routing table */
931         pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
932         /* pki->ipi_addr = ;   Header Destination address - ignored by kernel */
933
934 #ifdef DUMP_PACKET
935         if (unistimdebug) {
936                 int tmp;
937                 ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
938                                         ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
939                                         ast_inet_ntoa(addr_to->sin_addr));
940                 for (tmp = 0; tmp < size; tmp++)
941                         ast_verb(0, "%02hhx ", data[tmp]);
942                 ast_verb(0, "\n******************************************\n");
943
944         }
945 #endif
946
947         if (sendmsg(unistimsock, &msg, 0) == -1) {
948                 display_last_error("Error sending datas");
949         }
950 #else
951         if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
952                 == -1)
953                 display_last_error("Error sending datas");
954 #endif
955 }
956
957 static void send_client(int size, const unsigned char *data, struct unistimsession *pte)
958 {
959         unsigned int tick;
960         int buf_pos;
961         unsigned short seq = ntohs(++pte->seq_server);
962
963         ast_mutex_lock(&pte->lock);
964         buf_pos = pte->last_buf_available;
965
966         if (buf_pos >= MAX_BUF_NUMBER) {
967                 ast_log(LOG_WARNING, "Error : send queue overflow\n");
968                 ast_mutex_unlock(&pte->lock);
969                 return;
970         }
971         memcpy((void *)data + sizeof(unsigned short), (void *)&seq, sizeof(unsigned short));
972         pte->wsabufsend[buf_pos].len = size;
973         memcpy(pte->wsabufsend[buf_pos].buf, data, size);
974
975         tick = get_tick_count();
976         pte->timeout = tick + RETRANSMIT_TIMER;
977
978 /*#ifdef DUMP_PACKET */
979         if (unistimdebug) {
980                 ast_verb(0, "Sending datas with seq #0x%04x Using slot #%d :\n", (unsigned)pte->seq_server, buf_pos);
981         }
982 /*#endif */
983         send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
984                                   &(pte->sout));
985         pte->last_buf_available++;
986         ast_mutex_unlock(&pte->lock);
987 }
988
989 static void send_ping(struct unistimsession *pte)
990 {
991         BUFFSEND;
992         if (unistimdebug) {
993                 ast_verb(0, "Sending ping\n");
994         }
995         pte->tick_next_ping = get_tick_count() + unistim_keepalive;
996         memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
997         send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
998 }
999
1000 static int get_to_address(int fd, struct sockaddr_in *toAddr)
1001 {
1002 #ifdef HAVE_PKTINFO
1003         int err;
1004         struct msghdr msg;
1005         struct {
1006                 struct cmsghdr cm;
1007                 int len;
1008                 struct in_addr address;
1009         } ip_msg;
1010
1011         /* Zero out the structures before we use them */
1012         /* This sets several key values to NULL */
1013         memset(&msg, 0, sizeof(msg));
1014         memset(&ip_msg, 0, sizeof(ip_msg));
1015
1016         /* Initialize the message structure */
1017         msg.msg_control = &ip_msg;
1018         msg.msg_controllen = sizeof(ip_msg);
1019         /* Get info about the incoming packet */
1020         err = recvmsg(fd, &msg, MSG_PEEK);
1021         if (err == -1) {
1022                 ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
1023         }
1024         memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
1025         return err;
1026 #else
1027         memcpy(toAddr, &public_ip, sizeof(*toAddr));
1028         return 0;
1029 #endif
1030 }
1031
1032 /* Allocate memory & initialize structures for a new phone */
1033 /* addr_from : ip address of the phone */
1034 static struct unistimsession *create_client(const struct sockaddr_in *addr_from)
1035 {
1036         int tmp;
1037         struct unistimsession *s;
1038
1039         if (!(s = ast_calloc(1, sizeof(*s))))
1040                 return NULL;
1041
1042         memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
1043         get_to_address(unistimsock, &s->sout);
1044         s->sout.sin_family = AF_INET;
1045         if (unistimdebug) {
1046                 ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
1047                          ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
1048         }
1049         ast_mutex_init(&s->lock);
1050         ast_mutex_lock(&sessionlock);
1051         s->next = sessions;
1052         sessions = s;
1053
1054         s->timeout = get_tick_count() + RETRANSMIT_TIMER;
1055         s->state = STATE_INIT;
1056         s->tick_next_ping = get_tick_count() + unistim_keepalive;
1057         /* Initialize struct wsabuf  */
1058         for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
1059                 s->wsabufsend[tmp].buf = s->buf[tmp];
1060         }
1061         ast_mutex_unlock(&sessionlock);
1062         return s;
1063 }
1064
1065 static void send_end_call(struct unistimsession *pte)
1066 {
1067         BUFFSEND;
1068         if (unistimdebug) {
1069                 ast_verb(0, "Sending end call\n");
1070         }
1071         memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
1072         send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
1073 }
1074
1075 static void set_ping_timer(struct unistimsession *pte)
1076 {
1077         unsigned int tick = 0;  /* XXX what is this for, anyways */
1078
1079         pte->timeout = pte->tick_next_ping;
1080         DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
1081         return;
1082 }
1083
1084 /* Checking if our send queue is empty,
1085  * if true, setting up a timer for keepalive */
1086 static void check_send_queue(struct unistimsession *pte)
1087 {
1088         /* Check if our send queue contained only one element */
1089         if (pte->last_buf_available == 1) {
1090                 if (unistimdebug) {
1091                         ast_verb(0, "Our single packet was ACKed.\n");
1092                 }
1093                 pte->last_buf_available--;
1094                 set_ping_timer(pte);
1095                 return;
1096         }
1097         /* Check if this ACK catch up our latest packet */
1098         else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
1099                 if (unistimdebug) {
1100                         ast_verb(0, "Our send queue is completely ACKed.\n");
1101                 }
1102                 pte->last_buf_available = 0;    /* Purge the send queue */
1103                 set_ping_timer(pte);
1104                 return;
1105         }
1106         if (unistimdebug) {
1107                 ast_verb(0, "We still have packets in our send queue\n");
1108         }
1109         return;
1110 }
1111
1112 static void send_start_timer(struct unistimsession *pte)
1113 {
1114         BUFFSEND;
1115         if (unistimdebug) {
1116                 ast_verb(0, "Sending start timer\n");
1117         }
1118         memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer));
1119         send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte);
1120 }
1121
1122 static void send_stop_timer(struct unistimsession *pte)
1123 {
1124         BUFFSEND;
1125         if (unistimdebug) {
1126                 ast_verb(0, "Sending stop timer\n");
1127         }
1128         memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
1129         send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
1130 }
1131
1132 static void send_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
1133 {
1134         BUFFSEND;
1135         if (unistimdebug) {
1136                 ast_verb(0, "Sending icon pos %d with status 0x%02hhx\n", pos, status);
1137         }
1138         memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
1139         buffsend[9] = pos;
1140         buffsend[10] = status;
1141         send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
1142 }
1143
1144 static void send_expansion_next(struct unistimsession *pte)
1145 {
1146         BUFFSEND;
1147         memcpy(buffsend + SIZE_HEADER, packet_send_expansion_next, sizeof(packet_send_expansion_next));
1148         send_client(SIZE_HEADER + sizeof(packet_send_expansion_next), buffsend, pte);
1149 }
1150
1151
1152 static void send_expansion_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
1153 {
1154         BUFFSEND;
1155         if (unistimdebug) {
1156                 ast_verb(0, "Sending expansion icon pos %d with status 0x%02hhx\n", pos, status);
1157         }
1158         memcpy(buffsend + SIZE_HEADER, packet_send_expansion_icon, sizeof(packet_send_expansion_icon));
1159         buffsend[10] = pos;
1160         buffsend[11] = status;
1161         send_client(SIZE_HEADER + sizeof(packet_send_expansion_icon), buffsend, pte);
1162 }
1163
1164 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1165 static void send_expansion_text(unsigned char pos, struct unistimsession *pte, const char *text)
1166 {
1167         int i;
1168         BUFFSEND;
1169         if (!text) {
1170                 ast_log(LOG_ERROR, "[expansion] Asked to display NULL text (pos %d)\n", pos);
1171                 return;
1172         }
1173         if (unistimdebug) {
1174                 ast_verb(0, "[expansion] Sending text at pos %d\n", pos);
1175         }
1176         memcpy(buffsend + SIZE_HEADER, packet_send_expansion_text, sizeof(packet_send_expansion_text));
1177         buffsend[10] = pos;
1178         i = strlen(text);
1179         if (i > TEXT_LENGTH_MAX) {
1180                 i = TEXT_LENGTH_MAX;
1181         }
1182         memcpy(buffsend + 11, text, i);
1183         send_client(SIZE_HEADER + sizeof(packet_send_expansion_text), buffsend, pte);
1184 }
1185
1186 static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
1187 {
1188         BUFFSEND;
1189         if (!tone1) {
1190                 if (unistimdebug) {
1191                         ast_verb(0, "Sending Stream Based Tone Off\n");
1192                 }
1193                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
1194                            sizeof(packet_send_stream_based_tone_off));
1195                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
1196                 return;
1197         }
1198         /* Since most of the world use a continuous tone, it's useless
1199            if (unistimdebug)
1200            ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
1201            memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
1202            send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
1203         if (unistimdebug) {
1204                 ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
1205         }
1206         tone1 *= 8;
1207         if (!tone2) {
1208                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
1209                            sizeof(packet_send_stream_based_tone_single_freq));
1210                 buffsend[10] = (tone1 & 0xff00) >> 8;
1211                 buffsend[11] = (tone1 & 0x00ff);
1212                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
1213                                    pte);
1214         } else {
1215                 tone2 *= 8;
1216                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
1217                            sizeof(packet_send_stream_based_tone_dial_freq));
1218                 buffsend[10] = (tone1 & 0xff00) >> 8;
1219                 buffsend[11] = (tone1 & 0x00ff);
1220                 buffsend[12] = (tone2 & 0xff00) >> 8;
1221                 buffsend[13] = (tone2 & 0x00ff);
1222                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
1223                                    pte);
1224         }
1225
1226         if (unistimdebug) {
1227                 ast_verb(0, "Sending Stream Based Tone On\n");
1228         }
1229         memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
1230                    sizeof(packet_send_stream_based_tone_on));
1231         send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
1232 }
1233
1234 /* Positions for favorites
1235  |--------------------|
1236  |  5            2    | <-- not on screen in i2002
1237  |  4            1    |
1238  |  3            0    |
1239
1240
1241  KEM Positions
1242
1243  |--------------------|
1244  |  12           24   |
1245  |  11           23   |
1246  |  10           22   |
1247  |  9            21   |
1248  |  8            20   |
1249  |  7            19   |
1250  |  6            18   |
1251  |  5            17   |
1252  |  4            16   |
1253  |  3            15   |
1254  |  2            14   |
1255  |  1            13   |
1256
1257 */
1258
1259 /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */
1260 static void
1261 send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte,
1262                          const char *text)
1263 {
1264         BUFFSEND;
1265         int i;
1266
1267         if (unistimdebug) {
1268                 ast_verb(0, "Sending favorite pos %d with status 0x%02hhx\n", pos, status);
1269         }
1270         memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1271         buffsend[10] = pos;
1272         buffsend[24] = pos;
1273         buffsend[25] = status;
1274         i = strlen(ustmtext(text, pte));
1275         if (i > FAV_MAX_LENGTH) {
1276                 i = FAV_MAX_LENGTH;
1277         }
1278         memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i);
1279         send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1280 }
1281
1282 static void send_favorite_short(unsigned char pos, unsigned char status, struct unistimsession *pte) {
1283         send_favorite(pos, status, pte, pte->device->softkeylabel[pos]);
1284         return;
1285 }
1286
1287 static void send_favorite_selected(unsigned char status, struct unistimsession *pte) {
1288         if (pte->device->selected != -1) {
1289                 send_favorite(pte->device->selected, status, pte, pte->device->softkeylabel[pte->device->selected]);
1290         }
1291         return;
1292 }
1293
1294 static void send_expansion_short(unsigned char pos, unsigned char status, struct unistimsession *pte) {
1295         send_expansion_icon(pos, status, pte);
1296         send_expansion_text(pos, pte, ustmtext(pte->device->expsoftkeylabel[pos], pte));
1297         send_expansion_next(pte);
1298         return;
1299 }
1300
1301 static int soft_key_visible(struct unistim_device* d, unsigned char num)
1302 {
1303         if(d->height == 1 && num % 3 == 2) {
1304                 return 0;
1305         }
1306         return 1;
1307 }
1308
1309 static void refresh_all_favorite(struct unistimsession *pte)
1310 {
1311         unsigned char i = 0;
1312         char data[256];
1313         struct unistim_line *line;
1314         line = AST_LIST_FIRST(&pte->device->lines);
1315
1316         if (unistimdebug) {
1317                 ast_verb(0, "Refreshing all favorite\n");
1318         }
1319         for (i = 0; i < FAVNUM; i++) {
1320                 unsigned char status = pte->device->softkeyicon[i];
1321
1322                 if (!soft_key_visible(pte->device, i)) {
1323                         continue;
1324                 }
1325                 if (!strcasecmp(pte->device->softkeylabel[i], "DND") && line) {
1326                         if (!ast_db_get("DND", line->name, data, sizeof(data))) {
1327                                 status = FAV_ICON_SPEAKER_ONHOOK_WHITE;
1328                         }
1329                 }
1330
1331                 send_favorite_short(i, status, pte);
1332         }
1333         if (pte->device->hasexp) {
1334                 for (i = 0; i < EXPNUM; i++) {
1335                         send_expansion_short(i, FAV_ICON_NONE, pte);
1336                 }
1337         }
1338 }
1339
1340 static int is_key_favorite(struct unistim_device *d, int fav)
1341 {
1342         if ((fav < 0) && (fav > 5)) {
1343                 return 0;
1344         }
1345         if (d->sline[fav]) {
1346                 return 0;
1347         }
1348         if (d->softkeynumber[fav][0] == '\0') {
1349                 return 0;
1350         }
1351         return 1;
1352 }
1353
1354 static int is_key_line(struct unistim_device *d, int fav)
1355 {
1356         if ((fav < 0) && (fav > 5)) {
1357                 return 0;
1358         }
1359         if (!d->sline[fav]) {
1360                 return 0;
1361         }
1362         if (is_key_favorite(d, fav)) {
1363                 return 0;
1364         }
1365         return 1;
1366 }
1367
1368 static int get_active_softkey(struct unistimsession *pte)
1369 {
1370         return pte->device->selected;
1371 }
1372
1373 static int get_avail_softkey(struct unistimsession *pte, const char* name)
1374 {
1375         int i;
1376
1377         if (!is_key_line(pte->device, pte->device->selected)) {
1378                 pte->device->selected = -1;
1379         }
1380         for (i = 0; i < FAVNUM; i++) {
1381                 if (pte->device->selected != -1 && pte->device->selected != i) {
1382                         continue;
1383                 }
1384                 if (!soft_key_visible(pte->device, i)) {
1385                         continue;
1386                 }
1387                 if (pte->device->ssub[i]) {
1388                         continue;
1389                 }
1390                 if (is_key_line(pte->device, i)) {
1391                         if (name && strcmp(name, pte->device->sline[i]->name)) {
1392                                 continue;
1393                         }
1394                         if (unistimdebug) {
1395                                 ast_verb(0, "Found softkey %d for device %s\n", i, name);
1396                         }
1397                         return i;
1398                 }
1399         }
1400         return -1;
1401 }
1402
1403
1404 /* Change the status for this phone (pte) and update for each phones where pte is bookmarked
1405  * use FAV_ICON_*_BLACK constant in status parameters */
1406 static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
1407 {
1408         struct unistim_device *d = devices;
1409         int i;
1410         /* Update the current phone line softkey icon */
1411         if (pte->state != STATE_CLEANING) {
1412                 int softkeylinepos = get_active_softkey(pte);
1413                 if (softkeylinepos != -1) {
1414                         send_favorite_short(softkeylinepos, status, pte);
1415                 }
1416         }
1417         /* Notify other phones if we're in their bookmark */
1418         while (d) {
1419                 for (i = 0; i < FAVNUM; i++) {
1420                         if (d->sp[i] == pte->device) {  /* It's us ? */
1421                                 if (d->softkeyicon[i] != status) {      /* Avoid resending the same icon */
1422                                         d->softkeyicon[i] = status;
1423                                         if (d->session) {
1424                                                 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1425                                         }
1426                                 }
1427                         }
1428                 }
1429                 d = d->next;
1430         }
1431 }
1432
1433 static int register_extension(const struct unistimsession *pte)
1434 {
1435         struct unistim_line *line;
1436         line = AST_LIST_FIRST(&pte->device->lines);
1437         if (unistimdebug) {
1438                 ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
1439                                         pte->device->extension_number, pte->device->context,
1440                                         line->fullname);
1441         }
1442         return ast_add_extension(pte->device->context, 0,
1443                                                          pte->device->extension_number, 1, NULL, NULL, "Dial",
1444                                                          line->fullname, 0, "Unistim");
1445 }
1446
1447 static int unregister_extension(const struct unistimsession *pte)
1448 {
1449         if (unistimdebug) {
1450                 ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
1451                                         pte->device->extension_number, pte->device->context);
1452         }
1453         return ast_context_remove_extension(pte->device->context,
1454                                                                                 pte->device->extension_number, 1, "Unistim");
1455 }
1456
1457 /* Free memory allocated for a phone */
1458 static void close_client(struct unistimsession *s)
1459 {
1460         struct unistim_subchannel *sub = NULL;
1461         struct unistimsession *cur, *prev = NULL;
1462         ast_mutex_lock(&sessionlock);
1463         cur = sessions;
1464         /* Looking for the session in the linked chain */
1465         while (cur) {
1466                 if (cur == s) {
1467                         break;
1468                 }
1469                 prev = cur;
1470                 cur = cur->next;
1471         }
1472         if (cur) {                                    /* Session found ? */
1473                 if (cur->device) {            /* This session was registered ? */
1474                         s->state = STATE_CLEANING;
1475                         if (unistimdebug) {
1476                                 ast_verb(0, "close_client session %p device %p\n", s, s->device);
1477                         }
1478                         change_favorite_icon(s, FAV_ICON_NONE);
1479                         ast_mutex_lock(&s->device->lock);
1480                         AST_LIST_LOCK(&s->device->subs);
1481                         AST_LIST_TRAVERSE_SAFE_BEGIN(&s->device->subs, sub, list) {
1482                                 if (!sub) {
1483                                         continue;
1484                                 }
1485                                 if (sub->owner) {       /* Call in progress ? */
1486                                         if (unistimdebug) {
1487                                                 ast_verb(0, "Aborting call\n");
1488                                         }
1489                                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NETWORK_OUT_OF_ORDER);
1490                                 } else {
1491                                         if (unistimdebug) {
1492                                                 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, s->device->name);
1493                                         }
1494                                         AST_LIST_REMOVE_CURRENT(list);
1495                                         unistim_free_sub(sub);
1496                                 }
1497                         }
1498                         AST_LIST_TRAVERSE_SAFE_END;
1499                         AST_LIST_UNLOCK(&s->device->subs);
1500
1501                         if (!ast_strlen_zero(s->device->extension_number)) {
1502                                 unregister_extension(s);
1503                         }
1504                         cur->device->session = NULL;
1505                         ast_mutex_unlock(&s->device->lock);
1506                 } else {
1507                         if (unistimdebug) {
1508                                 ast_verb(0, "Freeing an unregistered client\n");
1509                         }
1510                 }
1511                 if (prev) {
1512                         prev->next = cur->next;
1513                 } else {
1514                         sessions = cur->next;
1515                 }
1516                 ast_mutex_destroy(&s->lock);
1517                 ast_free(s);
1518         } else {
1519                 ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
1520         }
1521         ast_mutex_unlock(&sessionlock);
1522         return;
1523 }
1524
1525 /* Return 1 if the session chained link was modified */
1526 static int send_retransmit(struct unistimsession *pte)
1527 {
1528         int i;
1529
1530         ast_mutex_lock(&pte->lock);
1531         if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
1532                 if (unistimdebug) {
1533                         ast_verb(0, "Too many retransmit - freeing client\n");
1534                 }
1535                 ast_mutex_unlock(&pte->lock);
1536                 close_client(pte);
1537                 return 1;
1538         }
1539         pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
1540
1541         for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
1542                  i < pte->last_buf_available; i++) {
1543                 if (i < 0) {
1544                         ast_log(LOG_WARNING,
1545                                         "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%04x last_seq_ack = #0x%04x\n",
1546                                         pte->last_buf_available, (unsigned)pte->seq_server, (unsigned)pte->last_seq_ack);
1547                         continue;
1548                 }
1549
1550                 if (unistimdebug) {
1551                         unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
1552                         unsigned short seq;
1553
1554                         seq = ntohs(sbuf[1]);
1555                         ast_verb(0, "Retransmit slot #%d (seq=#0x%04x), last ack was #0x%04x\n", i,
1556                                                 (unsigned)seq, (unsigned)pte->last_seq_ack);
1557                 }
1558                 send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
1559                                           &pte->sout);
1560         }
1561         ast_mutex_unlock(&pte->lock);
1562         return 0;
1563 }
1564
1565 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1566 static void send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte,
1567                  const char *text)
1568 {
1569         int i;
1570         BUFFSEND;
1571         if (!text) {
1572                 ast_log(LOG_ERROR, "Asked to display NULL text (pos %d, inverse flag %d)\n", pos, inverse);
1573                 return;
1574         }
1575         if (pte->device && pte->device->height == 1 && pos != TEXT_LINE0) {
1576                 return;
1577         }
1578         if (unistimdebug) {
1579                 ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
1580         }
1581         memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
1582         buffsend[10] = pos;
1583         buffsend[11] = inverse;
1584         i = strlen(text);
1585         if (i > TEXT_LENGTH_MAX) {
1586                 i = TEXT_LENGTH_MAX;
1587         }
1588         memcpy(buffsend + 12, text, i);
1589         send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
1590 }
1591
1592 static void send_text_status(struct unistimsession *pte, const char *text)
1593 {
1594         BUFFSEND;
1595         int i;
1596         if (unistimdebug) {
1597                 ast_verb(0, "Sending status text\n");
1598         }
1599         if (pte->device) {
1600                 if (pte->device->status_method == 1) {  /* For new firmware and i2050 soft phone */
1601                         int n = strlen(text);
1602                         /* Must send individual button separately */
1603                         int j;
1604                         for (i = 0, j = 0; i < 4; i++, j += 7) {
1605                                 int pos = 0x08 + (i * 0x20);
1606                                 memcpy(buffsend + SIZE_HEADER, packet_send_status2,
1607                                            sizeof(packet_send_status2));
1608
1609                                 buffsend[9] = pos;
1610                                 memcpy(buffsend + 10, (j < n) ? (text + j) : "       ", 7);
1611                                 send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
1612                         }
1613                         return;
1614                 }
1615         }
1616
1617         memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
1618         i = strlen(text);
1619         if (i > STATUS_LENGTH_MAX) {
1620                 i = STATUS_LENGTH_MAX;
1621         }
1622         memcpy(buffsend + 10, text, i);
1623         send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
1624
1625 }
1626
1627 static void send_led_update(struct unistimsession *pte, unsigned char led)
1628 {
1629         BUFFSEND;
1630         if (unistimdebug) {
1631                 ast_verb(0, "Sending led_update (%x)\n", (unsigned)led);
1632         }
1633         memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1634         buffsend[9] = led;
1635         send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1636 }
1637
1638 static void send_mute(struct unistimsession *pte, unsigned char mute)
1639 {
1640 /*
1641         0x00 = unmute TX, 0x01 = mute TX
1642         0x20 = unmute RX, 0x21 = mute RX
1643 */
1644         BUFFSEND;
1645         if (unistimdebug) {
1646                 ast_verb(0, "Sending mute packet (%x)\n", (unsigned)mute);
1647         }
1648         memcpy(buffsend + SIZE_HEADER, packet_send_mute, sizeof(packet_send_mute));
1649         buffsend[9] = mute;
1650         send_client(SIZE_HEADER + sizeof(packet_send_mute), buffsend, pte);
1651 }
1652
1653
1654 /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
1655  * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
1656  * mute = MUTE_OFF, MUTE_ON */
1657 static void
1658 send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume,
1659                                  unsigned char mute)
1660 {
1661         BUFFSEND;
1662         int mute_icon = -1;
1663         if (unistimdebug) {
1664                 ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n",
1665                         (unsigned)output, (unsigned)volume, (unsigned)mute);
1666         }
1667         memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1668                    sizeof(packet_send_select_output));
1669         buffsend[9] = output;
1670         if (output == OUTPUT_SPEAKER && volume == VOLUME_LOW) {
1671                 volume = VOLUME_LOW_SPEAKER;
1672         }
1673         buffsend[10] = volume;
1674         if (mute == MUTE_ON_DISCRET) {
1675                 buffsend[11] = MUTE_ON;
1676         } else {
1677                 buffsend[11] = mute;
1678         }
1679         send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1680         if (output == OUTPUT_HANDSET) {
1681                 mute_icon = (mute == MUTE_ON) ? FAV_ICON_ONHOLD_BLACK : FAV_ICON_OFFHOOK_BLACK;
1682                 send_led_update(pte, LED_SPEAKER_OFF);
1683                 send_led_update(pte, LED_HEADPHONE_OFF);
1684         } else if (output == OUTPUT_HEADPHONE) {
1685                 mute_icon = (mute == MUTE_ON)? FAV_ICON_HEADPHONES_ONHOLD : FAV_ICON_HEADPHONES;
1686                 send_led_update(pte, LED_SPEAKER_OFF);
1687                 send_led_update(pte, LED_HEADPHONE_ON);
1688         } else if (output == OUTPUT_SPEAKER) {
1689                 send_led_update(pte, LED_SPEAKER_ON);
1690                 send_led_update(pte, LED_HEADPHONE_OFF);
1691                 if (pte->device->receiver_state == STATE_OFFHOOK) {
1692                         mute_icon = (mute == MUTE_ON)? FAV_ICON_SPEAKER_ONHOLD_BLACK : FAV_ICON_SPEAKER_ONHOOK_BLACK;
1693                 } else {
1694                         mute_icon = (mute == MUTE_ON)? FAV_ICON_SPEAKER_ONHOLD_BLACK : FAV_ICON_SPEAKER_OFFHOOK_BLACK;
1695                 }
1696         } else {
1697                 ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
1698         }
1699         if (mute_icon != -1) {
1700                 change_favorite_icon(pte, mute_icon);
1701         }
1702         if (output != pte->device->output) {
1703                 pte->device->previous_output = pte->device->output;
1704         }
1705         pte->device->output = output;
1706 }
1707 static void send_ring(struct unistimsession *pte, signed char volume, signed char style)
1708 {
1709         BUFFSEND;
1710         if (unistimdebug) {
1711                 ast_verb(0, "Sending ring packet\n");
1712         }
1713         memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1714         buffsend[24] = style + 0x10;
1715         buffsend[29] = volume * 0x10;
1716         send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1717 }
1718
1719 static void send_no_ring(struct unistimsession *pte)
1720 {
1721         BUFFSEND;
1722         if (unistimdebug) {
1723                 ast_verb(0, "Sending no ring packet\n");
1724         }
1725         memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1726         send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1727 }
1728
1729 static void send_texttitle(struct unistimsession *pte, const char *text)
1730 {
1731         BUFFSEND;
1732         int i;
1733         if (unistimdebug) {
1734                 ast_verb(0, "Sending title text\n");
1735         }
1736         memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1737         i = strlen(text);
1738         if (i > 12) {
1739                 i = 12;
1740         }
1741         memcpy(buffsend + 10, text, i);
1742         send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1743 }
1744
1745 static void send_idle_clock(struct unistimsession *pte)
1746 {
1747         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
1748 }
1749
1750 static void send_month_labels(struct unistimsession *pte, int month)
1751 {
1752         BUFFSEND;
1753         char month_name[MONTH_LABEL_SIZE + 1];
1754         int i = 0;
1755         if (unistimdebug) {
1756                 ast_verb(0, "Sending Month Labels\n");
1757         }
1758         month_name[MONTH_LABEL_SIZE] = '\0';
1759         memcpy(buffsend + SIZE_HEADER, packet_send_monthlabels_download, sizeof(packet_send_monthlabels_download));
1760         while (i < 2) {
1761                 memcpy(month_name, &monthlabels[month * MONTH_LABEL_SIZE], MONTH_LABEL_SIZE);
1762                 memcpy(buffsend + SIZE_HEADER + 3 + i*MONTH_LABEL_SIZE, ustmtext(month_name, pte), MONTH_LABEL_SIZE);
1763                 ast_log(LOG_WARNING,"%s\n", month_name);
1764                 ast_log(LOG_WARNING,"%s\n", ustmtext(month_name, pte));
1765                 month = (month + 1)%12;
1766                 i++;
1767         }
1768         send_client(SIZE_HEADER + sizeof(packet_send_monthlabels_download), buffsend, pte);
1769 }
1770
1771
1772 static void send_date_time(struct unistimsession *pte)
1773 {
1774         BUFFSEND;
1775         struct timeval now = ast_tvnow();
1776         struct ast_tm atm = { 0, };
1777
1778         if (unistimdebug) {
1779                 ast_verb(0, "Sending Time & Date\n");
1780         }
1781         memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1782         ast_localtime(&now, &atm, NULL);
1783         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1784         buffsend[11] = (unsigned char) atm.tm_mday;
1785         buffsend[12] = (unsigned char) atm.tm_hour;
1786         buffsend[13] = (unsigned char) atm.tm_min;
1787         send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1788         send_month_labels(pte, atm.tm_mon);
1789 }
1790
1791 static void send_date_time2(struct unistimsession *pte)
1792 {
1793         BUFFSEND;
1794         struct timeval now = ast_tvnow();
1795         struct ast_tm atm = { 0, };
1796
1797         if (unistimdebug) {
1798                 ast_verb(0, "Sending Time & Date #2\n");
1799         }
1800         memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1801         ast_localtime(&now, &atm, NULL);
1802         if (pte->device) {
1803                 buffsend[9] = pte->device->datetimeformat;
1804         } else {
1805                 buffsend[9] = 61;
1806         }
1807         buffsend[14] = (unsigned char) atm.tm_mon + 1;
1808         buffsend[15] = (unsigned char) atm.tm_mday;
1809         buffsend[16] = (unsigned char) atm.tm_hour;
1810         buffsend[17] = (unsigned char) atm.tm_min;
1811         send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1812 }
1813
1814 static void send_date_time3(struct unistimsession *pte)
1815 {
1816         BUFFSEND;
1817         struct timeval now = ast_tvnow();
1818         struct ast_tm atm = { 0, };
1819
1820         if (unistimdebug) {
1821                 ast_verb(0, "Sending Time & Date #3\n");
1822         }
1823         memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1824         ast_localtime(&now, &atm, NULL);
1825         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1826         buffsend[11] = (unsigned char) atm.tm_mday;
1827         buffsend[12] = (unsigned char) atm.tm_hour;
1828         buffsend[13] = (unsigned char) atm.tm_min;
1829         send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1830 }
1831
1832 static void send_blink_cursor(struct unistimsession *pte)
1833 {
1834         BUFFSEND;
1835         if (unistimdebug) {
1836                 ast_verb(0, "Sending set blink\n");
1837         }
1838         memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
1839         send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1840         return;
1841 }
1842
1843 /* pos : 0xab (a=0/2/4 = line ; b = row) */
1844 static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
1845 {
1846         BUFFSEND;
1847         if (unistimdebug) {
1848                 ast_verb(0, "Sending set cursor position\n");
1849         }
1850         memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1851                    sizeof(packet_send_set_pos_cursor));
1852         buffsend[11] = pos;
1853         send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1854         return;
1855 }
1856
1857 static void send_charset_update(struct unistimsession *pte, int charset)
1858 {
1859         const unsigned char* packet_send_charset;
1860         int packet_size;
1861         BUFFSEND;
1862         if (unistimdebug) {
1863                 ast_verb(0, "Sending set default charset\n");
1864         }
1865         if (charset == LANG_DEFAULT) {
1866                 charset = options_languages[find_language(pte->device->language)].encoding;
1867         }
1868         switch (charset) {
1869         case ISO_8859_2:
1870                 packet_send_charset = packet_send_charset_iso_8859_2;
1871                 packet_size = sizeof(packet_send_charset_iso_8859_2);
1872                 break;
1873         case ISO_8859_4:
1874                 packet_send_charset = packet_send_charset_iso_8859_4;
1875                 packet_size = sizeof(packet_send_charset_iso_8859_4);
1876                 break;
1877         case ISO_8859_5:
1878                 packet_send_charset = packet_send_charset_iso_8859_5;
1879                 packet_size = sizeof(packet_send_charset_iso_8859_5);
1880                 break;
1881         case ISO_2022_JP:
1882                 packet_send_charset = packet_send_charset_iso_2022_jp;
1883                 packet_size = sizeof(packet_send_charset_iso_2022_jp);
1884                 break;
1885         case ISO_8859_1:
1886         default:
1887                 packet_send_charset = packet_send_charset_iso_8859_1;
1888                 packet_size = sizeof(packet_send_charset_iso_8859_1);
1889         }
1890         memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size);
1891         send_client(SIZE_HEADER + packet_size, buffsend, pte);
1892         return;
1893 }
1894
1895 static void rcv_resume_connection_with_server(struct unistimsession *pte)
1896 {
1897         BUFFSEND;
1898         if (unistimdebug) {
1899                 ast_verb(0, "ResumeConnectionWithServer received\n");
1900                 ast_verb(0, "Sending packet_send_query_mac_address\n");
1901         }
1902         memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1903                    sizeof(packet_send_query_mac_address));
1904         send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1905         return;
1906 }
1907
1908 static int unistim_register(struct unistimsession *s)
1909 {
1910         struct unistim_device *d;
1911
1912         ast_mutex_lock(&devicelock);
1913         d = devices;
1914         while (d) {
1915                 if (!strcasecmp(s->macaddr, d->id)) {
1916                         /* XXX Deal with IP authentication */
1917                         s->device = d;
1918                         d->session = s;
1919                         d->codec_number = DEFAULT_CODEC;
1920                         d->missed_call = 0;
1921                         d->receiver_state = STATE_ONHOOK;
1922                         break;
1923                 }
1924                 d = d->next;
1925         }
1926         ast_mutex_unlock(&devicelock);
1927
1928         if (!d) {
1929                 return 0;
1930         }
1931
1932         return 1;
1933 }
1934
1935 static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
1936 {
1937         struct ast_format_cap *tmp = src->cap;
1938         memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
1939         src->cap = tmp;
1940         ast_format_cap_append_from_cap(src->cap, dst->cap, AST_MEDIA_TYPE_UNKNOWN);
1941 }
1942
1943 static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
1944 {
1945         if (!l) {
1946                 return NULL;
1947         }
1948         ao2_ref(l->cap, -1);
1949         ast_free(l);
1950         return NULL;
1951 }
1952
1953 static struct unistim_line *unistim_line_alloc(void)
1954 {
1955         struct unistim_line *l;
1956         if (!(l = ast_calloc(1, sizeof(*l)))) {
1957                 return NULL;
1958         }
1959
1960         if (!(l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1961                 ast_free(l);
1962                 return NULL;
1963         }
1964         return l;
1965 }
1966
1967 static int unistim_free_sub(struct unistim_subchannel *sub) {
1968         if (unistimdebug) {
1969                 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, sub->parent->parent->name);
1970         }
1971         ast_mutex_destroy(&sub->lock);
1972         ast_free(sub);
1973         return 0;
1974 }
1975
1976 static struct unistim_subchannel *unistim_alloc_sub(struct unistim_device *d, int x)
1977 {
1978         struct unistim_subchannel *sub;
1979         if (!(sub = ast_calloc(1, sizeof(*sub)))) {
1980                 return NULL;
1981         }
1982
1983         if (unistimdebug) {
1984                 ast_verb(3, "Allocating UNISTIM subchannel #%d on %s ptr=%p\n", x, d->name, sub);
1985         }
1986         sub->ss_thread = AST_PTHREADT_NULL;
1987         sub->subtype = x;
1988         AST_LIST_LOCK(&d->subs);
1989         AST_LIST_INSERT_TAIL(&d->subs, sub, list);
1990         AST_LIST_UNLOCK(&d->subs);
1991         ast_mutex_init(&sub->lock);
1992         return sub;
1993 }
1994
1995 static int unistim_unalloc_sub(struct unistim_device *d, struct unistim_subchannel *sub)
1996 {
1997         struct unistim_subchannel *s;
1998
1999         AST_LIST_LOCK(&d->subs);
2000         AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, s, list) {
2001                 if (!s) {
2002                         continue;
2003                 }
2004                 if (s != sub) {
2005                         continue;
2006                 }
2007                 AST_LIST_REMOVE_CURRENT(list);
2008                 unistim_free_sub(sub);
2009         }
2010         AST_LIST_TRAVERSE_SAFE_END;
2011         AST_LIST_UNLOCK(&d->subs);
2012         return 0;
2013 }
2014
2015 static const char *subtype_tostr(const int type)
2016 {
2017         switch (type) {
2018         case SUB_REAL:
2019                 return "REAL";
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 struct unistim_subchannel* get_sub_holding(struct unistim_device *device, int type, int holding)
2500 {
2501         struct unistim_subchannel *sub = NULL;
2502
2503         AST_LIST_LOCK(&device->subs);
2504         AST_LIST_TRAVERSE(&device->subs, sub, list) {
2505                 if (!sub) {
2506                         continue;
2507                 }
2508                 if (sub->subtype == type && sub->holding == holding) {
2509                         break;
2510                 }
2511         }
2512         AST_LIST_UNLOCK(&device->subs);
2513
2514         return sub;
2515 }
2516
2517 static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
2518 {
2519         /* Silence our channel */
2520         if (!pte->device->silence_generator) {
2521                 pte->device->silence_generator =
2522                         ast_channel_start_silence_generator(sub->owner);
2523                 if (pte->device->silence_generator == NULL) {
2524                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2525                 } else if (unistimdebug) {
2526                         ast_verb(0, "Starting silence generator\n");
2527                 }
2528         }
2529
2530 }
2531
2532 static void sub_stop_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
2533 {
2534         /* Stop the silence generator */
2535         if (pte->device->silence_generator) {
2536                 if (unistimdebug) {
2537                         ast_verb(0, "Stopping silence generator\n");
2538                 }
2539                 if (sub->owner) {
2540                         ast_channel_stop_silence_generator(sub->owner, pte->device->silence_generator);
2541                 } else {
2542                         ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel!\n");
2543                 }
2544                 pte->device->silence_generator = NULL;
2545         }
2546 }
2547
2548 static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub)
2549 {
2550         if (!sub) {
2551                 return;
2552         }
2553         sub->moh = 1;
2554         sub->holding = 1;
2555         send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte);
2556         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2557         send_stop_timer(pte);
2558         if (sub->owner) {
2559                 ast_queue_hold(sub->owner, NULL);
2560         }
2561         return;
2562 }
2563
2564 static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *sub)
2565 {
2566         struct unistim_subchannel *sub_real;
2567
2568         sub_real = get_sub(pte->device, SUB_REAL);
2569         if (sub_real) {
2570             sub_hold(pte, sub_real);
2571         }
2572
2573         sub->moh = 0;
2574         sub->holding = 0;
2575         send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte);
2576         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2577         send_start_timer(pte);
2578         if (sub->owner) {
2579                 ast_queue_unhold(sub->owner);
2580                 if (sub->rtp) {
2581                         send_start_rtp(sub);
2582                 }
2583         }
2584         return;
2585 }
2586
2587 static void close_call(struct unistimsession *pte)
2588 {
2589         struct unistim_subchannel *sub, *sub_transf;
2590
2591         sub = get_sub(pte->device, SUB_REAL);
2592         sub_transf = get_sub(pte->device, SUB_THREEWAY);
2593         send_stop_timer(pte);
2594         if (!sub) {
2595                 ast_log(LOG_WARNING, "Close call without sub\n");
2596                 return;
2597         }
2598         send_favorite_short(sub->softkey, FAV_LINE_ICON, pte);
2599         if (sub->owner) {
2600                 sub->alreadygone = 1;
2601                 if (sub_transf) {
2602                         sub_transf->alreadygone = 1;
2603                         if (attempt_transfer(sub, sub_transf) < 0) {
2604                                 ast_verb(0, "attempt_transfer failed.\n");
2605                         }
2606                 } else {
2607                         ast_queue_hangup(sub->owner);
2608                 }
2609         } else {
2610                 if (sub_transf) {
2611                         if (sub_transf->owner) {
2612                                 ast_queue_hangup_with_cause(sub_transf->owner, AST_CAUSE_NORMAL_CLEARING);
2613                         } else {
2614                                 ast_log(LOG_WARNING, "threeway sub without owner\n");
2615                         }
2616                 } else {
2617                         ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2618                                                 pte->device->name, sub->softkey);
2619                 }
2620         }
2621         change_callerid(pte, 0, pte->device->redial_number);
2622         change_callerid(pte, 1, "");
2623         write_history(pte, 'o', pte->device->missed_call);
2624         pte->device->missed_call = 0;
2625         show_main_page(pte);
2626         return;
2627 }
2628
2629 static void ignore_call(struct unistimsession *pte)
2630 {
2631         send_no_ring(pte);
2632         return;
2633 }
2634
2635 static void discard_call(struct unistimsession *pte)
2636 {
2637         struct unistim_subchannel* sub;
2638         sub = get_sub(pte->device, SUB_RING);
2639         if (!sub) {
2640             return;
2641         }
2642
2643         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
2644         return;
2645 }
2646
2647 static void *unistim_ss(void *data)
2648 {
2649         struct ast_channel *chan = data;
2650         struct unistim_subchannel *sub = ast_channel_tech_pvt(chan);
2651         struct unistim_line *l = sub->parent;
2652         struct unistimsession *s = l->parent->session;
2653         int res;
2654
2655         if (!s) {
2656                 return NULL;
2657         }
2658         ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
2659         ast_channel_lock(chan);
2660         ast_channel_exten_set(chan, s->device->phone_number);
2661         ast_setstate(chan, AST_STATE_RING);
2662         ast_channel_unlock(chan);
2663         ast_copy_string(s->device->redial_number, s->device->phone_number,
2664                                         sizeof(s->device->redial_number));
2665         res = ast_pbx_run(chan);
2666         if (res) {
2667                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2668                 send_tone(s, 1000, 0);
2669         }
2670         return NULL;
2671 }
2672
2673 static int find_rtp_port(struct unistim_subchannel *s)
2674 {
2675         struct unistim_subchannel *sub = NULL;
2676         int rtp_start = s->parent->parent->rtp_port;
2677         struct ast_sockaddr us_tmp;
2678         struct sockaddr_in us = { 0, };
2679
2680         AST_LIST_LOCK(&s->parent->parent->subs);
2681         AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) {
2682                 if (!sub) {
2683                         continue;
2684                 }
2685                 if (sub->rtp) {
2686                         ast_rtp_instance_get_remote_address(sub->rtp, &us_tmp);
2687                         ast_sockaddr_to_sin(&us_tmp, &us);
2688                         if (htons(us.sin_port)) {
2689                                 rtp_start = htons(us.sin_port) + 1;
2690                                 break;
2691                         }
2692                 }
2693         }
2694         AST_LIST_UNLOCK(&s->parent->parent->subs);
2695         return rtp_start;
2696 }
2697
2698 static void send_start_rtp(struct unistim_subchannel *sub)
2699 {
2700         BUFFSEND;
2701
2702         int codec;
2703         struct sockaddr_in public = { 0, };
2704         struct sockaddr_in us = { 0, };
2705         struct sockaddr_in sin = { 0, };
2706         struct ast_sockaddr us_tmp;
2707         struct ast_sockaddr sin_tmp;
2708         struct unistimsession *pte;
2709
2710         ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
2711         ast_sockaddr_to_sin(&us_tmp, &us);
2712         ast_rtp_instance_get_remote_address(sub->rtp, &sin_tmp);
2713         ast_sockaddr_to_sin(&sin_tmp, &sin);
2714
2715         /* Setting up RTP of the phone */
2716         if (public_ip.sin_family == 0) {  /* NAT IP override ?   */
2717                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2718         } else {
2719                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2720         }
2721         if (unistimdebug) {
2722                 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
2723                          ast_inet_ntoa(us.sin_addr),
2724                          htons(us.sin_port), ast_format_get_name(ast_channel_readformat(sub->owner)));
2725                 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2726                                         ast_inet_ntoa(public.sin_addr));
2727         }
2728
2729         pte = sub->parent->parent->session;
2730         codec = ast_rtp_codecs_payload_code_tx(ast_rtp_instance_get_codecs(sub->rtp),
2731                 1, ast_channel_readformat(sub->owner), 0);
2732         if ((ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) ||
2733                 (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_alaw) == AST_FORMAT_CMP_EQUAL)) {
2734                 if (unistimdebug) {
2735                         ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2736                 }
2737                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2738                            sizeof(packet_send_rtp_packet_size));
2739                 buffsend[10] = (int) codec & 0xffffffffLL;
2740                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte);
2741         }
2742         if (unistimdebug) {
2743                 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2744         }
2745         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2746                    sizeof(packet_send_jitter_buffer_conf));
2747         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte);
2748         if (pte->device->rtp_method != 0) {
2749                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2750
2751                 if (unistimdebug) {
2752                         ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method);
2753                 }
2754                 if (pte->device->rtp_method == 3) {
2755                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2756                                    sizeof(packet_send_open_audio_stream_tx3));
2757                 } else {
2758                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2759                                    sizeof(packet_send_open_audio_stream_tx));
2760                 }
2761                 if (pte->device->rtp_method != 2) {
2762                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2763                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2764                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2765                         buffsend[23] = (rtcpsin_port & 0x00ff);
2766                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2767                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2768                         buffsend[24] = (us.sin_port & 0x00ff);
2769                         buffsend[27] = (rtcpsin_port & 0x00ff);
2770                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2771                 } else {
2772                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2773                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2774                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2775                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2776                         buffsend[19] = (us.sin_port & 0x00ff);
2777                 }
2778                 buffsend[11] = codec; /* rx */
2779                 buffsend[12] = codec; /* tx */
2780                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend, pte);
2781
2782                 if (unistimdebug) {
2783                         ast_verb(0, "Sending OpenAudioStreamRX\n");
2784                 }
2785                 if (pte->device->rtp_method == 3) {
2786                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2787                                    sizeof(packet_send_open_audio_stream_rx3));
2788                 } else {
2789                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2790                                    sizeof(packet_send_open_audio_stream_rx));
2791                 }
2792                 if (pte->device->rtp_method != 2) {
2793                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2794                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2795                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2796                         buffsend[23] = (rtcpsin_port & 0x00ff);
2797                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2798                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2799                         buffsend[24] = (us.sin_port & 0x00ff);
2800                         buffsend[27] = (rtcpsin_port & 0x00ff);
2801                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2802                 } else {
2803                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2804                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2805                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2806                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2807                         buffsend[19] = (us.sin_port & 0x00ff);
2808                 }
2809                 buffsend[11] = codec; /* rx */
2810                 buffsend[12] = codec; /* tx */
2811                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend, pte);
2812         } else {
2813                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2814
2815                 if (unistimdebug) {
2816                         ast_verb(0, "Sending packet_send_call default method\n");
2817                 }
2818
2819                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2820                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2821                 /* Destination port when sending RTP */
2822                 buffsend[49] = (us.sin_port & 0x00ff);
2823                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2824                 /* Destination port when sending RTCP */
2825                 buffsend[52] = (rtcpsin_port & 0x00ff);
2826                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2827                 /* Codec */
2828                 buffsend[40] = codec;
2829                 buffsend[41] = codec;
2830                 if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
2831                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2832                 } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
2833                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2834                 } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
2835                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2836                 } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
2837                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2838                 } else {
2839                         ast_log(LOG_WARNING, "Unsupported codec %s!\n",
2840                                 ast_format_get_name(ast_channel_readformat(sub->owner)));
2841                 }
2842                 /* Source port for transmit RTP and Destination port for receiving RTP */
2843                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2844                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2845                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2846                 buffsend[48] = (rtcpsin_port & 0x00ff);
2847                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte);
2848         }
2849 }
2850
2851 static void start_rtp(struct unistim_subchannel *sub)
2852 {
2853         struct sockaddr_in sin = { 0, };
2854         struct sockaddr_in sout = { 0, };
2855         struct ast_sockaddr sin_tmp;
2856         struct ast_sockaddr sout_tmp;
2857
2858         /* Sanity checks */
2859         if (!sub) {
2860                 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2861                 return;
2862         }
2863         if (!sub->parent) {
2864                 ast_log(LOG_WARNING, "start_rtp with a null line!\n");
2865                 return;
2866         }
2867         if (!sub->parent->parent) {
2868                 ast_log(LOG_WARNING, "start_rtp with a null device!\n");
2869                 return;
2870         }
2871         if (!sub->parent->parent->session) {
2872                 ast_log(LOG_WARNING, "start_rtp with a null session!\n");
2873                 return;
2874         }
2875         if (!sub->owner) {
2876                 ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n");
2877                 return;
2878         }
2879         sout = sub->parent->parent->session->sout;
2880         ast_mutex_lock(&sub->lock);
2881         /* Allocate the RTP */
2882         if (unistimdebug) {
2883                 ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2884         }
2885         ast_sockaddr_from_sin(&sout_tmp, &sout);
2886         sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
2887         if (!sub->rtp) {
2888                 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2889                                 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2890                 ast_mutex_unlock(&sub->lock);
2891                 return;
2892         }
2893         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
2894         ast_rtp_instance_set_channel_id(sub->rtp, ast_channel_uniqueid(sub->owner));
2895         ast_channel_internal_fd_set(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
2896         ast_channel_internal_fd_set(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
2897         ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2898         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
2899
2900         /* Create the RTP connection */
2901         sin.sin_family = AF_INET;
2902         /* Setting up RTP for our side */
2903         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2904                    sizeof(sin.sin_addr));
2905
2906         sin.sin_port = htons(find_rtp_port(sub));
2907         ast_sockaddr_from_sin(&sin_tmp, &sin);
2908         ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
2909         if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(sub->owner), ast_channel_readformat(sub->owner)) == AST_FORMAT_CMP_NOT_EQUAL) {
2910                 struct ast_format *tmpfmt;
2911                 struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
2912
2913                 tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(sub->owner), 0);
2914                 ast_log(LOG_WARNING,
2915                                 "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
2916                                 ast_format_get_name(ast_channel_readformat(sub->owner)),
2917                                 ast_format_get_name(tmpfmt),
2918                                 ast_format_cap_get_names(ast_channel_nativeformats(sub->owner), &cap_buf));
2919
2920                 ast_channel_set_readformat(sub->owner, tmpfmt);
2921                 ast_channel_set_writeformat(sub->owner, tmpfmt);
2922         ao2_ref(tmpfmt, -1);
2923         }
2924         send_start_rtp(sub);
2925         ast_mutex_unlock(&sub->lock);
2926 }
2927
2928 static void send_dial_tone(struct unistimsession *pte)
2929 {
2930         struct ast_tone_zone_sound *ts = NULL;
2931         struct ast_tone_zone_part tone_data;
2932         char *s = NULL;
2933         char *ind;
2934
2935         if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) {
2936                 ind = ast_strdupa(ts->data);
2937                 s = strsep(&ind, ",");
2938                 ast_tone_zone_part_parse(s, &tone_data);
2939                 send_tone(pte, tone_data.freq1, tone_data.freq2);
2940                 if (unistimdebug) {
2941                         ast_verb(0, "Country code found (%s), freq1=%u freq2=%u\n",
2942                                                         pte->device->tz->country, tone_data.freq1, tone_data.freq2);
2943                 }
2944                 ts = ast_tone_zone_sound_unref(ts);
2945         }
2946 }
2947
2948 static void show_phone_number(struct unistimsession *pte)
2949 {
2950         char tmp[TEXT_LENGTH_MAX + 1];
2951         const char *tmp_number = ustmtext("Number:", pte);
2952         int line, tmp_copy, offset = 0, i;
2953
2954         pte->device->phone_number[pte->device->size_phone_number] = '\0';
2955         if  (pte->device->size_phone_number > MAX_SCREEN_NUMBER) {
2956                 offset = pte->device->size_phone_number - MAX_SCREEN_NUMBER - 1;
2957                 if (offset > strlen(tmp_number)) {
2958                         offset = strlen(tmp_number);
2959                 }
2960                 tmp_copy = strlen(tmp_number) - offset + 1;
2961                 if (tmp_copy > sizeof(tmp)) {
2962                         tmp_copy = sizeof(tmp);
2963                 }
2964                 memcpy(tmp, tmp_number + offset, tmp_copy);
2965         } else {
2966                 ast_copy_string(tmp, tmp_number, sizeof(tmp));
2967         }
2968
2969         offset = (pte->device->size_phone_number >= TEXT_LENGTH_MAX) ? (pte->device->size_phone_number - TEXT_LENGTH_MAX +1) : 0;
2970         if (pte->device->size_phone_number) {
2971                 memcpy(tmp + strlen(tmp), pte->device->phone_number + offset, pte->device->size_phone_number - offset + 1);
2972         }
2973         offset = strlen(tmp);
2974
2975         for (i = strlen(tmp); i < TEXT_LENGTH_MAX; i++) {
2976                 tmp[i] = '.';
2977         }
2978         tmp[i] = '\0';
2979
2980         line = (pte->device->height == 1) ? TEXT_LINE0 : TEXT_LINE2;
2981         send_text(line, TEXT_NORMAL, pte, tmp);
2982         send_blink_cursor(pte);
2983         send_cursor_pos(pte, (unsigned char) (line + offset));
2984         send_led_update(pte, LED_BAR_OFF);
2985 }
2986
2987 static void handle_dial_page(struct unistimsession *pte)
2988 {
2989         pte->state = STATE_DIALPAGE;
2990         if (pte->device->call_forward[0] == -1) {
2991                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2992                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte));
2993                 send_text_status(pte, ustmtext("Fwd    Cancel BackSp Erase", pte));
2994                 if (pte->device->call_forward[1] != 0) {
2995                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2996                                                         sizeof(pte->device->phone_number));
2997                         show_phone_number(pte);
2998                         send_led_update(pte, LED_BAR_OFF);
2999                         return;
3000                 }
3001         } else {
3002                 if ((pte->device->output == OUTPUT_HANDSET) &&
3003                         (pte->device->receiver_state == STATE_ONHOOK)) {
3004                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3005                 } else {
3006                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3007                 }
3008                 send_dial_tone(pte);
3009
3010                 if (pte->device->height > 1) {
3011                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte));
3012                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte));
3013                 }
3014                 if (ast_strlen_zero(pte->device->redial_number)) {
3015                         send_text_status(pte, ustmtext("Call          BackSp Erase", pte));
3016                 } else {
3017                         send_text_status(pte, ustmtext("Call   Redial BackSp Erase", pte));
3018                 }
3019         }
3020
3021         pte->device->size_phone_number = 0;
3022         pte->device->phone_number[0] = 0;
3023         show_phone_number(pte);
3024         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
3025         send_icon(TEXT_LINE0, FAV_ICON_NONE, pte);
3026         pte->device->missed_call = 0;
3027         send_led_update(pte, LED_BAR_OFF);
3028         pte->device->lastmsgssent = -1;
3029         return;
3030 }
3031
3032 static void swap_subs(struct unistim_subchannel *a, struct unistim_subchannel *b)
3033 {
3034         struct ast_rtp_instance *rtp;
3035         int fds;
3036
3037         if (unistimdebug) {
3038                 ast_verb(0, "Swapping %p and %p\n", a, b);
3039         }
3040         if ((!a->owner) || (!b->owner)) {
3041                 ast_log(LOG_WARNING,
3042                                 "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n",
3043                                 a, a->owner, b, b->owner);
3044                 return;
3045         }
3046         rtp = a->rtp;
3047         a->rtp = b->rtp;
3048         b->rtp = rtp;
3049
3050         fds = ast_channel_fd(a->owner, 0);
3051         ast_channel_internal_fd_set(a->owner, 0, ast_channel_fd(b->owner, 0));
3052         ast_channel_internal_fd_set(b->owner, 0, fds);
3053
3054         fds = ast_channel_fd(a->owner, 1);
3055         ast_channel_internal_fd_set(a->owner, 1, ast_channel_fd(b->owner, 1));
3056         ast_channel_internal_fd_set(b->owner, 1, fds);
3057 }
3058
3059 /* Step 1 : Music On Hold for peer, Dialing screen for us */
3060 static void transfer_call_step1(struct unistimsession *pte)
3061 {
3062         struct unistim_subchannel *sub /*, *sub_trans */;
3063         struct unistim_device *d = pte->device;
3064
3065         sub = get_sub(d, SUB_REAL);
3066         /* sub_trans = get_sub(d, SUB_THREEWAY); */
3067
3068         if (!sub || !sub->owner) {
3069                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3070                 return;
3071         }
3072         /* Start music on hold if appropriate */
3073         if (sub->moh) {
3074                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
3075         } else {
3076                 ast_queue_hold(sub->owner, sub->parent->musicclass);
3077                 sub->moh = 1;
3078                 sub->subtype = SUB_THREEWAY;
3079         }
3080         sub_start_silence(pte, sub);
3081         handle_dial_page(pte);
3082 }
3083
3084 static void transfer_cancel_step2(struct unistimsession *pte)
3085 {
3086         struct unistim_subchannel *sub, *sub_trans;
3087         struct unistim_device *d = pte->device;
3088
3089         sub = get_sub(d, SUB_REAL);
3090         sub_trans = get_sub(d, SUB_THREEWAY);
3091
3092         if (!sub || !sub->owner) {
3093                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3094                 return;
3095         }
3096         if (sub_trans) {
3097                 if (unistimdebug) {
3098                         ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
3099                 }
3100                 if (sub->owner) {
3101                         swap_subs(sub, sub_trans);
3102                         ast_queue_unhold(sub_trans->owner);
3103                         sub_trans->moh = 0;
3104                         sub_trans->subtype = SUB_REAL;
3105                         sub->subtype = SUB_THREEWAY;
3106                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
3107                 }