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