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