install_prereq: Download latest Jansson.
[asterisk/asterisk.git] / channels / chan_unistim.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * UNISTIM channel driver for asterisk
5  *
6  * Copyright (C) 2005 - 2007, Cedric Hans
7  *
8  * Cedric Hans <cedric.hans@mlkj.net>
9  *
10  * Asterisk 1.4 patch by Peter Be
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20  * at the top of the source tree.
21  */
22
23 /*!
24  * \file
25  *
26  * \brief chan_unistim channel driver for Asterisk
27  * \author Cedric Hans <cedric.hans@mlkj.net>
28  *
29  * Unistim (Unified Networks IP Stimulus) channel driver
30  * for Nortel i2002, i2004 and i2050
31  *
32  * \ingroup channel_drivers
33  */
34
35 /*** MODULEINFO
36         <support_level>extended</support_level>
37  ***/
38
39 #include "asterisk.h"
40
41 #include <sys/stat.h>
42 #include <signal.h>
43
44 #if defined(__CYGWIN__)
45 /*
46  * cygwin headers are partly inconsistent. struct iovec is defined in sys/uio.h
47  * which is not included by default by sys/socket.h - in_pktinfo is defined in
48  * w32api/ws2tcpip.h but this probably has compatibility problems with sys/socket.h
49  * So for the time being we simply disable HAVE_PKTINFO when building under cygwin.
50  *    This should be done in some common header, but for now this is the only file
51  * using iovec and in_pktinfo so it suffices to apply the fix here.
52  */
53 #ifdef HAVE_PKTINFO
54 #undef HAVE_PKTINFO
55 #endif
56 #endif /* __CYGWIN__ */
57
58 #include "asterisk/paths.h"     /* ast_config_AST_LOG_DIR used in (too ?) many places */
59 #include "asterisk/network.h"
60 #include "asterisk/channel.h"
61 #include "asterisk/config.h"
62 #include "asterisk/module.h"
63 #include "asterisk/pbx.h"
64 #include "asterisk/rtp_engine.h"
65 #include "asterisk/netsock2.h"
66 #include "asterisk/acl.h"
67 #include "asterisk/callerid.h"
68 #include "asterisk/cli.h"
69 #include "asterisk/app.h"
70 #include "asterisk/musiconhold.h"
71 #include "asterisk/causes.h"
72 #include "asterisk/indications.h"
73 #include "asterisk/pickup.h"
74 #include "asterisk/astobj2.h"
75 #include "asterisk/astdb.h"
76 #include "asterisk/features_config.h"
77 #include "asterisk/bridge.h"
78 #include "asterisk/stasis_channels.h"
79 #include "asterisk/format_cache.h"
80
81 #define DEFAULTCONTEXT    "default"
82 #define DEFAULTCALLERID  "Unknown"
83 #define DEFAULTCALLERNAME       " "
84 #define DEFAULTHEIGHT    3
85 #define USTM_LOG_DIR        "unistimHistory"
86 #define USTM_LANG_DIR       "unistimLang"
87
88 /*! Size of the transmit buffer */
89 #define MAX_BUF_SIZE        64
90 /*! Number of slots for the transmit queue */
91 #define MAX_BUF_NUMBER    150
92 /*! Number of digits displayed on screen */
93 #define MAX_SCREEN_NUMBER   15
94 /*! Length of month label size */
95 #define MONTH_LABEL_SIZE 3
96 /*! Try x times before removing the phone */
97 #define NB_MAX_RETRANSMIT       8
98 /*! Nb of milliseconds waited when no events are scheduled */
99 #define IDLE_WAIT              1000
100 /*! Wait x milliseconds before resending a packet */
101 #define RETRANSMIT_TIMER        2000
102 /*! How often the mailbox is checked for new messages */
103 #define TIMER_MWI              5000
104 /*! Timeout value for entered number being dialed */
105 #define DEFAULT_INTERDIGIT_TIMER        4000
106
107 /*! Not used */
108 #define DEFAULT_CODEC      0x00
109 #define SIZE_PAGE              4096
110 #define DEVICE_NAME_LEN  16
111 #define AST_CONFIG_MAX_PATH     255
112 #define MAX_ENTRY_LOG      30
113
114 #define SUB_REAL                0
115 #define SUB_RING                1
116 #define SUB_THREEWAY            2
117
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                 if (!(lang->trans = ao2_container_alloc(8, lang_hash_fn, lang_cmp_fn))) {
817                         ast_log(LOG_ERROR, "Unable to allocate container for translation!\n");
818                         return str;
819                 }
820                 snprintf(tmp, sizeof(tmp), "%s/%s/%s.po", ast_config_AST_VAR_DIR,
821                          USTM_LANG_DIR, lang->lang_short);
822                 f = fopen(tmp, "r");
823                 if (!f) {
824                         ast_log(LOG_WARNING, "There is no translation file for '%s'\n", lang->lang_short);
825                         return str;
826                 }
827                 while (fgets(tmp, sizeof(tmp), f)) {
828                         if (!(p = strchr(tmp, '\n'))) {
829                                 ast_log(LOG_ERROR, "Too long line found in language file - truncated!\n");
830                                 continue;
831                         }
832                         *p = '\0';
833                         if (!(p = strchr(tmp, '"'))) {
834                                 continue;
835                         }
836                         if (tmp == strstr(tmp, "msgid")) {
837                                 p_orig = ast_strdup(p + 1);
838                                 p = strchr(p_orig, '"');
839                         } else if (tmp == strstr(tmp, "msgstr")) {
840                                 p_trans = ast_strdup(p + 1);
841                                 p = strchr(p_trans, '"');
842                         } else {
843                                 continue;
844                         }
845                         *p = '\0';
846                         if (!p_trans || !p_orig) {
847                                 continue;
848                         }
849                         if (ast_strlen_zero(p_trans)) {
850                                 ast_free(p_trans);
851                                 ast_free(p_orig);
852                                 p_trans = NULL;
853                                 p_orig = NULL;
854                                 continue;
855                         }
856                         if (!(lang_entry = ao2_alloc(sizeof(*lang_entry), NULL))) {
857                                 fclose(f);
858                                 return str;
859                         }
860
861                         lang_entry->str_trans = p_trans;
862                         lang_entry->str_orig = p_orig;
863                         ao2_link(lang->trans, lang_entry);
864                         p_trans = NULL;
865                         p_orig = NULL;
866                 }
867
868                 fclose(f);
869         }
870
871         le_search.str_orig = str;
872         if ((lang_entry = ao2_find(lang->trans, &le_search, OBJ_POINTER))) {
873                 size = strlen(lang_entry->str_trans)+1;
874                 if (size > 1024) {
875                         size = 1024;
876                 }
877                 memcpy(ustm_strcopy, lang_entry->str_trans, size);
878                 ao2_ref(lang_entry, -1);
879                 return ustm_strcopy;
880         }
881
882         return str;
883 }
884
885 static void display_last_error(const char *sz_msg)
886 {
887         /* Display the error message */
888         ast_log(LOG_WARNING, "%s : (%d) %s\n", sz_msg, errno, strerror(errno));
889 }
890
891 static unsigned int get_tick_count(void)
892 {
893         struct timeval now = ast_tvnow();
894
895         return (now.tv_sec * 1000) + (now.tv_usec / 1000);
896 }
897
898 /* Send data to a phone without retransmit nor buffering */
899 static void send_raw_client(int size, const unsigned char *data, struct sockaddr_in *addr_to,
900                             const struct sockaddr_in *addr_ourip)
901 {
902 #ifdef HAVE_PKTINFO
903         struct iovec msg_iov;
904         struct msghdr msg;
905         char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
906         struct cmsghdr *ip_msg = (struct cmsghdr *) buffer;
907         struct in_pktinfo *pki = (struct in_pktinfo *) CMSG_DATA(ip_msg);
908
909         /* cast this to a non-const pointer, since the sendmsg() API
910          * does not provide read-only and write-only flavors of the
911          * structures used for its arguments, but in this case we know
912          * the data will not be modified
913          */
914         msg_iov.iov_base = (char *) data;
915         msg_iov.iov_len = size;
916
917         msg.msg_name = addr_to;  /* optional address */
918         msg.msg_namelen = sizeof(struct sockaddr_in);   /* size of address */
919         msg.msg_iov = &msg_iov;  /* scatter/gather array */
920         msg.msg_iovlen = 1;                  /* # elements in msg_iov */
921         msg.msg_control = ip_msg;       /* ancillary data */
922         msg.msg_controllen = sizeof(buffer);    /* ancillary data buffer len */
923         msg.msg_flags = 0;                    /* flags on received message */
924
925         ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
926         ip_msg->cmsg_level = IPPROTO_IP;
927         ip_msg->cmsg_type = IP_PKTINFO;
928         pki->ipi_ifindex = 0;      /* Interface index, 0 = use interface specified in routing table */
929         pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
930         /* pki->ipi_addr = ;   Header Destination address - ignored by kernel */
931
932 #ifdef DUMP_PACKET
933         if (unistimdebug) {
934                 int tmp;
935                 ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
936                                         ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
937                                         ast_inet_ntoa(addr_to->sin_addr));
938                 for (tmp = 0; tmp < size; tmp++)
939                         ast_verb(0, "%02hhx ", data[tmp]);
940                 ast_verb(0, "\n******************************************\n");
941
942         }
943 #endif
944
945         if (sendmsg(unistimsock, &msg, 0) == -1) {
946                 display_last_error("Error sending datas");
947         }
948 #else
949         if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
950                 == -1)
951                 display_last_error("Error sending datas");
952 #endif
953 }
954
955 static void send_client(int size, const unsigned char *data, struct unistimsession *pte)
956 {
957         unsigned int tick;
958         int buf_pos;
959         unsigned short seq = ntohs(++pte->seq_server);
960
961         ast_mutex_lock(&pte->lock);
962         buf_pos = pte->last_buf_available;
963
964         if (buf_pos >= MAX_BUF_NUMBER) {
965                 ast_log(LOG_WARNING, "Error : send queue overflow\n");
966                 ast_mutex_unlock(&pte->lock);
967                 return;
968         }
969         memcpy((void *)data + sizeof(unsigned short), (void *)&seq, sizeof(unsigned short));
970         pte->wsabufsend[buf_pos].len = size;
971         memcpy(pte->wsabufsend[buf_pos].buf, data, size);
972
973         tick = get_tick_count();
974         pte->timeout = tick + RETRANSMIT_TIMER;
975
976 /*#ifdef DUMP_PACKET */
977         if (unistimdebug) {
978                 ast_verb(0, "Sending datas with seq #0x%04x Using slot #%d :\n", (unsigned)pte->seq_server, buf_pos);
979         }
980 /*#endif */
981         send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
982                                   &(pte->sout));
983         pte->last_buf_available++;
984         ast_mutex_unlock(&pte->lock);
985 }
986
987 static void send_ping(struct unistimsession *pte)
988 {
989         BUFFSEND;
990         if (unistimdebug) {
991                 ast_verb(0, "Sending ping\n");
992         }
993         pte->tick_next_ping = get_tick_count() + unistim_keepalive;
994         memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
995         send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
996 }
997
998 static int get_to_address(int fd, struct sockaddr_in *toAddr)
999 {
1000 #ifdef HAVE_PKTINFO
1001         int err;
1002         struct msghdr msg;
1003         struct {
1004                 struct cmsghdr cm;
1005                 int len;
1006                 struct in_addr address;
1007         } ip_msg;
1008
1009         /* Zero out the structures before we use them */
1010         /* This sets several key values to NULL */
1011         memset(&msg, 0, sizeof(msg));
1012         memset(&ip_msg, 0, sizeof(ip_msg));
1013
1014         /* Initialize the message structure */
1015         msg.msg_control = &ip_msg;
1016         msg.msg_controllen = sizeof(ip_msg);
1017         /* Get info about the incoming packet */
1018         err = recvmsg(fd, &msg, MSG_PEEK);
1019         if (err == -1) {
1020                 ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
1021         }
1022         memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
1023         return err;
1024 #else
1025         memcpy(toAddr, &public_ip, sizeof(*toAddr));
1026         return 0;
1027 #endif
1028 }
1029
1030 /* Allocate memory & initialize structures for a new phone */
1031 /* addr_from : ip address of the phone */
1032 static struct unistimsession *create_client(const struct sockaddr_in *addr_from)
1033 {
1034         int tmp;
1035         struct unistimsession *s;
1036
1037         if (!(s = ast_calloc(1, sizeof(*s))))
1038                 return NULL;
1039
1040         memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
1041         get_to_address(unistimsock, &s->sout);
1042         s->sout.sin_family = AF_INET;
1043         if (unistimdebug) {
1044                 ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
1045                          ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
1046         }
1047         ast_mutex_init(&s->lock);
1048         ast_mutex_lock(&sessionlock);
1049         s->next = sessions;
1050         sessions = s;
1051
1052         s->timeout = get_tick_count() + RETRANSMIT_TIMER;
1053         s->state = STATE_INIT;
1054         s->tick_next_ping = get_tick_count() + unistim_keepalive;
1055         /* Initialize struct wsabuf  */
1056         for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
1057                 s->wsabufsend[tmp].buf = s->buf[tmp];
1058         }
1059         ast_mutex_unlock(&sessionlock);
1060         return s;
1061 }
1062
1063 static void send_end_call(struct unistimsession *pte)
1064 {
1065         BUFFSEND;
1066         if (unistimdebug) {
1067                 ast_verb(0, "Sending end call\n");
1068         }
1069         memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
1070         send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
1071 }
1072
1073 static void set_ping_timer(struct unistimsession *pte)
1074 {
1075         unsigned int tick = 0;  /* XXX what is this for, anyways */
1076
1077         pte->timeout = pte->tick_next_ping;
1078         DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
1079         return;
1080 }
1081
1082 /* Checking if our send queue is empty,
1083  * if true, setting up a timer for keepalive */
1084 static void check_send_queue(struct unistimsession *pte)
1085 {
1086         /* Check if our send queue contained only one element */
1087         if (pte->last_buf_available == 1) {
1088                 if (unistimdebug) {
1089                         ast_verb(0, "Our single packet was ACKed.\n");
1090                 }
1091                 pte->last_buf_available--;
1092                 set_ping_timer(pte);
1093                 return;
1094         }
1095         /* Check if this ACK catch up our latest packet */
1096         else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
1097                 if (unistimdebug) {
1098                         ast_verb(0, "Our send queue is completely ACKed.\n");
1099                 }
1100                 pte->last_buf_available = 0;    /* Purge the send queue */
1101                 set_ping_timer(pte);
1102                 return;
1103         }
1104         if (unistimdebug) {
1105                 ast_verb(0, "We still have packets in our send queue\n");
1106         }
1107         return;
1108 }
1109
1110 static void send_start_timer(struct unistimsession *pte)
1111 {
1112         BUFFSEND;
1113         if (unistimdebug) {
1114                 ast_verb(0, "Sending start timer\n");
1115         }
1116         memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer));
1117         send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte);
1118 }
1119
1120 static void send_stop_timer(struct unistimsession *pte)
1121 {
1122         BUFFSEND;
1123         if (unistimdebug) {
1124                 ast_verb(0, "Sending stop timer\n");
1125         }
1126         memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
1127         send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
1128 }
1129
1130 static void send_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
1131 {
1132         BUFFSEND;
1133         if (unistimdebug) {
1134                 ast_verb(0, "Sending icon pos %d with status 0x%02hhx\n", pos, status);
1135         }
1136         memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
1137         buffsend[9] = pos;
1138         buffsend[10] = status;
1139         send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
1140 }
1141
1142 static void send_expansion_next(struct unistimsession *pte)
1143 {
1144         BUFFSEND;
1145         memcpy(buffsend + SIZE_HEADER, packet_send_expansion_next, sizeof(packet_send_expansion_next));
1146         send_client(SIZE_HEADER + sizeof(packet_send_expansion_next), buffsend, pte);
1147 }
1148
1149
1150 static void send_expansion_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
1151 {
1152         BUFFSEND;
1153         if (unistimdebug) {
1154                 ast_verb(0, "Sending expansion icon pos %d with status 0x%02hhx\n", pos, status);
1155         }
1156         memcpy(buffsend + SIZE_HEADER, packet_send_expansion_icon, sizeof(packet_send_expansion_icon));
1157         buffsend[10] = pos;
1158         buffsend[11] = status;
1159         send_client(SIZE_HEADER + sizeof(packet_send_expansion_icon), buffsend, pte);
1160 }
1161
1162 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1163 static void send_expansion_text(unsigned char pos, struct unistimsession *pte, const char *text)
1164 {
1165         int i;
1166         BUFFSEND;
1167         if (!text) {
1168                 ast_log(LOG_ERROR, "[expansion] Asked to display NULL text (pos %d)\n", pos);
1169                 return;
1170         }
1171         if (unistimdebug) {
1172                 ast_verb(0, "[expansion] Sending text at pos %d\n", pos);
1173         }
1174         memcpy(buffsend + SIZE_HEADER, packet_send_expansion_text, sizeof(packet_send_expansion_text));
1175         buffsend[10] = pos;
1176         i = strlen(text);
1177         if (i > TEXT_LENGTH_MAX) {
1178                 i = TEXT_LENGTH_MAX;
1179         }
1180         memcpy(buffsend + 11, text, i);
1181         send_client(SIZE_HEADER + sizeof(packet_send_expansion_text), buffsend, pte);
1182 }
1183
1184 static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
1185 {
1186         BUFFSEND;
1187         if (!tone1) {
1188                 if (unistimdebug) {
1189                         ast_verb(0, "Sending Stream Based Tone Off\n");
1190                 }
1191                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
1192                            sizeof(packet_send_stream_based_tone_off));
1193                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
1194                 return;
1195         }
1196         /* Since most of the world use a continuous tone, it's useless
1197            if (unistimdebug)
1198            ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
1199            memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
1200            send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
1201         if (unistimdebug) {
1202                 ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
1203         }
1204         tone1 *= 8;
1205         if (!tone2) {
1206                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
1207                            sizeof(packet_send_stream_based_tone_single_freq));
1208                 buffsend[10] = (tone1 & 0xff00) >> 8;
1209                 buffsend[11] = (tone1 & 0x00ff);
1210                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
1211                                    pte);
1212         } else {
1213                 tone2 *= 8;
1214                 memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
1215                            sizeof(packet_send_stream_based_tone_dial_freq));
1216                 buffsend[10] = (tone1 & 0xff00) >> 8;
1217                 buffsend[11] = (tone1 & 0x00ff);
1218                 buffsend[12] = (tone2 & 0xff00) >> 8;
1219                 buffsend[13] = (tone2 & 0x00ff);
1220                 send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
1221                                    pte);
1222         }
1223
1224         if (unistimdebug) {
1225                 ast_verb(0, "Sending Stream Based Tone On\n");
1226         }
1227         memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
1228                    sizeof(packet_send_stream_based_tone_on));
1229         send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
1230 }
1231
1232 /* Positions for favorites
1233  |--------------------|
1234  |  5            2    | <-- not on screen in i2002
1235  |  4            1    |
1236  |  3            0    |
1237
1238
1239  KEM Positions
1240
1241  |--------------------|
1242  |  12           24   |
1243  |  11           23   |
1244  |  10           22   |
1245  |  9            21   |
1246  |  8            20   |
1247  |  7            19   |
1248  |  6            18   |
1249  |  5            17   |
1250  |  4            16   |
1251  |  3            15   |
1252  |  2            14   |
1253  |  1            13   |
1254
1255 */
1256
1257 /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */
1258 static void
1259 send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte,
1260                          const char *text)
1261 {
1262         BUFFSEND;
1263         int i;
1264
1265         if (unistimdebug) {
1266                 ast_verb(0, "Sending favorite pos %d with status 0x%02hhx\n", pos, status);
1267         }
1268         memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1269         buffsend[10] = pos;
1270         buffsend[24] = pos;
1271         buffsend[25] = status;
1272         i = strlen(ustmtext(text, pte));
1273         if (i > FAV_MAX_LENGTH) {
1274                 i = FAV_MAX_LENGTH;
1275         }
1276         memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i);
1277         send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1278 }
1279
1280 static void send_favorite_short(unsigned char pos, unsigned char status, struct unistimsession *pte) {
1281         send_favorite(pos, status, pte, pte->device->softkeylabel[pos]);
1282         return;
1283 }
1284
1285 static void send_favorite_selected(unsigned char status, struct unistimsession *pte) {
1286         if (pte->device->selected != -1) {
1287                 send_favorite(pte->device->selected, status, pte, pte->device->softkeylabel[pte->device->selected]);
1288         }
1289         return;
1290 }
1291
1292 static void send_expansion_short(unsigned char pos, unsigned char status, struct unistimsession *pte) {
1293         send_expansion_icon(pos, status, pte);
1294         send_expansion_text(pos, pte, ustmtext(pte->device->expsoftkeylabel[pos], pte));
1295         send_expansion_next(pte);
1296         return;
1297 }
1298
1299 static int soft_key_visible(struct unistim_device* d, unsigned char num)
1300 {
1301         if(d->height == 1 && num % 3 == 2) {
1302                 return 0;
1303         }
1304         return 1;
1305 }
1306
1307 static void refresh_all_favorite(struct unistimsession *pte)
1308 {
1309         unsigned char i = 0;
1310         char data[256];
1311         struct unistim_line *line;
1312         line = AST_LIST_FIRST(&pte->device->lines);
1313
1314         if (unistimdebug) {
1315                 ast_verb(0, "Refreshing all favorite\n");
1316         }
1317         for (i = 0; i < FAVNUM; i++) {
1318                 unsigned char status = pte->device->softkeyicon[i];
1319
1320                 if (!soft_key_visible(pte->device, i)) {
1321                         continue;
1322                 }
1323                 if (!strcasecmp(pte->device->softkeylabel[i], "DND") && line) {
1324                         if (!ast_db_get("DND", line->name, data, sizeof(data))) {
1325                                 status = FAV_ICON_SPEAKER_ONHOOK_WHITE;
1326                         }
1327                 }
1328
1329                 send_favorite_short(i, status, pte);
1330         }
1331         if (pte->device->hasexp) {
1332                 for (i = 0; i < EXPNUM; i++) {
1333                         send_expansion_short(i, FAV_ICON_NONE, pte);
1334                 }
1335         }
1336 }
1337
1338 static int is_key_favorite(struct unistim_device *d, int fav)
1339 {
1340         if ((fav < 0) && (fav > 5)) {
1341                 return 0;
1342         }
1343         if (d->sline[fav]) {
1344                 return 0;
1345         }
1346         if (d->softkeynumber[fav][0] == '\0') {
1347                 return 0;
1348         }
1349         return 1;
1350 }
1351
1352 static int is_key_line(struct unistim_device *d, int fav)
1353 {
1354         if ((fav < 0) && (fav > 5)) {
1355                 return 0;
1356         }
1357         if (!d->sline[fav]) {
1358                 return 0;
1359         }
1360         if (is_key_favorite(d, fav)) {
1361                 return 0;
1362         }
1363         return 1;
1364 }
1365
1366 static int get_active_softkey(struct unistimsession *pte)
1367 {
1368         return pte->device->selected;
1369 }
1370
1371 static int get_avail_softkey(struct unistimsession *pte, const char* name)
1372 {
1373         int i;
1374
1375         if (!is_key_line(pte->device, pte->device->selected)) {
1376                 pte->device->selected = -1;
1377         }
1378         for (i = 0; i < FAVNUM; i++) {
1379                 if (pte->device->selected != -1 && pte->device->selected != i) {
1380                         continue;
1381                 }
1382                 if (!soft_key_visible(pte->device, i)) {
1383                         continue;
1384                 }
1385                 if (pte->device->ssub[i]) {
1386                         continue;
1387                 }
1388                 if (is_key_line(pte->device, i)) {
1389                         if (name && strcmp(name, pte->device->sline[i]->name)) {
1390                                 continue;
1391                         }
1392                         if (unistimdebug) {
1393                                 ast_verb(0, "Found softkey %d for device %s\n", i, name);
1394                         }
1395                         return i;
1396                 }
1397         }
1398         return -1;
1399 }
1400
1401
1402 /* Change the status for this phone (pte) and update for each phones where pte is bookmarked
1403  * use FAV_ICON_*_BLACK constant in status parameters */
1404 static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
1405 {
1406         struct unistim_device *d = devices;
1407         int i;
1408         /* Update the current phone line softkey icon */
1409         if (pte->state != STATE_CLEANING) {
1410                 int softkeylinepos = get_active_softkey(pte);
1411                 if (softkeylinepos != -1) {
1412                         send_favorite_short(softkeylinepos, status, pte);
1413                 }
1414         }
1415         /* Notify other phones if we're in their bookmark */
1416         while (d) {
1417                 for (i = 0; i < FAVNUM; i++) {
1418                         if (d->sp[i] == pte->device) {  /* It's us ? */
1419                                 if (d->softkeyicon[i] != status) {      /* Avoid resending the same icon */
1420                                         d->softkeyicon[i] = status;
1421                                         if (d->session) {
1422                                                 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1423                                         }
1424                                 }
1425                         }
1426                 }
1427                 d = d->next;
1428         }
1429 }
1430
1431 static int register_extension(const struct unistimsession *pte)
1432 {
1433         struct unistim_line *line;
1434         line = AST_LIST_FIRST(&pte->device->lines);
1435         if (unistimdebug) {
1436                 ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
1437                                         pte->device->extension_number, pte->device->context,
1438                                         line->fullname);
1439         }
1440         return ast_add_extension(pte->device->context, 0,
1441                                                          pte->device->extension_number, 1, NULL, NULL, "Dial",
1442                                                          line->fullname, 0, "Unistim");
1443 }
1444
1445 static int unregister_extension(const struct unistimsession *pte)
1446 {
1447         if (unistimdebug) {
1448                 ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
1449                                         pte->device->extension_number, pte->device->context);
1450         }
1451         return ast_context_remove_extension(pte->device->context,
1452                                                                                 pte->device->extension_number, 1, "Unistim");
1453 }
1454
1455 /* Free memory allocated for a phone */
1456 static void close_client(struct unistimsession *s)
1457 {
1458         struct unistim_subchannel *sub = NULL;
1459         struct unistimsession *cur, *prev = NULL;
1460         ast_mutex_lock(&sessionlock);
1461         cur = sessions;
1462         /* Looking for the session in the linked chain */
1463         while (cur) {
1464                 if (cur == s) {
1465                         break;
1466                 }
1467                 prev = cur;
1468                 cur = cur->next;
1469         }
1470         if (cur) {                                    /* Session found ? */
1471                 if (cur->device) {            /* This session was registered ? */
1472                         s->state = STATE_CLEANING;
1473                         if (unistimdebug) {
1474                                 ast_verb(0, "close_client session %p device %p\n", s, s->device);
1475                         }
1476                         change_favorite_icon(s, FAV_ICON_NONE);
1477                         ast_mutex_lock(&s->device->lock);
1478                         AST_LIST_LOCK(&s->device->subs);
1479                         AST_LIST_TRAVERSE_SAFE_BEGIN(&s->device->subs, sub, list) {
1480                                 if (!sub) {
1481                                         continue;
1482                                 }
1483                                 if (sub->owner) {       /* Call in progress ? */
1484                                         if (unistimdebug) {
1485                                                 ast_verb(0, "Aborting call\n");
1486                                         }
1487                                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NETWORK_OUT_OF_ORDER);
1488                                 } else {
1489                                         if (unistimdebug) {
1490                                                 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, s->device->name);
1491                                         }
1492                                         AST_LIST_REMOVE_CURRENT(list);
1493                                         unistim_free_sub(sub);
1494                                 }
1495                         }
1496                         AST_LIST_TRAVERSE_SAFE_END;
1497                         AST_LIST_UNLOCK(&s->device->subs);
1498
1499                         if (!ast_strlen_zero(s->device->extension_number)) {
1500                                 unregister_extension(s);
1501                         }
1502                         cur->device->session = NULL;
1503                         ast_mutex_unlock(&s->device->lock);
1504                 } else {
1505                         if (unistimdebug) {
1506                                 ast_verb(0, "Freeing an unregistered client\n");
1507                         }
1508                 }
1509                 if (prev) {
1510                         prev->next = cur->next;
1511                 } else {
1512                         sessions = cur->next;
1513                 }
1514                 ast_mutex_destroy(&s->lock);
1515                 ast_free(s);
1516         } else {
1517                 ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
1518         }
1519         ast_mutex_unlock(&sessionlock);
1520         return;
1521 }
1522
1523 /* Return 1 if the session chained link was modified */
1524 static int send_retransmit(struct unistimsession *pte)
1525 {
1526         int i;
1527
1528         ast_mutex_lock(&pte->lock);
1529         if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
1530                 if (unistimdebug) {
1531                         ast_verb(0, "Too many retransmit - freeing client\n");
1532                 }
1533                 ast_mutex_unlock(&pte->lock);
1534                 close_client(pte);
1535                 return 1;
1536         }
1537         pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
1538
1539         for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
1540                  i < pte->last_buf_available; i++) {
1541                 if (i < 0) {
1542                         ast_log(LOG_WARNING,
1543                                         "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%04x last_seq_ack = #0x%04x\n",
1544                                         pte->last_buf_available, (unsigned)pte->seq_server, (unsigned)pte->last_seq_ack);
1545                         continue;
1546                 }
1547
1548                 if (unistimdebug) {
1549                         unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
1550                         unsigned short seq;
1551
1552                         seq = ntohs(sbuf[1]);
1553                         ast_verb(0, "Retransmit slot #%d (seq=#0x%04x), last ack was #0x%04x\n", i,
1554                                                 (unsigned)seq, (unsigned)pte->last_seq_ack);
1555                 }
1556                 send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
1557                                           &pte->sout);
1558         }
1559         ast_mutex_unlock(&pte->lock);
1560         return 0;
1561 }
1562
1563 /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL  : no */
1564 static void send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte,
1565                  const char *text)
1566 {
1567         int i;
1568         BUFFSEND;
1569         if (!text) {
1570                 ast_log(LOG_ERROR, "Asked to display NULL text (pos %d, inverse flag %d)\n", pos, inverse);
1571                 return;
1572         }
1573         if (pte->device && pte->device->height == 1 && pos != TEXT_LINE0) {
1574                 return;
1575         }
1576         if (unistimdebug) {
1577                 ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
1578         }
1579         memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
1580         buffsend[10] = pos;
1581         buffsend[11] = inverse;
1582         i = strlen(text);
1583         if (i > TEXT_LENGTH_MAX) {
1584                 i = TEXT_LENGTH_MAX;
1585         }
1586         memcpy(buffsend + 12, text, i);
1587         send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
1588 }
1589
1590 static void send_text_status(struct unistimsession *pte, const char *text)
1591 {
1592         BUFFSEND;
1593         int i;
1594         if (unistimdebug) {
1595                 ast_verb(0, "Sending status text\n");
1596         }
1597         if (pte->device) {
1598                 if (pte->device->status_method == 1) {  /* For new firmware and i2050 soft phone */
1599                         int n = strlen(text);
1600                         /* Must send individual button separately */
1601                         int j;
1602                         for (i = 0, j = 0; i < 4; i++, j += 7) {
1603                                 int pos = 0x08 + (i * 0x20);
1604                                 memcpy(buffsend + SIZE_HEADER, packet_send_status2,
1605                                            sizeof(packet_send_status2));
1606
1607                                 buffsend[9] = pos;
1608                                 memcpy(buffsend + 10, (j < n) ? (text + j) : "       ", 7);
1609                                 send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
1610                         }
1611                         return;
1612                 }
1613         }
1614
1615         memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
1616         i = strlen(text);
1617         if (i > STATUS_LENGTH_MAX) {
1618                 i = STATUS_LENGTH_MAX;
1619         }
1620         memcpy(buffsend + 10, text, i);
1621         send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
1622
1623 }
1624
1625 static void send_led_update(struct unistimsession *pte, unsigned char led)
1626 {
1627         BUFFSEND;
1628         if (unistimdebug) {
1629                 ast_verb(0, "Sending led_update (%x)\n", (unsigned)led);
1630         }
1631         memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1632         buffsend[9] = led;
1633         send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1634 }
1635
1636 static void send_mute(struct unistimsession *pte, unsigned char mute)
1637 {
1638 /*
1639         0x00 = unmute TX, 0x01 = mute TX
1640         0x20 = unmute RX, 0x21 = mute RX
1641 */
1642         BUFFSEND;
1643         if (unistimdebug) {
1644                 ast_verb(0, "Sending mute packet (%x)\n", (unsigned)mute);
1645         }
1646         memcpy(buffsend + SIZE_HEADER, packet_send_mute, sizeof(packet_send_mute));
1647         buffsend[9] = mute;
1648         send_client(SIZE_HEADER + sizeof(packet_send_mute), buffsend, pte);
1649 }
1650
1651
1652 /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
1653  * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
1654  * mute = MUTE_OFF, MUTE_ON */
1655 static void
1656 send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume,
1657                                  unsigned char mute)
1658 {
1659         BUFFSEND;
1660         int mute_icon = -1;
1661         if (unistimdebug) {
1662                 ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n",
1663                         (unsigned)output, (unsigned)volume, (unsigned)mute);
1664         }
1665         memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1666                    sizeof(packet_send_select_output));
1667         buffsend[9] = output;
1668         if (output == OUTPUT_SPEAKER && volume == VOLUME_LOW) {
1669                 volume = VOLUME_LOW_SPEAKER;
1670         }
1671         buffsend[10] = volume;
1672         if (mute == MUTE_ON_DISCRET) {
1673                 buffsend[11] = MUTE_ON;
1674         } else {
1675                 buffsend[11] = mute;
1676         }
1677         send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1678         if (output == OUTPUT_HANDSET) {
1679                 mute_icon = (mute == MUTE_ON) ? FAV_ICON_ONHOLD_BLACK : FAV_ICON_OFFHOOK_BLACK;
1680                 send_led_update(pte, LED_SPEAKER_OFF);
1681                 send_led_update(pte, LED_HEADPHONE_OFF);
1682         } else if (output == OUTPUT_HEADPHONE) {
1683                 mute_icon = (mute == MUTE_ON)? FAV_ICON_HEADPHONES_ONHOLD : FAV_ICON_HEADPHONES;
1684                 send_led_update(pte, LED_SPEAKER_OFF);
1685                 send_led_update(pte, LED_HEADPHONE_ON);
1686         } else if (output == OUTPUT_SPEAKER) {
1687                 send_led_update(pte, LED_SPEAKER_ON);
1688                 send_led_update(pte, LED_HEADPHONE_OFF);
1689                 if (pte->device->receiver_state == STATE_OFFHOOK) {
1690                         mute_icon = (mute == MUTE_ON)? FAV_ICON_SPEAKER_ONHOLD_BLACK : FAV_ICON_SPEAKER_ONHOOK_BLACK;
1691                 } else {
1692                         mute_icon = (mute == MUTE_ON)? FAV_ICON_SPEAKER_ONHOLD_BLACK : FAV_ICON_SPEAKER_OFFHOOK_BLACK;
1693                 }
1694         } else {
1695                 ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
1696         }
1697         if (mute_icon != -1) {
1698                 change_favorite_icon(pte, mute_icon);
1699         }
1700         if (output != pte->device->output) {
1701                 pte->device->previous_output = pte->device->output;
1702         }
1703         pte->device->output = output;
1704 }
1705 static void send_ring(struct unistimsession *pte, signed char volume, signed char style)
1706 {
1707         BUFFSEND;
1708         if (unistimdebug) {
1709                 ast_verb(0, "Sending ring packet\n");
1710         }
1711         memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1712         buffsend[24] = style + 0x10;
1713         buffsend[29] = volume * 0x10;
1714         send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1715 }
1716
1717 static void send_no_ring(struct unistimsession *pte)
1718 {
1719         BUFFSEND;
1720         if (unistimdebug) {
1721                 ast_verb(0, "Sending no ring packet\n");
1722         }
1723         memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1724         send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1725 }
1726
1727 static void send_texttitle(struct unistimsession *pte, const char *text)
1728 {
1729         BUFFSEND;
1730         int i;
1731         if (unistimdebug) {
1732                 ast_verb(0, "Sending title text\n");
1733         }
1734         memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1735         i = strlen(text);
1736         if (i > 12) {
1737                 i = 12;
1738         }
1739         memcpy(buffsend + 10, text, i);
1740         send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1741 }
1742
1743 static void send_idle_clock(struct unistimsession *pte)
1744 {
1745         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
1746 }
1747
1748 static void send_month_labels(struct unistimsession *pte, int month)
1749 {
1750         BUFFSEND;
1751         char month_name[MONTH_LABEL_SIZE + 1];
1752         int i = 0;
1753         if (unistimdebug) {
1754                 ast_verb(0, "Sending Month Labels\n");
1755         }
1756         month_name[MONTH_LABEL_SIZE] = '\0';
1757         memcpy(buffsend + SIZE_HEADER, packet_send_monthlabels_download, sizeof(packet_send_monthlabels_download));
1758         while (i < 2) {
1759                 memcpy(month_name, &monthlabels[month * MONTH_LABEL_SIZE], MONTH_LABEL_SIZE);
1760                 memcpy(buffsend + SIZE_HEADER + 3 + i*MONTH_LABEL_SIZE, ustmtext(month_name, pte), MONTH_LABEL_SIZE);
1761                 ast_log(LOG_WARNING,"%s\n", month_name);
1762                 ast_log(LOG_WARNING,"%s\n", ustmtext(month_name, pte));
1763                 month = (month + 1)%12;
1764                 i++;
1765         }
1766         send_client(SIZE_HEADER + sizeof(packet_send_monthlabels_download), buffsend, pte);
1767 }
1768
1769
1770 static void send_date_time(struct unistimsession *pte)
1771 {
1772         BUFFSEND;
1773         struct timeval now = ast_tvnow();
1774         struct ast_tm atm = { 0, };
1775
1776         if (unistimdebug) {
1777                 ast_verb(0, "Sending Time & Date\n");
1778         }
1779         memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1780         ast_localtime(&now, &atm, NULL);
1781         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1782         buffsend[11] = (unsigned char) atm.tm_mday;
1783         buffsend[12] = (unsigned char) atm.tm_hour;
1784         buffsend[13] = (unsigned char) atm.tm_min;
1785         send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1786         send_month_labels(pte, atm.tm_mon);
1787 }
1788
1789 static void send_date_time2(struct unistimsession *pte)
1790 {
1791         BUFFSEND;
1792         struct timeval now = ast_tvnow();
1793         struct ast_tm atm = { 0, };
1794
1795         if (unistimdebug) {
1796                 ast_verb(0, "Sending Time & Date #2\n");
1797         }
1798         memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1799         ast_localtime(&now, &atm, NULL);
1800         if (pte->device) {
1801                 buffsend[9] = pte->device->datetimeformat;
1802         } else {
1803                 buffsend[9] = 61;
1804         }
1805         buffsend[14] = (unsigned char) atm.tm_mon + 1;
1806         buffsend[15] = (unsigned char) atm.tm_mday;
1807         buffsend[16] = (unsigned char) atm.tm_hour;
1808         buffsend[17] = (unsigned char) atm.tm_min;
1809         send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1810 }
1811
1812 static void send_date_time3(struct unistimsession *pte)
1813 {
1814         BUFFSEND;
1815         struct timeval now = ast_tvnow();
1816         struct ast_tm atm = { 0, };
1817
1818         if (unistimdebug) {
1819                 ast_verb(0, "Sending Time & Date #3\n");
1820         }
1821         memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1822         ast_localtime(&now, &atm, NULL);
1823         buffsend[10] = (unsigned char) atm.tm_mon + 1;
1824         buffsend[11] = (unsigned char) atm.tm_mday;
1825         buffsend[12] = (unsigned char) atm.tm_hour;
1826         buffsend[13] = (unsigned char) atm.tm_min;
1827         send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1828 }
1829
1830 static void send_blink_cursor(struct unistimsession *pte)
1831 {
1832         BUFFSEND;
1833         if (unistimdebug) {
1834                 ast_verb(0, "Sending set blink\n");
1835         }
1836         memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
1837         send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1838         return;
1839 }
1840
1841 /* pos : 0xab (a=0/2/4 = line ; b = row) */
1842 static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
1843 {
1844         BUFFSEND;
1845         if (unistimdebug) {
1846                 ast_verb(0, "Sending set cursor position\n");
1847         }
1848         memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1849                    sizeof(packet_send_set_pos_cursor));
1850         buffsend[11] = pos;
1851         send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1852         return;
1853 }
1854
1855 static void send_charset_update(struct unistimsession *pte, int charset)
1856 {
1857         const unsigned char* packet_send_charset;
1858         int packet_size;
1859         BUFFSEND;
1860         if (unistimdebug) {
1861                 ast_verb(0, "Sending set default charset\n");
1862         }
1863         if (charset == LANG_DEFAULT) {
1864                 charset = options_languages[find_language(pte->device->language)].encoding;
1865         }
1866         switch (charset) {
1867         case ISO_8859_2:
1868                 packet_send_charset = packet_send_charset_iso_8859_2;
1869                 packet_size = sizeof(packet_send_charset_iso_8859_2);
1870                 break;
1871         case ISO_8859_4:
1872                 packet_send_charset = packet_send_charset_iso_8859_4;
1873                 packet_size = sizeof(packet_send_charset_iso_8859_4);
1874                 break;
1875         case ISO_8859_5:
1876                 packet_send_charset = packet_send_charset_iso_8859_5;
1877                 packet_size = sizeof(packet_send_charset_iso_8859_5);
1878                 break;
1879         case ISO_2022_JP:
1880                 packet_send_charset = packet_send_charset_iso_2022_jp;
1881                 packet_size = sizeof(packet_send_charset_iso_2022_jp);
1882                 break;
1883         case ISO_8859_1:
1884         default:
1885                 packet_send_charset = packet_send_charset_iso_8859_1;
1886                 packet_size = sizeof(packet_send_charset_iso_8859_1);
1887         }
1888         memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size);
1889         send_client(SIZE_HEADER + packet_size, buffsend, pte);
1890         return;
1891 }
1892
1893 static void rcv_resume_connection_with_server(struct unistimsession *pte)
1894 {
1895         BUFFSEND;
1896         if (unistimdebug) {
1897                 ast_verb(0, "ResumeConnectionWithServer received\n");
1898                 ast_verb(0, "Sending packet_send_query_mac_address\n");
1899         }
1900         memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1901                    sizeof(packet_send_query_mac_address));
1902         send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1903         return;
1904 }
1905
1906 static int unistim_register(struct unistimsession *s)
1907 {
1908         struct unistim_device *d;
1909
1910         ast_mutex_lock(&devicelock);
1911         d = devices;
1912         while (d) {
1913                 if (!strcasecmp(s->macaddr, d->id)) {
1914                         /* XXX Deal with IP authentication */
1915                         s->device = d;
1916                         d->session = s;
1917                         d->codec_number = DEFAULT_CODEC;
1918                         d->missed_call = 0;
1919                         d->receiver_state = STATE_ONHOOK;
1920                         break;
1921                 }
1922                 d = d->next;
1923         }
1924         ast_mutex_unlock(&devicelock);
1925
1926         if (!d) {
1927                 return 0;
1928         }
1929
1930         return 1;
1931 }
1932
1933 static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
1934 {
1935         struct ast_format_cap *tmp = src->cap;
1936         memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
1937         src->cap = tmp;
1938         ast_format_cap_append_from_cap(src->cap, dst->cap, AST_MEDIA_TYPE_UNKNOWN);
1939 }
1940
1941 static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
1942 {
1943         if (!l) {
1944                 return NULL;
1945         }
1946         ao2_ref(l->cap, -1);
1947         ast_free(l);
1948         return NULL;
1949 }
1950
1951 static struct unistim_line *unistim_line_alloc(void)
1952 {
1953         struct unistim_line *l;
1954         if (!(l = ast_calloc(1, sizeof(*l)))) {
1955                 return NULL;
1956         }
1957
1958         if (!(l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1959                 ast_free(l);
1960                 return NULL;
1961         }
1962         return l;
1963 }
1964
1965 static int unistim_free_sub(struct unistim_subchannel *sub) {
1966         if (unistimdebug) {
1967                 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, sub->parent->parent->name);
1968         }
1969         ast_mutex_destroy(&sub->lock);
1970         ast_free(sub);
1971         return 0;
1972 }
1973
1974 static struct unistim_subchannel *unistim_alloc_sub(struct unistim_device *d, int x)
1975 {
1976         struct unistim_subchannel *sub;
1977         if (!(sub = ast_calloc(1, sizeof(*sub)))) {
1978                 return NULL;
1979         }
1980
1981         if (unistimdebug) {
1982                 ast_verb(3, "Allocating UNISTIM subchannel #%d on %s ptr=%p\n", x, d->name, sub);
1983         }
1984         sub->ss_thread = AST_PTHREADT_NULL;
1985         sub->subtype = x;
1986         AST_LIST_LOCK(&d->subs);
1987         AST_LIST_INSERT_TAIL(&d->subs, sub, list);
1988         AST_LIST_UNLOCK(&d->subs);
1989         ast_mutex_init(&sub->lock);
1990         return sub;
1991 }
1992
1993 static int unistim_unalloc_sub(struct unistim_device *d, struct unistim_subchannel *sub)
1994 {
1995         struct unistim_subchannel *s;
1996
1997         AST_LIST_LOCK(&d->subs);
1998         AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, s, list) {
1999                 if (!s) {
2000                         continue;
2001                 }
2002                 if (s != sub) {
2003                         continue;
2004                 }
2005                 AST_LIST_REMOVE_CURRENT(list);
2006                 unistim_free_sub(sub);
2007         }
2008         AST_LIST_TRAVERSE_SAFE_END;
2009         AST_LIST_UNLOCK(&d->subs);
2010         return 0;
2011 }
2012
2013 static const char *subtype_tostr(const int type)
2014 {
2015         switch (type) {
2016         case SUB_REAL:
2017                 return "REAL";
2018         case SUB_RING:
2019                 return "RINGING";
2020         case SUB_THREEWAY:
2021                 return "THREEWAY";
2022         }
2023         return "UNKNOWN";
2024 }
2025
2026 static const char *ptestate_tostr(const int type)
2027 {
2028         switch (type) {
2029         case STATE_INIT:
2030                 return "INIT";
2031         case STATE_AUTHDENY:
2032                 return "AUTHDENY";
2033         case STATE_MAINPAGE:
2034                 return "MAINPAGE";
2035         case STATE_EXTENSION:
2036                 return "EXTENSION";
2037         case STATE_DIALPAGE:
2038                 return "DIALPAGE";
2039         case STATE_RINGING:
2040                 return "RINGING";
2041         case STATE_CALL:
2042                 return "CALL";
2043         case STATE_SELECTOPTION:
2044                 return "SELECTOPTION";
2045         case STATE_SELECTCODEC:
2046                 return "SELECTCODEC";
2047         case STATE_SELECTLANGUAGE:
2048                 return "SELECTLANGUAGE";
2049         case STATE_CLEANING:
2050                 return "CLEARING";
2051         case STATE_HISTORY:
2052                 return "HISTORY";
2053         }
2054         return "UNKNOWN";
2055 }
2056
2057 static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
2058 {
2059         BUFFSEND;
2060         int tmp, i = 0;
2061         char addrmac[19];
2062         int res = 0;
2063         for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
2064                 sprintf(&addrmac[i], "%02hhx", buf[tmp]);
2065                 i += 2;
2066         }
2067         if (unistimdebug) {
2068                 ast_verb(0, "MAC Address received: %s\n", addrmac);
2069         }
2070         strcpy(pte->macaddr, addrmac);
2071         res = unistim_register(pte);
2072         if (!res) {
2073                 switch (autoprovisioning) {
2074                 case AUTOPROVISIONING_NO:
2075                         ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
2076                         pte->state = STATE_AUTHDENY;
2077                         break;
2078                 case AUTOPROVISIONING_YES:
2079                         {
2080                                 struct unistim_device *d = NULL, *newd = NULL;
2081                                 struct unistim_line *newl = NULL, *l = NULL;
2082                                 if (unistimdebug) {
2083                                         ast_verb(0, "New phone, autoprovisioning on\n");
2084                                 }
2085                                 /* First : locate the [template] section */
2086                                 ast_mutex_lock(&devicelock);
2087                                 d = devices;
2088                                 while (d) {
2089                                         if (strcasecmp(d->name, "template")) {
2090                                                 d = d->next;
2091                                                 continue;
2092                                         }
2093                                         /* Found, cloning this entry */
2094                                         if (!(newd = ast_malloc(sizeof(*newd)))) {
2095                                                 ast_mutex_unlock(&devicelock);
2096                                                 return;
2097                                         }
2098                                         memcpy(newd, d, sizeof(*newd));
2099                                         ast_mutex_init(&newd->lock);
2100                                         newd->lines.first = NULL;
2101                                         newd->lines.last = NULL;
2102                                         AST_LIST_LOCK(&d->lines);
2103                                         AST_LIST_TRAVERSE(&d->lines, l, list) {
2104                                                 if (!(newl = unistim_line_alloc())) {
2105                                                         break;
2106                                                 }
2107                                                 unistim_line_copy(l, newl);
2108                                                 newl->parent = newd;
2109                                                 ast_copy_string(newl->name, l->name, sizeof(newl->name));
2110                                                 snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
2111                                                                  newl->name, newd->name);
2112                                                 snprintf(l->name, sizeof(l->name), "%d", atoi(l->name) + 1);
2113
2114                                                 AST_LIST_LOCK(&newd->lines);
2115                                                 AST_LIST_INSERT_TAIL(&newd->lines, newl, list);
2116                                                 AST_LIST_UNLOCK(&newd->lines);
2117                                         }
2118                                         AST_LIST_UNLOCK(&d->lines);
2119                                         if (!newl) {
2120                                                 ast_free(newd);
2121                                                 ast_mutex_unlock(&devicelock);
2122                                         }
2123
2124                                         /* Ok, now updating some fields */
2125                                         ast_copy_string(newd->id, addrmac, sizeof(newd->id));
2126                                         ast_copy_string(newd->name, addrmac, sizeof(newd->name));
2127                                         if (newd->extension == EXTENSION_NONE) {
2128                                                 newd->extension = EXTENSION_ASK;
2129                                         }
2130
2131                                         newd->receiver_state = STATE_ONHOOK;
2132                                         newd->session = pte;
2133                                         newd->language[0] = '\0';
2134                                         newd->to_delete = -1;
2135                                         newd->next = NULL;
2136                                         pte->device = newd;
2137
2138                                         /* Go to the end of the linked chain */
2139                                         while (d->next) {
2140                                                 d = d->next;
2141                                         }
2142                                         d->next = newd;
2143                                         d = newd;
2144                                         break;
2145                                 }
2146                                 ast_mutex_unlock(&devicelock);
2147                                 if (!d) {
2148                                         ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
2149                                         pte->state = STATE_AUTHDENY;
2150                                 }
2151                         }
2152                         break;
2153                 case AUTOPROVISIONING_TN:
2154                         pte->state = STATE_AUTHDENY;
2155                         break;
2156                 default:
2157                         ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %u\n",
2158                                         autoprovisioning);
2159                 }
2160         }
2161         if (pte->state != STATE_AUTHDENY) {
2162                 struct unistim_line *line;
2163                 struct unistim_subchannel *sub;
2164
2165                 ast_verb(3, "Device '%s' successfuly registered\n", pte->device->name);
2166
2167                 AST_LIST_LOCK(&pte->device->subs);
2168                 AST_LIST_TRAVERSE_SAFE_BEGIN(&pte->device->subs, sub, list) {
2169                         if (sub) {
2170                                 ast_log(LOG_ERROR, "Subchannel lost sice reboot. Hanged channel may apear!\n");
2171                                 AST_LIST_REMOVE_CURRENT(list);
2172                                 ast_free(sub);
2173                         }
2174                 }
2175                 AST_LIST_TRAVERSE_SAFE_END;
2176                 AST_LIST_UNLOCK(&pte->device->subs);
2177
2178                 switch (pte->device->extension) {
2179                 case EXTENSION_NONE:
2180                         pte->state = STATE_MAINPAGE;
2181                         break;
2182                 case EXTENSION_ASK:
2183                         /* Checking if we already have an extension number */
2184                         if (ast_strlen_zero(pte->device->extension_number)) {
2185                                 pte->state = STATE_EXTENSION;
2186                         } else {
2187                                 /* Yes, because of a phone reboot. We don't ask again for the TN */
2188                                 if (register_extension(pte)) {
2189                                         pte->state = STATE_EXTENSION;
2190                                 } else {
2191                                         pte->state = STATE_MAINPAGE;
2192                                 }
2193                         }
2194                         break;
2195                 case EXTENSION_LINE:
2196                         line = AST_LIST_FIRST(&pte->device->lines);
2197                         ast_copy_string(pte->device->extension_number, line->name,
2198                                                         sizeof(pte->device->extension_number));
2199                         if (register_extension(pte)) {
2200                                 pte->state = STATE_EXTENSION;
2201                         } else {
2202                                 pte->state = STATE_MAINPAGE;
2203                         }
2204                         break;
2205                 case EXTENSION_TN:
2206                         /* If we are here, it's because of a phone reboot */
2207                         pte->state = STATE_MAINPAGE;
2208                         break;
2209                 default:
2210                         ast_log(LOG_WARNING, "Internal error, extension value unknown : %u\n",
2211                                         pte->device->extension);
2212                         pte->state = STATE_AUTHDENY;
2213                         break;
2214                 }
2215         }
2216         if (pte->state == STATE_EXTENSION) {
2217                 if (pte->device->extension != EXTENSION_TN) {
2218                         pte->device->extension = EXTENSION_ASK;
2219                 }
2220                 pte->device->extension_number[0] = '\0';
2221         }
2222         if (unistimdebug) {
2223                 ast_verb(0, "\nSending S1\n");
2224         }
2225         memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
2226         send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
2227
2228         if (unistimdebug) {
2229                 ast_verb(0, "Sending query_basic_manager_04\n");
2230         }
2231         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
2232                    sizeof(packet_send_query_basic_manager_04));
2233         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
2234
2235         if (unistimdebug) {
2236                 ast_verb(0, "Sending query_basic_manager_10\n");
2237         }
2238         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
2239                    sizeof(packet_send_query_basic_manager_10));
2240         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
2241
2242         send_date_time(pte);
2243         return;
2244 }
2245
2246 static int write_entry_history(struct unistimsession *pte, FILE * f, char c, char *line1)
2247 {
2248         if (fwrite(&c, 1, 1, f) != 1) {
2249                 display_last_error("Unable to write history log header.");
2250                 return -1;
2251         }
2252         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
2253                 display_last_error("Unable to write history entry - date.");
2254                 return -1;
2255         }
2256         if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
2257                 display_last_error("Unable to write history entry - callerid.");
2258                 return -1;
2259         }
2260         if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
2261                 display_last_error("Unable to write history entry - callername.");
2262                 return -1;
2263         }
2264         return 0;
2265 }
2266
2267 static int write_history(struct unistimsession *pte, char way, char ismissed)
2268 {
2269         char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
2270         char line1[TEXT_LENGTH_MAX + 1];
2271         char count = 0, *histbuf;
2272         int size;
2273         FILE *f, *f2;
2274         struct timeval now = ast_tvnow();
2275         struct ast_tm atm = { 0, };
2276
2277         if (!pte->device) {
2278                 return -1;
2279         }
2280         if (!pte->device->callhistory) {
2281                 return 0;
2282         }
2283         if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
2284                 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
2285                                 pte->device->name);
2286                 return -1;
2287         }
2288
2289         snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
2290         if (ast_mkdir(tmp, 0770)) {
2291                 ast_log(LOG_WARNING, "Unable to create directory for history\n");
2292                 return -1;
2293         }
2294
2295         ast_localtime(&now, &atm, NULL);
2296         if (ismissed) {
2297                 if (way == 'i') {
2298                         ast_copy_string(tmp2, ustmtext("Miss", pte), sizeof(tmp2));
2299                 } else {
2300                         ast_copy_string(tmp2, ustmtext("Fail", pte), sizeof(tmp2));
2301                 }
2302         } else {
2303                 ast_copy_string(tmp2, ustmtext("Answ", pte), sizeof(tmp2));
2304         }
2305         snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
2306                          atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
2307                          atm.tm_min, atm.tm_sec, tmp2);
2308
2309         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
2310                          USTM_LOG_DIR, pte->device->name, way);
2311         if ((f = fopen(tmp, "r"))) {
2312                 struct stat bufstat;
2313
2314                 if (stat(tmp, &bufstat)) {
2315                         display_last_error("Unable to stat history log.");
2316                         fclose(f);
2317                         return -1;
2318                 }
2319                 size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
2320                 if (bufstat.st_size != size) {
2321                         ast_log(LOG_WARNING,
2322                                         "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
2323                                         tmp, (int) bufstat.st_size, size);
2324                         fclose(f);
2325                         f = NULL;
2326                         count = 1;
2327                 }
2328         }
2329
2330         /* If we can't open the log file, we create a brand new one */
2331         if (!f) {
2332                 char c = 1;
2333                 int i;
2334
2335                 if ((errno != ENOENT) && (count == 0)) {
2336                         display_last_error("Unable to open history log.");
2337                         return -1;
2338                 }
2339                 f = fopen(tmp, "w");
2340                 if (!f) {
2341                         display_last_error("Unable to create history log.");
2342                         return -1;
2343                 }
2344                 if (write_entry_history(pte, f, c, line1)) {
2345                         fclose(f);
2346                         return -1;
2347                 }
2348                 memset(line1, ' ', TEXT_LENGTH_MAX);
2349                 for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
2350                         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
2351                                 display_last_error("Unable to write history entry - stuffing.");
2352                                 fclose(f);
2353                                 return -1;
2354                         }
2355                 }
2356                 if (fclose(f)) {
2357                         display_last_error("Unable to close history - creation.");
2358                 }
2359                 return 0;
2360         }
2361         /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
2362         if (fread(&count, 1, 1, f) != 1) {
2363                 display_last_error("Unable to read history header.");
2364                 fclose(f);
2365                 return -1;
2366         }
2367         if (count > MAX_ENTRY_LOG) {
2368                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
2369                                 count, MAX_ENTRY_LOG);
2370                 fclose(f);
2371                 return -1;
2372         }
2373         snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
2374                          USTM_LOG_DIR, pte->device->name, way);
2375         if (!(f2 = fopen(tmp2, "w"))) {
2376                 display_last_error("Unable to create temporary history log.");
2377                 fclose(f);
2378                 return -1;
2379         }
2380
2381         if (++count > MAX_ENTRY_LOG) {
2382                 count = MAX_ENTRY_LOG;
2383         }
2384         if (write_entry_history(pte, f2, count, line1)) {
2385                 fclose(f);
2386                 fclose(f2);
2387                 return -1;
2388         }
2389         size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
2390         if (!(histbuf = ast_malloc(size))) {
2391                 fclose(f);
2392                 fclose(f2);
2393                 return -1;
2394         }
2395
2396         if (fread(histbuf, size, 1, f) != 1) {
2397                 ast_free(histbuf);
2398                 fclose(f);
2399                 fclose(f2);
2400                 display_last_error("Unable to read previous history entries.");
2401                 return -1;
2402         }
2403         if (fwrite(histbuf, size, 1, f2) != 1) {
2404                 ast_free(histbuf);
2405                 fclose(f);
2406                 fclose(f2);
2407                 display_last_error("Unable to write previous history entries.");
2408                 return -1;
2409         }
2410         ast_free(histbuf);
2411         if (fclose(f)) {
2412                 display_last_error("Unable to close history log.");
2413         }
2414         if (fclose(f2)) {
2415                 display_last_error("Unable to close temporary history log.");
2416         }
2417         if (unlink(tmp)) {
2418                 display_last_error("Unable to remove old history log.");
2419         }
2420         if (rename(tmp2, tmp)) {
2421                 display_last_error("Unable to rename new history log.");
2422         }
2423         return 0;
2424 }
2425
2426 static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
2427 {
2428         RAII_VAR(struct ast_channel *, chana, NULL, ast_channel_unref);
2429         RAII_VAR(struct ast_channel *, chanb, NULL, ast_channel_unref);
2430
2431         if (!p1->owner || !p2->owner) {
2432                 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
2433                 return -1;
2434         }
2435         chana = ast_channel_ref(p1->owner);
2436         chanb = ast_channel_ref(p2->owner);
2437
2438         switch (ast_bridge_transfer_attended(chana, chanb)) {
2439         case AST_BRIDGE_TRANSFER_INVALID:
2440                 ast_log(LOG_WARNING, "Transfer failed. Invalid bridge setup\n");
2441                 break;
2442         case AST_BRIDGE_TRANSFER_NOT_PERMITTED:
2443                 ast_log(LOG_WARNING, "Transfer not permitted\n");
2444                 break;
2445         case AST_BRIDGE_TRANSFER_FAIL:
2446                 ast_log(LOG_WARNING, "Transfer encountered internal error\n");
2447                 break;
2448         case AST_BRIDGE_TRANSFER_SUCCESS:
2449                 return 0;
2450         }
2451
2452         /* Control only reaches this point if transfer has failed */
2453         ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
2454         ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
2455         return -1;
2456 }
2457
2458 void change_callerid(struct unistimsession *pte, int type, char *callerid)
2459 {
2460         char *data;
2461         int size;
2462
2463         if (type) {
2464                 data = pte->device->lst_cnm;
2465         } else {
2466                 data = pte->device->lst_cid;
2467         }
2468
2469         /* This is very nearly strncpy(), except that the remaining buffer
2470          * is padded with ' ', instead of '\0' */
2471         memset(data, ' ', TEXT_LENGTH_MAX);
2472         size = strlen(callerid);
2473         if (size > TEXT_LENGTH_MAX) {
2474                 size = TEXT_LENGTH_MAX;
2475         }
2476         memcpy(data, callerid, size);
2477 }
2478
2479 static struct unistim_subchannel* get_sub(struct unistim_device *device, int type)
2480 {
2481         struct unistim_subchannel *sub = NULL;
2482
2483         AST_LIST_LOCK(&device->subs);
2484         AST_LIST_TRAVERSE(&device->subs, sub, list) {
2485                 if (!sub) {
2486                         continue;
2487                 }
2488                 if (sub->subtype == type) {
2489                         break;
2490                 }
2491         }
2492         AST_LIST_UNLOCK(&device->subs);
2493
2494         return sub;
2495 }
2496
2497 static struct unistim_subchannel* get_sub_holding(struct unistim_device *device, int type, int holding)
2498 {
2499         struct unistim_subchannel *sub = NULL;
2500
2501         AST_LIST_LOCK(&device->subs);
2502         AST_LIST_TRAVERSE(&device->subs, sub, list) {
2503                 if (!sub) {
2504                         continue;
2505                 }
2506                 if (sub->subtype == type && sub->holding == holding) {
2507                         break;
2508                 }
2509         }
2510         AST_LIST_UNLOCK(&device->subs);
2511
2512         return sub;
2513 }
2514
2515 static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
2516 {
2517         /* Silence our channel */
2518         if (!pte->device->silence_generator) {
2519                 pte->device->silence_generator =
2520                         ast_channel_start_silence_generator(sub->owner);
2521                 if (pte->device->silence_generator == NULL) {
2522                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2523                 } else if (unistimdebug) {
2524                         ast_verb(0, "Starting silence generator\n");
2525                 }
2526         }
2527
2528 }
2529
2530 static void sub_stop_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
2531 {
2532         /* Stop the silence generator */
2533         if (pte->device->silence_generator) {
2534                 if (unistimdebug) {
2535                         ast_verb(0, "Stopping silence generator\n");
2536                 }
2537                 if (sub->owner) {
2538                         ast_channel_stop_silence_generator(sub->owner, pte->device->silence_generator);
2539                 } else {
2540                         ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel!\n");
2541                 }
2542                 pte->device->silence_generator = NULL;
2543         }
2544 }
2545
2546 static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub)
2547 {
2548         if (!sub) {
2549                 return;
2550         }
2551         sub->moh = 1;
2552         sub->holding = 1;
2553         send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte);
2554         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2555         send_stop_timer(pte);
2556         if (sub->owner) {
2557                 ast_queue_hold(sub->owner, NULL);
2558         }
2559         return;
2560 }
2561
2562 static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *sub)
2563 {
2564         struct unistim_subchannel *sub_real;
2565
2566         sub_real = get_sub(pte->device, SUB_REAL);
2567         if (sub_real) {
2568             sub_hold(pte, sub_real);
2569         }
2570
2571         sub->moh = 0;
2572         sub->holding = 0;
2573         send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte);
2574         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2575         send_start_timer(pte);
2576         if (sub->owner) {
2577                 ast_queue_unhold(sub->owner);
2578                 if (sub->rtp) {
2579                         send_start_rtp(sub);
2580                 }
2581         }
2582         return;
2583 }
2584
2585 static void close_call(struct unistimsession *pte)
2586 {
2587         struct unistim_subchannel *sub, *sub_transf;
2588
2589         sub = get_sub(pte->device, SUB_REAL);
2590         sub_transf = get_sub(pte->device, SUB_THREEWAY);
2591         send_stop_timer(pte);
2592         if (!sub) {
2593                 ast_log(LOG_WARNING, "Close call without sub\n");
2594                 return;
2595         }
2596         send_favorite_short(sub->softkey, FAV_LINE_ICON, pte);
2597         if (sub->owner) {
2598                 sub->alreadygone = 1;
2599                 if (sub_transf) {
2600                         sub_transf->alreadygone = 1;
2601                         if (attempt_transfer(sub, sub_transf) < 0) {
2602                                 ast_verb(0, "attempt_transfer failed.\n");
2603                         }
2604                 } else {
2605                         ast_queue_hangup(sub->owner);
2606                 }
2607         } else {
2608                 if (sub_transf) {
2609                         if (sub_transf->owner) {
2610                                 ast_queue_hangup_with_cause(sub_transf->owner, AST_CAUSE_NORMAL_CLEARING);
2611                         } else {
2612                                 ast_log(LOG_WARNING, "threeway sub without owner\n");
2613                         }
2614                 } else {
2615                         ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2616                                                 pte->device->name, sub->softkey);
2617                 }
2618         }
2619         change_callerid(pte, 0, pte->device->redial_number);
2620         change_callerid(pte, 1, "");
2621         write_history(pte, 'o', pte->device->missed_call);
2622         pte->device->missed_call = 0;
2623         show_main_page(pte);
2624         return;
2625 }
2626
2627 static void ignore_call(struct unistimsession *pte)
2628 {
2629         send_no_ring(pte);
2630         return;
2631 }
2632
2633 static void discard_call(struct unistimsession *pte)
2634 {
2635         struct unistim_subchannel* sub;
2636         sub = get_sub(pte->device, SUB_RING);
2637         if (!sub) {
2638             return;
2639         }
2640
2641         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
2642         return;
2643 }
2644
2645 static void *unistim_ss(void *data)
2646 {
2647         struct ast_channel *chan = data;
2648         struct unistim_subchannel *sub = ast_channel_tech_pvt(chan);
2649         struct unistim_line *l = sub->parent;
2650         struct unistimsession *s = l->parent->session;
2651         int res;
2652
2653         if (!s) {
2654                 return NULL;
2655         }
2656         ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
2657         ast_channel_lock(chan);
2658         ast_channel_exten_set(chan, s->device->phone_number);
2659         ast_setstate(chan, AST_STATE_RING);
2660         ast_channel_unlock(chan);
2661         ast_copy_string(s->device->redial_number, s->device->phone_number,
2662                                         sizeof(s->device->redial_number));
2663         res = ast_pbx_run(chan);
2664         if (res) {
2665                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2666                 send_tone(s, 1000, 0);
2667         }
2668         return NULL;
2669 }
2670
2671 static int find_rtp_port(struct unistim_subchannel *s)
2672 {
2673         struct unistim_subchannel *sub = NULL;
2674         int rtp_start = s->parent->parent->rtp_port;
2675         struct ast_sockaddr us_tmp;
2676         struct sockaddr_in us = { 0, };
2677
2678         AST_LIST_LOCK(&s->parent->parent->subs);
2679         AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) {
2680                 if (!sub) {
2681                         continue;
2682                 }
2683                 if (sub->rtp) {
2684                         ast_rtp_instance_get_remote_address(sub->rtp, &us_tmp);
2685                         ast_sockaddr_to_sin(&us_tmp, &us);
2686                         if (htons(us.sin_port)) {
2687                                 rtp_start = htons(us.sin_port) + 1;
2688                                 break;
2689                         }
2690                 }
2691         }
2692         AST_LIST_UNLOCK(&s->parent->parent->subs);
2693         return rtp_start;
2694 }
2695
2696 static void send_start_rtp(struct unistim_subchannel *sub)
2697 {
2698         BUFFSEND;
2699
2700         int codec;
2701         struct sockaddr_in public = { 0, };
2702         struct sockaddr_in us = { 0, };
2703         struct sockaddr_in sin = { 0, };
2704         struct ast_sockaddr us_tmp;
2705         struct ast_sockaddr sin_tmp;
2706         struct unistimsession *pte;
2707
2708         ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
2709         ast_sockaddr_to_sin(&us_tmp, &us);
2710         ast_rtp_instance_get_remote_address(sub->rtp, &sin_tmp);
2711         ast_sockaddr_to_sin(&sin_tmp, &sin);
2712
2713         /* Setting up RTP of the phone */
2714         if (public_ip.sin_family == 0) {  /* NAT IP override ?   */
2715                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2716         } else {
2717                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2718         }
2719         if (unistimdebug) {
2720                 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
2721                          ast_inet_ntoa(us.sin_addr),
2722                          htons(us.sin_port), ast_format_get_name(ast_channel_readformat(sub->owner)));
2723                 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2724                                         ast_inet_ntoa(public.sin_addr));
2725         }
2726
2727         pte = sub->parent->parent->session;
2728         codec = ast_rtp_codecs_payload_code_tx(ast_rtp_instance_get_codecs(sub->rtp),
2729                 1, ast_channel_readformat(sub->owner), 0);
2730         if ((ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) ||
2731                 (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_alaw) == AST_FORMAT_CMP_EQUAL)) {
2732                 if (unistimdebug) {
2733                         ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2734                 }
2735                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2736                            sizeof(packet_send_rtp_packet_size));
2737                 buffsend[10] = (int) codec & 0xffffffffLL;
2738                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte);
2739         }
2740         if (unistimdebug) {
2741                 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2742         }
2743         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2744                    sizeof(packet_send_jitter_buffer_conf));
2745         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte);
2746         if (pte->device->rtp_method != 0) {
2747                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2748
2749                 if (unistimdebug) {
2750                         ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method);
2751                 }
2752                 if (pte->device->rtp_method == 3) {
2753                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2754                                    sizeof(packet_send_open_audio_stream_tx3));
2755                 } else {
2756                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2757                                    sizeof(packet_send_open_audio_stream_tx));
2758                 }
2759                 if (pte->device->rtp_method != 2) {
2760                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2761                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2762                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2763                         buffsend[23] = (rtcpsin_port & 0x00ff);
2764                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2765                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2766                         buffsend[24] = (us.sin_port & 0x00ff);
2767                         buffsend[27] = (rtcpsin_port & 0x00ff);
2768                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2769                 } else {
2770                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2771                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2772                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2773                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2774                         buffsend[19] = (us.sin_port & 0x00ff);
2775                 }
2776                 buffsend[11] = codec; /* rx */
2777                 buffsend[12] = codec; /* tx */
2778                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend, pte);
2779
2780                 if (unistimdebug) {
2781                         ast_verb(0, "Sending OpenAudioStreamRX\n");
2782                 }
2783                 if (pte->device->rtp_method == 3) {
2784                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2785                                    sizeof(packet_send_open_audio_stream_rx3));
2786                 } else {
2787                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2788                                    sizeof(packet_send_open_audio_stream_rx));
2789                 }
2790                 if (pte->device->rtp_method != 2) {
2791                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2792                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2793                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2794                         buffsend[23] = (rtcpsin_port & 0x00ff);
2795                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2796                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2797                         buffsend[24] = (us.sin_port & 0x00ff);
2798                         buffsend[27] = (rtcpsin_port & 0x00ff);
2799                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2800                 } else {
2801                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2802                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2803                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2804                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2805                         buffsend[19] = (us.sin_port & 0x00ff);
2806                 }
2807                 buffsend[11] = codec; /* rx */
2808                 buffsend[12] = codec; /* tx */
2809                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend, pte);
2810         } else {
2811                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2812
2813                 if (unistimdebug) {
2814                         ast_verb(0, "Sending packet_send_call default method\n");
2815                 }
2816
2817                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2818                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2819                 /* Destination port when sending RTP */
2820                 buffsend[49] = (us.sin_port & 0x00ff);
2821                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2822                 /* Destination port when sending RTCP */
2823                 buffsend[52] = (rtcpsin_port & 0x00ff);
2824                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2825                 /* Codec */
2826                 buffsend[40] = codec;
2827                 buffsend[41] = codec;
2828                 if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
2829                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2830                 } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_alaw) == 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_g723) == AST_FORMAT_CMP_EQUAL) {
2833                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2834                 } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
2835                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2836                 } else {
2837                         ast_log(LOG_WARNING, "Unsupported codec %s!\n",
2838                                 ast_format_get_name(ast_channel_readformat(sub->owner)));
2839                 }
2840                 /* Source port for transmit RTP and Destination port for receiving RTP */
2841                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2842                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2843                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2844                 buffsend[48] = (rtcpsin_port & 0x00ff);
2845                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte);
2846         }
2847 }
2848
2849 static void start_rtp(struct unistim_subchannel *sub)
2850 {
2851         struct sockaddr_in sin = { 0, };
2852         struct sockaddr_in sout = { 0, };
2853         struct ast_sockaddr sin_tmp;
2854         struct ast_sockaddr sout_tmp;
2855
2856         /* Sanity checks */
2857         if (!sub) {
2858                 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2859                 return;
2860         }
2861         if (!sub->parent) {
2862                 ast_log(LOG_WARNING, "start_rtp with a null line!\n");
2863                 return;
2864         }
2865         if (!sub->parent->parent) {
2866                 ast_log(LOG_WARNING, "start_rtp with a null device!\n");
2867                 return;
2868         }
2869         if (!sub->parent->parent->session) {
2870                 ast_log(LOG_WARNING, "start_rtp with a null session!\n");
2871                 return;
2872         }
2873         if (!sub->owner) {
2874                 ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n");
2875                 return;
2876         }
2877         sout = sub->parent->parent->session->sout;
2878         ast_mutex_lock(&sub->lock);
2879         /* Allocate the RTP */
2880         if (unistimdebug) {
2881                 ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2882         }
2883         ast_sockaddr_from_sin(&sout_tmp, &sout);
2884         sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
2885         if (!sub->rtp) {
2886                 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2887                                 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2888                 ast_mutex_unlock(&sub->lock);
2889                 return;
2890         }
2891         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
2892         ast_rtp_instance_set_channel_id(sub->rtp, ast_channel_uniqueid(sub->owner));
2893         ast_channel_internal_fd_set(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
2894         ast_channel_internal_fd_set(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
2895         ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2896         ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
2897
2898         /* Create the RTP connection */
2899         sin.sin_family = AF_INET;
2900         /* Setting up RTP for our side */
2901         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2902                    sizeof(sin.sin_addr));
2903
2904         sin.sin_port = htons(find_rtp_port(sub));
2905         ast_sockaddr_from_sin(&sin_tmp, &sin);
2906         ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
2907         if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(sub->owner), ast_channel_readformat(sub->owner)) == AST_FORMAT_CMP_NOT_EQUAL) {
2908                 struct ast_format *tmpfmt;
2909                 struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
2910
2911                 tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(sub->owner), 0);
2912                 ast_log(LOG_WARNING,
2913                                 "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
2914                                 ast_format_get_name(ast_channel_readformat(sub->owner)),
2915                                 ast_format_get_name(tmpfmt),
2916                                 ast_format_cap_get_names(ast_channel_nativeformats(sub->owner), &cap_buf));
2917
2918                 ast_channel_set_readformat(sub->owner, tmpfmt);
2919                 ast_channel_set_writeformat(sub->owner, tmpfmt);
2920         ao2_ref(tmpfmt, -1);
2921         }
2922         send_start_rtp(sub);
2923         ast_mutex_unlock(&sub->lock);
2924 }
2925
2926 static void send_dial_tone(struct unistimsession *pte)
2927 {
2928         struct ast_tone_zone_sound *ts = NULL;
2929         struct ast_tone_zone_part tone_data;
2930         char *s = NULL;
2931         char *ind;
2932
2933         if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) {
2934                 ind = ast_strdupa(ts->data);
2935                 s = strsep(&ind, ",");
2936                 ast_tone_zone_part_parse(s, &tone_data);
2937                 send_tone(pte, tone_data.freq1, tone_data.freq2);
2938                 if (unistimdebug) {
2939                         ast_verb(0, "Country code found (%s), freq1=%u freq2=%u\n",
2940                                                         pte->device->tz->country, tone_data.freq1, tone_data.freq2);
2941                 }
2942                 ts = ast_tone_zone_sound_unref(ts);
2943         }
2944 }
2945
2946 static void show_phone_number(struct unistimsession *pte)
2947 {
2948         char tmp[TEXT_LENGTH_MAX + 1];
2949         const char *tmp_number = ustmtext("Number:", pte);
2950         int line, tmp_copy, offset = 0, i;
2951
2952         pte->device->phone_number[pte->device->size_phone_number] = '\0';
2953         if  (pte->device->size_phone_number > MAX_SCREEN_NUMBER) {
2954                 offset = pte->device->size_phone_number - MAX_SCREEN_NUMBER - 1;
2955                 if (offset > strlen(tmp_number)) {
2956                         offset = strlen(tmp_number);
2957                 }
2958                 tmp_copy = strlen(tmp_number) - offset + 1;
2959                 if (tmp_copy > sizeof(tmp)) {
2960                         tmp_copy = sizeof(tmp);
2961                 }
2962                 memcpy(tmp, tmp_number + offset, tmp_copy);
2963         } else {
2964                 ast_copy_string(tmp, tmp_number, sizeof(tmp));
2965         }
2966
2967         offset = (pte->device->size_phone_number >= TEXT_LENGTH_MAX) ? (pte->device->size_phone_number - TEXT_LENGTH_MAX +1) : 0;
2968         if (pte->device->size_phone_number) {
2969                 memcpy(tmp + strlen(tmp), pte->device->phone_number + offset, pte->device->size_phone_number - offset + 1);
2970         }
2971         offset = strlen(tmp);
2972
2973         for (i = strlen(tmp); i < TEXT_LENGTH_MAX; i++) {
2974                 tmp[i] = '.';
2975         }
2976         tmp[i] = '\0';
2977
2978         line = (pte->device->height == 1) ? TEXT_LINE0 : TEXT_LINE2;
2979         send_text(line, TEXT_NORMAL, pte, tmp);
2980         send_blink_cursor(pte);
2981         send_cursor_pos(pte, (unsigned char) (line + offset));
2982         send_led_update(pte, LED_BAR_OFF);
2983 }
2984
2985 static void handle_dial_page(struct unistimsession *pte)
2986 {
2987         pte->state = STATE_DIALPAGE;
2988         if (pte->device->call_forward[0] == -1) {
2989                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2990                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte));
2991                 send_text_status(pte, ustmtext("Fwd    Cancel BackSp Erase", pte));
2992                 if (pte->device->call_forward[1] != 0) {
2993                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2994                                                         sizeof(pte->device->phone_number));
2995                         show_phone_number(pte);
2996                         send_led_update(pte, LED_BAR_OFF);
2997                         return;
2998                 }
2999         } else {
3000                 if ((pte->device->output == OUTPUT_HANDSET) &&
3001                         (pte->device->receiver_state == STATE_ONHOOK)) {
3002                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
3003                 } else {
3004                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
3005                 }
3006                 send_dial_tone(pte);
3007
3008                 if (pte->device->height > 1) {
3009                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte));
3010                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte));
3011                 }
3012                 if (ast_strlen_zero(pte->device->redial_number)) {
3013                         send_text_status(pte, ustmtext("Call          BackSp Erase", pte));
3014                 } else {
3015                         send_text_status(pte, ustmtext("Call   Redial BackSp Erase", pte));
3016                 }
3017         }
3018
3019         pte->device->size_phone_number = 0;
3020         pte->device->phone_number[0] = 0;
3021         show_phone_number(pte);
3022         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
3023         send_icon(TEXT_LINE0, FAV_ICON_NONE, pte);
3024         pte->device->missed_call = 0;
3025         send_led_update(pte, LED_BAR_OFF);
3026         pte->device->lastmsgssent = -1;
3027         return;
3028 }
3029
3030 static void swap_subs(struct unistim_subchannel *a, struct unistim_subchannel *b)
3031 {
3032         struct ast_rtp_instance *rtp;
3033         int fds;
3034
3035         if (unistimdebug) {
3036                 ast_verb(0, "Swapping %p and %p\n", a, b);
3037         }
3038         if ((!a->owner) || (!b->owner)) {
3039                 ast_log(LOG_WARNING,
3040                                 "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n",
3041                                 a, a->owner, b, b->owner);
3042                 return;
3043         }
3044         rtp = a->rtp;
3045         a->rtp = b->rtp;
3046         b->rtp = rtp;
3047
3048         fds = ast_channel_fd(a->owner, 0);
3049         ast_channel_internal_fd_set(a->owner, 0, ast_channel_fd(b->owner, 0));
3050         ast_channel_internal_fd_set(b->owner, 0, fds);
3051
3052         fds = ast_channel_fd(a->owner, 1);
3053         ast_channel_internal_fd_set(a->owner, 1, ast_channel_fd(b->owner, 1));
3054         ast_channel_internal_fd_set(b->owner, 1, fds);
3055 }
3056
3057 /* Step 1 : Music On Hold for peer, Dialing screen for us */
3058 static void transfer_call_step1(struct unistimsession *pte)
3059 {
3060         struct unistim_subchannel *sub /*, *sub_trans */;
3061         struct unistim_device *d = pte->device;
3062
3063         sub = get_sub(d, SUB_REAL);
3064         /* sub_trans = get_sub(d, SUB_THREEWAY); */
3065
3066         if (!sub || !sub->owner) {
3067                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3068                 return;
3069         }
3070         /* Start music on hold if appropriate */
3071         if (sub->moh) {
3072                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
3073         } else {
3074                 ast_queue_hold(sub->owner, sub->parent->musicclass);
3075                 sub->moh = 1;
3076                 sub->subtype = SUB_THREEWAY;
3077         }
3078         sub_start_silence(pte, sub);
3079         handle_dial_page(pte);
3080 }
3081
3082 static void transfer_cancel_step2(struct unistimsession *pte)
3083 {
3084         struct unistim_subchannel *sub, *sub_trans;
3085         struct unistim_device *d = pte->device;
3086
3087         sub = get_sub(d, SUB_REAL);
3088         sub_trans = get_sub(d, SUB_THREEWAY);
3089
3090         if (!sub || !sub->owner) {
3091                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3092                 return;
3093         }
3094         if (sub_trans) {
3095                 if (unistimdebug) {
3096                         ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
3097                 }
3098                 if (sub->owner) {
3099                         swap_subs(sub, sub_trans);
3100                         ast_queue_unhold(sub_trans->owner);
3101                         sub_trans->moh = 0;
3102                         sub_trans->subtype = SUB_REAL;
3103                         sub->subtype = SUB_THREEWAY;
3104                         ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
3105                 } else {
3106                         ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
3107                 }