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