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