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