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