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