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