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