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