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