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