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