another few errno.h removals
[asterisk/asterisk.git] / channels / chan_unistim.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * UNISTIM channel driver for asterisk
5  *
6  * Copyright (C) 2005 - 2007, Cedric Hans
7  * 
8  * Cedric Hans <cedric.hans@mlkj.net>
9  *
10  * Asterisk 1.4 patch by Peter Be
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20  * at the top of the source tree.
21  */
22
23 /*!
24  * \file
25  *
26  * \brief chan_unistim channel driver for Asterisk
27  * \author Cedric Hans <cedric.hans@mlkj.net>
28  *
29  * Unistim (Unified Networks IP Stimulus) channel driver
30  * for Nortel i2002, i2004 and i2050
31  *
32  * \ingroup channel_drivers
33  */
34
35 #include "asterisk.h"
36
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38
39 #include <sys/socket.h>
40 #include <sys/ioctl.h>
41 #include <sys/stat.h>
42 #include <net/if.h>
43 #include <fcntl.h>
44 #include <netdb.h>
45 #include <sys/signal.h>
46 #include <signal.h>
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/ip.h>
50 #include <arpa/inet.h>
51 #include <ctype.h>
52
53 #include "asterisk/lock.h"
54 #include "asterisk/channel.h"
55 #include "asterisk/config.h"
56 #include "asterisk/module.h"
57 #include "asterisk/pbx.h"
58 #include "asterisk/options.h"
59 #include "asterisk/sched.h"
60 #include "asterisk/io.h"
61 #include "asterisk/rtp.h"
62 #include "asterisk/acl.h"
63 #include "asterisk/callerid.h"
64 #include "asterisk/cli.h"
65 #include "asterisk/say.h"
66 #include "asterisk/cdr.h"
67 #include "asterisk/astdb.h"
68 #include "asterisk/features.h"
69 #include "asterisk/app.h"
70 #include "asterisk/musiconhold.h"
71 #include "asterisk/utils.h"
72 #include "asterisk/causes.h"
73 #include "asterisk/indications.h"
74 #include "asterisk/dsp.h"
75 #include "asterisk/devicestate.h"
76 #include "asterisk/stringfields.h"
77 #include "asterisk/abstract_jb.h"
78 #include "asterisk/event.h"
79
80 /*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */
81 #define CAPABILITY AST_FORMAT_ALAW | AST_FORMAT_ULAW    /* | AST_FORMAT_G729A | AST_FORMAT_G723_1 */
82
83 #define DEFAULTCONTEXT    "default"
84 #define DEFAULTCALLERID  "Unknown"
85 #define DEFAULTCALLERNAME       " "
86 #define USTM_LOG_DIR        "unistimHistory"
87
88 /*! Size of the transmit buffer */
89 #define MAX_BUF_SIZE        64
90 /*! Number of slots for the transmit queue */
91 #define MAX_BUF_NUMBER    50
92 /*! Try x times before removing the phone */
93 #define NB_MAX_RETRANSMIT       8
94 /*! Nb of milliseconds waited when no events are scheduled */
95 #define IDLE_WAIT              1000
96 /*! Wait x milliseconds before resending a packet */
97 #define RETRANSMIT_TIMER        2000
98 /*! How often the mailbox is checked for new messages */
99 #define TIMER_MWI              10000
100 /*! Not used */
101 #define DEFAULT_CODEC      0x00
102 #define SIZE_PAGE              4096
103 #define DEVICE_NAME_LEN  16
104 #define AST_CONFIG_MAX_PATH     255
105 #define MAX_ENTRY_LOG      30
106
107 #define SUB_REAL                0
108 #define SUB_THREEWAY        1
109 #define MAX_SUBS                2
110
111 enum autoprovision {
112         AUTOPROVISIONING_NO = 0,
113         AUTOPROVISIONING_YES,
114         AUTOPROVISIONING_DB,
115         AUTOPROVISIONING_TN
116 };
117
118 enum autoprov_extn {
119         /*! Do not create an extension into the default dialplan */
120         EXTENSION_NONE = 0,
121         /*! Prompt user for an extension number and register it */
122         EXTENSION_ASK,
123         /*! Register an extension with the line=> value */
124         EXTENSION_LINE,
125         /*! Used with AUTOPROVISIONING_TN */
126         EXTENSION_TN
127 };
128 #define OUTPUT_HANDSET    0xC0
129 #define OUTPUT_HEADPHONE        0xC1
130 #define OUTPUT_SPEAKER    0xC2
131
132 #define VOLUME_LOW            0x01
133 #define VOLUME_LOW_SPEAKER      0x03
134 #define VOLUME_NORMAL      0x02
135 #define VOLUME_INSANELY_LOUD    0x07
136
137 #define MUTE_OFF                0x00
138 #define MUTE_ON          0xFF
139 #define MUTE_ON_DISCRET  0xCE
140
141 #define SIZE_HEADER          6
142 #define SIZE_MAC_ADDR      17
143 #define TEXT_LENGTH_MAX  24
144 #define TEXT_LINE0            0x00
145 #define TEXT_LINE1            0x20
146 #define TEXT_LINE2            0x40
147 #define TEXT_NORMAL          0x05
148 #define TEXT_INVERSE        0x25
149 #define STATUS_LENGTH_MAX       28
150
151 #define FAV_ICON_NONE              0x00
152 #define FAV_ICON_ONHOOK_BLACK      0x20
153 #define FAV_ICON_ONHOOK_WHITE      0x21
154 #define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22
155 #define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23
156 #define FAV_ICON_OFFHOOK_BLACK    0x24
157 #define FAV_ICON_OFFHOOK_WHITE    0x25
158 #define FAV_ICON_ONHOLD_BLACK      0x26
159 #define FAV_ICON_ONHOLD_WHITE      0x27
160 #define FAV_ICON_SPEAKER_OFFHOOK_BLACK  0x28
161 #define FAV_ICON_SPEAKER_OFFHOOK_WHITE  0x29
162 #define FAV_ICON_PHONE_BLACK        0x2A
163 #define FAV_ICON_PHONE_WHITE        0x2B
164 #define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C
165 #define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D
166 #define FAV_ICON_HEADPHONES          0x2E
167 #define FAV_ICON_HEADPHONES_ONHOLD      0x2F
168 #define FAV_ICON_HOME              0x30
169 #define FAV_ICON_CITY              0x31
170 #define FAV_ICON_SHARP            0x32
171 #define FAV_ICON_PAGER            0x33
172 #define FAV_ICON_CALL_CENTER        0x34
173 #define FAV_ICON_FAX                0x35
174 #define FAV_ICON_MAILBOX                0x36
175 #define FAV_ICON_REFLECT                0x37
176 #define FAV_ICON_COMPUTER              0x38
177 #define FAV_ICON_FORWARD                0x39
178 #define FAV_ICON_LOCKED          0x3A
179 #define FAV_ICON_TRASH            0x3B
180 #define FAV_ICON_INBOX            0x3C
181 #define FAV_ICON_OUTBOX          0x3D
182 #define FAV_ICON_MEETING                0x3E
183 #define FAV_ICON_BOX                0x3F
184
185 #define FAV_BLINK_FAST            0x20
186 #define FAV_BLINK_SLOW            0x40
187
188 #define FAV_MAX_LENGTH            0x0A
189
190 static void dummy(char *dummy, ...)
191 {
192         return;
193 }
194
195 /*! \brief Global jitterbuffer configuration - by default, jb is disabled */
196 static struct ast_jb_conf default_jbconf =
197 {
198         .flags = 0,
199         .max_size = -1,
200         .resync_threshold = -1,
201         .impl = ""
202 };
203 static struct ast_jb_conf global_jbconf;
204                                 
205
206 /* #define DUMP_PACKET 1 */
207 /* #define DEBUG_TIMER ast_verbose */
208
209 #define DEBUG_TIMER dummy
210 /*! Enable verbose output. can also be set with the CLI */
211 static int unistimdebug = 0;
212 static int unistim_port;
213 static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO;
214 static int unistim_keepalive;
215 static int unistimsock = -1;
216 static struct io_context *io;
217 static struct sched_context *sched;
218 static struct sockaddr_in public_ip = { 0, };
219 /*! give the IP address for the last packet received */
220 static struct sockaddr_in addr_from;
221 /*! size of the sockaddr_in (in WSARecvFrom) */
222 static unsigned int size_addr_from = sizeof(addr_from);
223 /*! Receive buffer address */
224 static unsigned char *buff;
225 /*! 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 | AST_CHAN_TP_CREATESJITTER,
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 = 0;  /* XXX what is this for, anyways */
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                 ast_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_debug(1, "Released sub %d of channel %s@%s\n", x, p->name,
1551                                 p->parent->name);
1552         ast_mutex_destroy(&p->lock);
1553         ast_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(*newd)))) {
1593                                                         ast_mutex_unlock(&devicelock);
1594                                                         return;
1595                                                 }
1596
1597                                                 memcpy(newd, d, sizeof(*newd));
1598                                                 if (!(newl = ast_malloc(sizeof(*newl)))) {
1599                                                         ast_free(newd);
1600                                                         ast_mutex_unlock(&devicelock);
1601                                                         return;
1602                                                 }
1603
1604                                                 memcpy(newl, d->lines, sizeof(*newl));
1605                                                 if (!alloc_sub(newl, SUB_REAL)) {
1606                                                         ast_free(newd);
1607                                                         ast_free(newl);
1608                                                         ast_mutex_unlock(&devicelock);
1609                                                         return;
1610                                                 }
1611                                                 /* Ok, now updating some fields */
1612                                                 ast_copy_string(newd->id, addrmac, sizeof(newd->id));
1613                                                 ast_copy_string(newd->name, addrmac, sizeof(newd->name));
1614                                                 if (newd->extension == EXTENSION_NONE)
1615                                                         newd->extension = EXTENSION_ASK;
1616                                                 newd->lines = newl;
1617                                                 newd->receiver_state = STATE_ONHOOK;
1618                                                 newd->session = pte;
1619                                                 newd->to_delete = -1;
1620                                                 pte->device = newd;
1621                                                 newd->next = NULL;
1622                                                 newl->parent = newd;
1623                                                 strcpy(newl->name, d->lines->name);
1624                                                 snprintf(d->lines->name, sizeof(d->lines->name), "%d",
1625                                                                  atoi(d->lines->name) + 1);
1626                                                 snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
1627                                                                  newl->name, newd->name);
1628                                                 /* Go to the end of the linked chain */
1629                                                 while (d->next) {
1630                                                         d = d->next;
1631                                                 }
1632                                                 d->next = newd;
1633                                                 d = newd;
1634                                                 break;
1635                                         }
1636                                         d = d->next;
1637                                 }
1638                                 ast_mutex_unlock(&devicelock);
1639                                 if (!d) {
1640                                         ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
1641                                         pte->state = STATE_AUTHDENY;
1642                                 }
1643                         }
1644                         break;
1645                 case AUTOPROVISIONING_TN:
1646                         pte->state = STATE_AUTHDENY;
1647                         break;
1648                 case AUTOPROVISIONING_DB:
1649                         ast_log(LOG_WARNING,
1650                                         "Autoprovisioning with database is not yet functional\n");
1651                         break;
1652                 default:
1653                         ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %d\n",
1654                                         autoprovisioning);
1655                 }
1656         }
1657         if (pte->state != STATE_AUTHDENY) {
1658                 if (option_verbose > 2)
1659                         ast_verbose(VERBOSE_PREFIX_3 "Device '%s' successfuly registered\n",
1660                                                 pte->device->name);
1661                 switch (pte->device->extension) {
1662                 case EXTENSION_NONE:
1663                         pte->state = STATE_MAINPAGE;
1664                         break;
1665                 case EXTENSION_ASK:
1666                         /* Checking if we already have an extension number */
1667                         if (ast_strlen_zero(pte->device->extension_number))
1668                                 pte->state = STATE_EXTENSION;
1669                         else {
1670                                 /* Yes, because of a phone reboot. We don't ask again for the TN */
1671                                 if (RegisterExtension(pte))
1672                                         pte->state = STATE_EXTENSION;
1673                                 else
1674                                         pte->state = STATE_MAINPAGE;
1675                         }
1676                         break;
1677                 case EXTENSION_LINE:
1678                         ast_copy_string(pte->device->extension_number, pte->device->lines->name,
1679                                                         sizeof(pte->device->extension_number));
1680                         if (RegisterExtension(pte))
1681                                 pte->state = STATE_EXTENSION;
1682                         else
1683                                 pte->state = STATE_MAINPAGE;
1684                         break;
1685                 case EXTENSION_TN:
1686                         /* If we are here, it's because of a phone reboot */
1687                         pte->state = STATE_MAINPAGE;
1688                         break;
1689                 default:
1690                         ast_log(LOG_WARNING, "Internal error, extension value unknown : %d\n",
1691                                         pte->device->extension);
1692                         pte->state = STATE_AUTHDENY;
1693                         break;
1694                 }
1695         }
1696         if (pte->state == STATE_EXTENSION) {
1697                 if (pte->device->extension != EXTENSION_TN)
1698                         pte->device->extension = EXTENSION_ASK;
1699                 pte->device->extension_number[0] = '\0';
1700         }
1701         if (unistimdebug)
1702                 ast_verbose("\nSending S1\n");
1703         memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
1704         send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
1705
1706         if (unistimdebug)
1707                 ast_verbose("Sending query_basic_manager_04\n");
1708         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
1709                    sizeof(packet_send_query_basic_manager_04));
1710         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
1711
1712         if (unistimdebug)
1713                 ast_verbose("Sending query_basic_manager_10\n");
1714         memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
1715                    sizeof(packet_send_query_basic_manager_10));
1716         send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
1717
1718         send_date_time(pte);
1719         return;
1720 }
1721
1722 static int write_entry_history(struct unistimsession *pte, FILE * f, char c, char *line1)
1723 {
1724         if (fwrite(&c, 1, 1, f) != 1) {
1725                 display_last_error("Unable to write history log header.");
1726                 return -1;
1727         }
1728         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
1729                 display_last_error("Unable to write history entry - date.");
1730                 return -1;
1731         }
1732         if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
1733                 display_last_error("Unable to write history entry - callerid.");
1734                 return -1;
1735         }
1736         if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
1737                 display_last_error("Unable to write history entry - callername.");
1738                 return -1;
1739         }
1740         return 0;
1741 }
1742
1743 static int write_history(struct unistimsession *pte, char way, char ismissed)
1744 {
1745         char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
1746         char line1[TEXT_LENGTH_MAX + 1];
1747         char count = 0, *histbuf;
1748         int size;
1749         FILE *f, *f2;
1750         struct systemtime systime;
1751         systime.w_year = systime.w_month = systime.w_day_of_week = 0;
1752         systime.w_day = systime.w_hour = systime.w_minute = 0;
1753         systime.w_second = systime.w_milliseconds = 0;
1754         if (!pte->device)
1755                 return -1;
1756         if (!pte->device->callhistory)
1757                 return 0;
1758         if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
1759                 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
1760                                 pte->device->name);
1761                 return -1;
1762         }
1763         snprintf(tmp, sizeof(tmp), "%s/%s", (char *) ast_config_AST_LOG_DIR, USTM_LOG_DIR);
1764         if (mkdir(tmp, 0770)) {
1765                 if (errno != EEXIST) {
1766                         display_last_error("Unable to create directory for history.");
1767                         return -1;
1768                 }
1769         }
1770         get_localtime(&systime);
1771         if (ismissed) {
1772                 if (way == 'i')
1773                         strcpy(tmp2, "Miss");
1774                 else
1775                         strcpy(tmp2, "Fail");
1776         } else
1777                 strcpy(tmp2, "Answ");
1778         snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
1779                          systime.w_year + 1900, systime.w_month, systime.w_day, systime.w_hour,
1780                          systime.w_minute, systime.w_second, tmp2);
1781         snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", (char *) ast_config_AST_LOG_DIR,
1782                          USTM_LOG_DIR, pte->device->name, way);
1783         f = fopen(tmp, "r");
1784         if (f) {
1785                 struct stat bufstat;
1786
1787                 if (stat(tmp, &bufstat)) {
1788                         display_last_error("Unable to stat history log.");
1789                         fclose(f);
1790                         return -1;
1791                 }
1792                 size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
1793                 if (bufstat.st_size != size) {
1794                         ast_log(LOG_WARNING,
1795                                         "History file %s have an incorrect size (%d instead of %d). It will be replaced by a new one.",
1796                                         tmp, (int) bufstat.st_size, size);
1797                         f = 0;
1798                         count = 1;
1799                 }
1800         }
1801         /* If we can't open the log file, we create a brand new one */
1802         if (!f) {
1803                 char c = 1;
1804                 int i;
1805
1806                 if ((errno != ENOENT) && (count == 0)) {
1807                         display_last_error("Unable to open history log.");
1808                         return -1;
1809                 }
1810                 f = fopen(tmp, "w");
1811                 if (!f) {
1812                         display_last_error("Unable to create history log.");
1813                         return -1;
1814                 }
1815                 if (write_entry_history(pte, f, c, line1)) {
1816                         fclose(f);
1817                         return -1;
1818                 }
1819                 memset(line1, ' ', TEXT_LENGTH_MAX);
1820                 for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
1821                         if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
1822                                 display_last_error("Unable to write history entry - stuffing.");
1823                                 fclose(f);
1824                                 return -1;
1825                         }
1826                 }
1827                 if (fclose(f))
1828                         display_last_error("Unable to close history - creation.");
1829                 return 0;
1830         }
1831         /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
1832         if (fread(&count, 1, 1, f) != 1) {
1833                 display_last_error("Unable to read history header.");
1834                 fclose(f);
1835                 return -1;
1836         }
1837         if (count > MAX_ENTRY_LOG) {
1838                 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
1839                                 count, MAX_ENTRY_LOG);
1840                 fclose(f);
1841                 return -1;
1842         }
1843         snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", (char *) ast_config_AST_LOG_DIR,
1844                          USTM_LOG_DIR, pte->device->name, way);
1845         f2 = fopen(tmp2, "w");
1846         if (!f2) {
1847                 display_last_error("Unable to create temporary history log.");
1848                 fclose(f);
1849                 return -1;
1850         }
1851         count++;
1852         if (count > MAX_ENTRY_LOG)
1853                 count = MAX_ENTRY_LOG;
1854         if (write_entry_history(pte, f2, count, line1)) {
1855                 fclose(f);
1856                 fclose(f2);
1857                 return -1;
1858         }
1859         size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
1860         if (!(histbuf = ast_malloc(size))) {
1861                 fclose(f);
1862                 fclose(f2);
1863                 return -1;
1864         }
1865         if (fread(histbuf, size, 1, f) != 1) {
1866                 ast_free(histbuf);
1867                 fclose(f);
1868                 fclose(f2);
1869                 display_last_error("Unable to read previous history entries.");
1870                 return -1;
1871         }
1872         if (fwrite(histbuf, size, 1, f2) != 1) {
1873                 ast_free(histbuf);
1874                 fclose(f);
1875                 fclose(f2);
1876                 display_last_error("Unable to write previous history entries.");
1877                 return -1;
1878         }
1879         ast_free(histbuf);
1880         if (fclose(f))
1881                 display_last_error("Unable to close history log.");
1882         if (fclose(f2))
1883                 display_last_error("Unable to close temporary history log.");
1884         if (unlink(tmp))
1885                 display_last_error("Unable to remove old history log.");
1886         if (rename(tmp2, tmp))
1887                 display_last_error("Unable to rename new history log.");
1888         return 0;
1889 }
1890
1891 static void cancel_dial(struct unistimsession *pte)
1892 {
1893         send_no_ring(pte);
1894         pte->device->missed_call++;
1895         write_history(pte, 'i', 1);
1896         show_main_page(pte);
1897         return;
1898 }
1899
1900 static void swap_subs(struct unistim_line *p, int a, int b)
1901 {
1902 /*  struct ast_channel *towner; */
1903         struct ast_rtp *rtp;
1904         int fds;
1905
1906         if (unistimdebug)
1907                 ast_verbose("Swapping %d and %d\n", a, b);
1908
1909         if ((!p->subs[a]->owner) || (!p->subs[b]->owner)) {
1910                 ast_log(LOG_WARNING,
1911                                 "Attempted to swap subchannels with a null owner : sub #%d=%p sub #%d=%p\n",
1912                                 a, p->subs[a]->owner, b, p->subs[b]->owner);
1913                 return;
1914         }
1915         rtp = p->subs[a]->rtp;
1916         p->subs[a]->rtp = p->subs[b]->rtp;
1917         p->subs[b]->rtp = rtp;
1918
1919         fds = p->subs[a]->owner->fds[0];
1920         p->subs[a]->owner->fds[0] = p->subs[b]->owner->fds[0];
1921         p->subs[b]->owner->fds[0] = fds;
1922
1923         fds = p->subs[a]->owner->fds[1];
1924         p->subs[a]->owner->fds[1] = p->subs[b]->owner->fds[1];
1925         p->subs[b]->owner->fds[1] = fds;
1926 }
1927
1928 static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
1929 {
1930         int res = 0;
1931         struct ast_channel
1932          *chana = NULL, *chanb = NULL, *bridgea = NULL, *bridgeb = NULL, *peera =
1933                 NULL, *peerb = NULL, *peerc = NULL, *peerd = NULL;
1934
1935         if (!p1->owner || !p2->owner) {
1936                 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
1937                 return -1;
1938         }
1939         chana = p1->owner;
1940         chanb = p2->owner;
1941         bridgea = ast_bridged_channel(chana);
1942         bridgeb = ast_bridged_channel(chanb);
1943
1944         if (bridgea) {
1945                 peera = chana;
1946                 peerb = chanb;
1947                 peerc = bridgea;
1948                 peerd = bridgeb;
1949         } else if (bridgeb) {
1950                 peera = chanb;
1951                 peerb = chana;
1952                 peerc = bridgeb;
1953                 peerd = bridgea;
1954         }
1955
1956         if (peera && peerb && peerc && (peerb != peerc)) {
1957                 /*ast_quiet_chan(peera);
1958                    ast_quiet_chan(peerb);
1959                    ast_quiet_chan(peerc);
1960                    ast_quiet_chan(peerd); */
1961
1962                 if (peera->cdr && peerb->cdr) {
1963                         peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
1964                 } else if (peera->cdr) {
1965                         peerb->cdr = peera->cdr;
1966                 }
1967                 peera->cdr = NULL;
1968
1969                 if (peerb->cdr && peerc->cdr) {
1970                         peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
1971                 } else if (peerc->cdr) {
1972                         peerb->cdr = peerc->cdr;
1973                 }
1974                 peerc->cdr = NULL;
1975
1976                 if (ast_channel_masquerade(peerb, peerc)) {
1977                         ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name,
1978                                         peerc->name);
1979                         res = -1;
1980                 }
1981                 return res;
1982         } else {
1983                 ast_log(LOG_NOTICE,
1984                                 "Transfer attempted with no appropriate bridged calls to transfer\n");
1985                 if (chana)
1986                         ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
1987                 if (chanb)
1988                         ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
1989                 return -1;
1990         }
1991         return 0;
1992 }
1993
1994 void change_callerid(struct unistimsession *pte, int type, char *callerid)
1995 {
1996         char *data;
1997         int size;
1998
1999         if (type)
2000                 data = pte->device->lst_cnm;
2001         else
2002                 data = pte->device->lst_cid;
2003
2004         memset(data, ' ', TEXT_LENGTH_MAX);
2005         size = strlen(callerid);
2006         if (size > TEXT_LENGTH_MAX)
2007                 size = TEXT_LENGTH_MAX;
2008         memcpy(data, callerid, size);
2009 }
2010
2011 static void close_call(struct unistimsession *pte)
2012 {
2013         struct unistim_subchannel *sub;
2014         struct unistim_line *l = pte->device->lines;
2015
2016         sub = pte->device->lines->subs[SUB_REAL];
2017         send_stop_timer(pte);
2018         if (sub->owner) {
2019                 sub->alreadygone = 1;
2020                 if (l->subs[SUB_THREEWAY]) {
2021                         l->subs[SUB_THREEWAY]->alreadygone = 1;
2022                         if (attempt_transfer(sub, l->subs[SUB_THREEWAY]) < 0)
2023                                 ast_verbose("attempt_transfer failed.\n");
2024                 } else
2025                         ast_queue_hangup(sub->owner);
2026         } else {
2027                 if (l->subs[SUB_THREEWAY]) {
2028                         if (l->subs[SUB_THREEWAY]->owner)
2029                                 ast_queue_hangup(l->subs[SUB_THREEWAY]->owner);
2030                         else
2031                                 ast_log(LOG_WARNING, "threeway sub without owner\n");
2032                 } else
2033                         ast_verbose("USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2034                                                 sub->parent->parent->name, sub->subtype);
2035         }
2036         change_callerid(pte, 0, pte->device->redial_number);
2037         change_callerid(pte, 1, "");
2038         write_history(pte, 'o', pte->device->missed_call);
2039         pte->device->missed_call = 0;
2040         show_main_page(pte);
2041         return;
2042 }
2043
2044 static void IgnoreCall(struct unistimsession *pte)
2045 {
2046         send_no_ring(pte);
2047         return;
2048 }
2049
2050 static void *unistim_ss(void *data)
2051 {
2052         struct ast_channel *chan = data;
2053         struct unistim_subchannel *sub = chan->tech_pvt;
2054         struct unistim_line *l = sub->parent;
2055         struct unistimsession *s = l->parent->session;
2056         int res;
2057
2058         if (option_verbose > 2)
2059                 ast_verbose(VERBOSE_PREFIX_3 "Starting switch on '%s@%s-%d' to %s\n",
2060                                         l->name, l->parent->name, sub->subtype, s->device->phone_number);
2061         ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten));
2062         ast_copy_string(s->device->redial_number, s->device->phone_number,
2063                                         sizeof(s->device->redial_number));
2064         ast_setstate(chan, AST_STATE_RING);
2065         res = ast_pbx_run(chan);
2066         if (res) {
2067                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2068                 send_tone(s, 1000, 0);;
2069         }
2070         return NULL;
2071 }
2072
2073 static void start_rtp(struct unistim_subchannel *sub)
2074 {
2075         BUFFSEND;
2076         struct sockaddr_in us;
2077         struct sockaddr_in public;
2078         struct sockaddr_in sin;
2079         int codec;
2080         struct sockaddr_in sout;
2081
2082         /* Sanity checks */
2083         if (!sub) {
2084                 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2085                 return;
2086         }
2087         if (!sub->parent) {
2088                 ast_log(LOG_WARNING, "start_rtp with a null line !\n");
2089                 return;
2090         }
2091         if (!sub->parent->parent) {
2092                 ast_log(LOG_WARNING, "start_rtp with a null device !\n");
2093                 return;
2094         }
2095         if (!sub->parent->parent->session) {
2096                 ast_log(LOG_WARNING, "start_rtp with a null session !\n");
2097                 return;
2098         }
2099         sout = sub->parent->parent->session->sout;
2100
2101         ast_mutex_lock(&sub->lock);
2102         /* Allocate the RTP */
2103         if (unistimdebug)
2104                 ast_verbose("Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2105         sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, sout.sin_addr);
2106         if (!sub->rtp) {
2107                 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2108                                 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2109                 ast_mutex_unlock(&sub->lock);
2110                 return;
2111         }
2112         if (sub->rtp && sub->owner) {
2113                 sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
2114                 sub->owner->fds[1] = ast_rtcp_fd(sub->rtp);
2115         }
2116         if (sub->rtp)
2117                 ast_rtp_setnat(sub->rtp, sub->parent->parent->nat);
2118
2119         /* Create the RTP connection */
2120         ast_rtp_get_us(sub->rtp, &us);
2121         sin.sin_family = AF_INET;
2122         /* Setting up RTP for our side */
2123         memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2124                    sizeof(sin.sin_addr));
2125         sin.sin_port = htons(sub->parent->parent->rtp_port);
2126         ast_rtp_set_peer(sub->rtp, &sin);
2127         if (!(sub->owner->nativeformats & sub->owner->readformat)) {
2128                 int fmt;
2129                 fmt = ast_best_codec(sub->owner->nativeformats);
2130                 ast_log(LOG_WARNING,
2131                                 "Our read/writeformat has been changed to something incompatible : %s (%d), using %s (%d) best codec from %d\n",
2132                                 ast_getformatname(sub->owner->readformat),
2133                                 sub->owner->readformat, ast_getformatname(fmt), fmt,
2134                                 sub->owner->nativeformats);
2135                 sub->owner->readformat = fmt;
2136                 sub->owner->writeformat = fmt;
2137         }
2138         codec = ast_rtp_lookup_code(sub->rtp, 1, sub->owner->readformat);
2139         /* Setting up RTP of the phone */
2140         if (public_ip.sin_family == 0)  /* NAT IP override ?   */
2141                 memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
2142         else
2143                 memcpy(&public, &public_ip, sizeof(public));    /* override  */
2144         if (unistimdebug) {
2145                 ast_verbose
2146                         ("RTP started : Our IP/port is : %s:%hd with codec %s (%d)\n",
2147                          ast_inet_ntoa(us.sin_addr),
2148                          htons(us.sin_port), ast_getformatname(sub->owner->readformat),
2149                          sub->owner->readformat);
2150                 ast_verbose("Starting phone RTP stack. Our public IP is %s\n",
2151                                         ast_inet_ntoa(public.sin_addr));
2152         }
2153         if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
2154                 (sub->owner->readformat == AST_FORMAT_ALAW)) {
2155                 if (unistimdebug)
2156                         ast_verbose("Sending packet_send_rtp_packet_size for codec %d\n", codec);
2157                 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2158                            sizeof(packet_send_rtp_packet_size));
2159                 buffsend[10] = codec;
2160                 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend,
2161                                    sub->parent->parent->session);
2162         }
2163         if (unistimdebug)
2164                 ast_verbose("Sending Jitter Buffer Parameters Configuration\n");
2165         memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
2166                    sizeof(packet_send_jitter_buffer_conf));
2167         send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend,
2168                            sub->parent->parent->session);
2169         if (sub->parent->parent->rtp_method != 0) {
2170                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2171
2172                 if (unistimdebug)
2173                         ast_verbose("Sending OpenAudioStreamTX using method #%d\n",
2174                                                 sub->parent->parent->rtp_method);
2175                 if (sub->parent->parent->rtp_method == 3)
2176                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
2177                                    sizeof(packet_send_open_audio_stream_tx3));
2178                 else
2179                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
2180                                    sizeof(packet_send_open_audio_stream_tx));
2181                 if (sub->parent->parent->rtp_method != 2) {
2182                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2183                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2184                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2185                         buffsend[23] = (rtcpsin_port & 0x00ff);
2186                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2187                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2188                         buffsend[24] = (us.sin_port & 0x00ff);
2189                         buffsend[27] = (rtcpsin_port & 0x00ff);
2190                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2191                 } else {
2192                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2193                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2194                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2195                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2196                         buffsend[19] = (us.sin_port & 0x00ff);
2197                         buffsend[11] = codec;
2198                 }
2199                 buffsend[12] = codec;
2200                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend,
2201                                    sub->parent->parent->session);
2202
2203                 if (unistimdebug)
2204                         ast_verbose("Sending OpenAudioStreamRX\n");
2205                 if (sub->parent->parent->rtp_method == 3)
2206                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
2207                                    sizeof(packet_send_open_audio_stream_rx3));
2208                 else
2209                         memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
2210                                    sizeof(packet_send_open_audio_stream_rx));
2211                 if (sub->parent->parent->rtp_method != 2) {
2212                         memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2213                         buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
2214                         buffsend[21] = (htons(sin.sin_port) & 0x00ff);
2215                         buffsend[23] = (rtcpsin_port & 0x00ff);
2216                         buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
2217                         buffsend[25] = (us.sin_port & 0xff00) >> 8;
2218                         buffsend[24] = (us.sin_port & 0x00ff);
2219                         buffsend[27] = (rtcpsin_port & 0x00ff);
2220                         buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
2221                 } else {
2222                         memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2223                         buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
2224                         buffsend[16] = (htons(sin.sin_port) & 0x00ff);
2225                         buffsend[20] = (us.sin_port & 0xff00) >> 8;
2226                         buffsend[19] = (us.sin_port & 0x00ff);
2227                         buffsend[12] = codec;
2228                 }
2229                 buffsend[11] = codec;
2230                 send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend,
2231                                    sub->parent->parent->session);
2232         } else {
2233                 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2234
2235                 if (unistimdebug)
2236                         ast_verbose("Sending packet_send_call default method\n");
2237
2238                 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2239                 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2240                 /* Destination port when sending RTP */
2241                 buffsend[49] = (us.sin_port & 0x00ff);
2242                 buffsend[50] = (us.sin_port & 0xff00) >> 8;
2243                 /* Destination port when sending RTCP */
2244                 buffsend[52] = (rtcpsin_port & 0x00ff);
2245                 buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
2246                 /* Codec */
2247                 buffsend[40] = codec;
2248                 buffsend[41] = codec;
2249                 if (sub->owner->readformat == AST_FORMAT_ULAW)
2250                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2251                 else if (sub->owner->readformat == AST_FORMAT_ALAW)
2252                         buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2253                 else if (sub->owner->readformat == AST_FORMAT_G723_1)
2254                         buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2255                 else if (sub->owner->readformat == AST_FORMAT_G729A)
2256                         buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2257                 else
2258                         ast_log(LOG_WARNING, "Unsupported codec %s (%d) !\n",
2259                                         ast_getformatname(sub->owner->readformat), sub->owner->readformat);
2260                 /* Source port for transmit RTP and Destination port for receiving RTP */
2261                 buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
2262                 buffsend[46] = (htons(sin.sin_port) & 0x00ff);
2263                 buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
2264                 buffsend[48] = (rtcpsin_port & 0x00ff);
2265                 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend,
2266                                    sub->parent->parent->session);
2267         }
2268         ast_mutex_unlock(&sub->lock);
2269 }
2270
2271 static void SendDialTone(struct unistimsession *pte)
2272 {
2273         int i;
2274         /* No country defined ? Using US tone */
2275         if (ast_strlen_zero(pte->device->country)) {
2276                 if (unistimdebug)
2277                         ast_verbose("No country defined, using US tone\n");
2278                 send_tone(pte, 350, 440);
2279                 return;
2280         }
2281         if (strlen(pte->device->country) != 2) {
2282                 if (unistimdebug)
2283                         ast_verbose("Country code != 2 char, using US tone\n");
2284                 send_tone(pte, 350, 440);
2285                 return;
2286         }
2287         i = 0;
2288         while (frequency[i].freq1) {
2289                 if ((frequency[i].country[0] == pte->device->country[0]) &&
2290                         (frequency[i].country[1] == pte->device->country[1])) {
2291                         if (unistimdebug)
2292                                 ast_verbose("Country code found (%s), freq1=%d freq2=%d\n",
2293                                                         frequency[i].country, frequency[i].freq1, frequency[i].freq2);
2294                         send_tone(pte, frequency[i].freq1, frequency[i].freq2);
2295                 }
2296                 i++;
2297         }
2298 }
2299
2300 static void handle_dial_page(struct unistimsession *pte)
2301 {
2302         pte->state = STATE_DIALPAGE;
2303         if (pte->device->call_forward[0] == -1) {
2304                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2305                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
2306                 send_text_status(pte, "ForwardCancel BackSpcErase");
2307                 if (pte->device->call_forward[1] != 0) {
2308                         char tmp[TEXT_LENGTH_MAX + 1];
2309
2310                         ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
2311                                                         sizeof(pte->device->phone_number));
2312                         pte->device->size_phone_number = strlen(pte->device->phone_number);
2313                         if (pte->device->size_phone_number > 15)
2314                                 pte->device->size_phone_number = 15;
2315                         strcpy(tmp, "Number : ...............");
2316                         memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
2317                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
2318                         send_blink_cursor(pte);
2319                         send_cursor_pos(pte,
2320                                                   (unsigned char) (TEXT_LINE2 + 0x09 +
2321                                                                                    pte->device->size_phone_number));
2322                         send_led_update(pte, 0);
2323                         return;
2324                 }
2325         } else {
2326                 if ((pte->device->output == OUTPUT_HANDSET) &&
2327                         (pte->device->receiver_state == STATE_ONHOOK))
2328                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2329                 else
2330                         send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2331                 SendDialTone(pte);
2332                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
2333                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
2334                 send_text_status(pte, "Call   Redial BackSpcErase");
2335         }
2336         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2337         send_blink_cursor(pte);
2338         send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2339         pte->device->size_phone_number = 0;
2340         pte->device->phone_number[0] = 0;
2341         change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
2342         Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
2343         pte->device->missed_call = 0;
2344         send_led_update(pte, 0);
2345         return;
2346 }
2347
2348 /* Step 1 : Music On Hold for peer, Dialing screen for us */
2349 static void TransferCallStep1(struct unistimsession *pte)
2350 {
2351         struct unistim_subchannel *sub;
2352         struct unistim_line *p = pte->device->lines;
2353
2354         sub = p->subs[SUB_REAL];
2355
2356         if (!sub->owner) {
2357                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2358                 return;
2359         }
2360         if (p->subs[SUB_THREEWAY]) {
2361                 if (unistimdebug)
2362                         ast_verbose("Transfer canceled, hangup our threeway channel\n");
2363                 if (p->subs[SUB_THREEWAY]->owner)
2364                         ast_queue_hangup(p->subs[SUB_THREEWAY]->owner);
2365                 else
2366                         ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
2367                 return;
2368         }
2369         /* Start music on hold if appropriate */
2370         if (pte->device->moh)
2371                 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
2372         else {
2373                 if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
2374                         ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
2375                                                   pte->device->lines->musicclass, NULL);
2376                         pte->device->moh = 1;
2377                 } else {
2378                         ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
2379                         return;
2380                 }
2381         }
2382         /* Silence our channel */
2383         if (!pte->device->silence_generator) {
2384                 pte->device->silence_generator =
2385                         ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
2386                 if (pte->device->silence_generator == NULL)
2387                         ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2388                 else if (unistimdebug)
2389                         ast_verbose("Starting silence generator\n");
2390         }
2391         handle_dial_page(pte);
2392 }
2393
2394 /* From phone to PBX */
2395 static void HandleCallOutgoing(struct unistimsession *s)
2396 {
2397         struct ast_channel *c;
2398         struct unistim_subchannel *sub;
2399         pthread_t t;
2400         s->state = STATE_CALL;
2401         sub = s->device->lines->subs[SUB_REAL];
2402         if (!sub) {
2403                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2404                 return;
2405         }
2406         if (!sub->owner) {                    /* A call is already in progress ? */
2407                 c = unistim_new(sub, AST_STATE_DOWN);   /* No, starting a new one */
2408                 if (c) {
2409                         /* Need to start RTP before calling ast_pbx_run */
2410                         if (!sub->rtp)
2411                                 start_rtp(sub);
2412                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2413                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
2414                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2415                         send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2416                         send_text_status(s, "Hangup");
2417                         /* start switch */
2418                         if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
2419                                 display_last_error("Unable to create switch thread");
2420                                 ast_queue_hangup(c);
2421                         }
2422                 } else
2423                         ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
2424                                         sub->parent->name, s->device->name);
2425         } else {                                        /* We already have a call, so we switch in a threeway call */
2426
2427                 if (s->device->moh) {
2428                         struct unistim_subchannel *sub;
2429                         struct unistim_line *p = s->device->lines;
2430                         sub = p->subs[SUB_REAL];
2431
2432                         if (!sub->owner) {
2433                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2434                                 return;
2435                         }
2436                         if (p->subs[SUB_THREEWAY]) {
2437                                 ast_log(LOG_WARNING,
2438                                                 "Can't transfer while an another transfer is taking place\n");
2439                                 return;
2440                         }
2441                         if (!alloc_sub(p, SUB_THREEWAY)) {
2442                                 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
2443                                 return;
2444                         }
2445                         /* Stop the silence generator */
2446                         if (s->device->silence_generator) {
2447                                 if (unistimdebug)
2448                                         ast_verbose("Stopping silence generator\n");
2449                                 ast_channel_stop_silence_generator(sub->owner,
2450                                                                                                    s->device->silence_generator);
2451                                 s->device->silence_generator = NULL;
2452                         }
2453                         send_tone(s, 0, 0);
2454                         /* Make new channel */
2455                         c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN);
2456                         if (!c) {
2457                                 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
2458                                 return;
2459                         }
2460                         /* Swap things around between the three-way and real call */
2461                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
2462                         send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2463                         send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
2464                         send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
2465                         send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
2466                         send_text_status(s, "TransfrCancel");
2467
2468                         if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
2469                                 ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
2470                                 ast_hangup(c);
2471                                 return;
2472                         }
2473                         if (unistimdebug)
2474                                 ast_verbose
2475                                         ("Started three way call on channel %p (%s) subchan %d\n",
2476                                          p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name,
2477                                          p->subs[SUB_THREEWAY]->subtype);
2478                 } else
2479                         ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
2480         }
2481         return;
2482 }
2483
2484 /* From PBX to phone */
2485 static void HandleCallIncoming(struct unistimsession *s)
2486 {
2487         struct unistim_subchannel *sub;
2488         s->state = STATE_CALL;
2489         s->device->missed_call = 0;
2490         send_no_ring(s);
2491         sub = s->device->lines->subs[SUB_REAL];
2492         if (!sub) {
2493                 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
2494                 return;
2495         } else if (unistimdebug)
2496                 ast_verbose("Handle Call Incoming for %s@%s\n", sub->parent->name,
2497                                         s->device->name);
2498         start_rtp(sub);
2499         if (!sub->rtp)
2500                 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
2501                                 s->device->name);
2502         ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
2503         send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
2504         send_text_status(s, "Hangup Transf");
2505         send_start_timer(s);
2506
2507         if ((s->device->output == OUTPUT_HANDSET) &&
2508                 (s->device->receiver_state == STATE_ONHOOK))
2509                 send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
2510         else
2511                 send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
2512         s->device->start_call_timestamp = time(0);
2513         write_history(s, 'i', 0);
2514         return;
2515 }
2516
2517 static int unistim_do_senddigit(struct unistimsession *pte, char digit)
2518 {
2519
2520         struct ast_frame f = { 0, };
2521         struct unistim_subchannel *sub;
2522         sub = pte->device->lines->subs[SUB_REAL];
2523         if (!sub->owner) {
2524                 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
2525                 return -1;
2526         }
2527         if (unistimdebug)
2528                 ast_verbose("Send Digit %c\n", digit);
2529         switch (digit) {
2530         case '0':
2531                 send_tone(pte, 941, 1336);
2532                 break;
2533         case '1':
2534                 send_tone(pte, 697, 1209);
2535                 break;
2536         case '2':
2537                 send_tone(pte, 697, 1336);
2538                 break;
2539         case '3':
2540                 send_tone(pte, 697, 1477);
2541                 break;
2542         case '4':
2543                 send_tone(pte, 770, 1209);
2544                 break;
2545         case '5':
2546                 send_tone(pte, 770, 1336);
2547                 break;
2548         case '6':
2549                 send_tone(pte, 770, 1477);
2550                 break;
2551         case '7':
2552                 send_tone(pte, 852, 1209);
2553                 break;
2554         case '8':
2555                 send_tone(pte, 852, 1336);
2556                 break;
2557         case '9':
2558                 send_tone(pte, 852, 1477);
2559                 break;
2560         case 'A':
2561                 send_tone(pte, 697, 1633);
2562                 break;
2563         case 'B':
2564                 send_tone(pte, 770, 1633);
2565                 break;
2566         case 'C':
2567                 send_tone(pte, 852, 1633);
2568                 break;
2569         case 'D':
2570                 send_tone(pte, 941, 1633);
2571                 break;
2572         case '*':
2573                 send_tone(pte, 941, 1209);
2574                 break;
2575         case '#':
2576                 send_tone(pte, 941, 1477);
2577                 break;
2578         default:
2579                 send_tone(pte, 500, 2000);
2580         }
2581         usleep(150000);                  /* XXX Less than perfect, blocking an important thread is not a good idea */
2582         send_tone(pte, 0, 0);
2583         f.frametype = AST_FRAME_DTMF;
2584         f.subclass = digit;
2585         f.src = "unistim";
2586         ast_queue_frame(sub->owner, &f);
2587         return 0;
2588 }
2589
2590 static void key_call(struct unistimsession *pte, char keycode)
2591 {
2592         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2593                 if (keycode == KEY_SHARP)
2594                         keycode = '#';
2595                 else if (keycode == KEY_STAR)
2596                         keycode = '*';
2597                 else
2598                         keycode -= 0x10;
2599                 unistim_do_senddigit(pte, keycode);
2600                 return;
2601         }
2602         switch (keycode) {
2603         case KEY_HANGUP:
2604         case KEY_FUNC1:
2605                 close_call(pte);
2606                 break;
2607         case KEY_FUNC2:
2608                 TransferCallStep1(pte);
2609                 break;
2610         case KEY_HEADPHN:
2611                 if (pte->device->output == OUTPUT_HEADPHONE)
2612                         send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2613                 else
2614                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2615                 break;
2616         case KEY_LOUDSPK:
2617                 if (pte->device->output != OUTPUT_SPEAKER)
2618                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2619                 else
2620                         send_select_output(pte, pte->device->previous_output, pte->device->volume,
2621                                                          MUTE_OFF);
2622                 break;
2623         case KEY_MUTE:
2624                 if (!pte->device->moh) {
2625                         if (pte->device->mute == MUTE_ON)
2626                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
2627                         else
2628                                 send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
2629                         break;
2630                 }
2631         case KEY_ONHOLD:
2632                 {
2633                         struct unistim_subchannel *sub;
2634                         struct ast_channel *bridgepeer = NULL;
2635                         sub = pte->device->lines->subs[SUB_REAL];
2636                         if (!sub->owner) {
2637                                 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
2638                                 return;
2639                         }
2640                         if ((bridgepeer = ast_bridged_channel(sub->owner))) {
2641                                 if (pte->device->moh) {
2642                                         ast_moh_stop(bridgepeer);
2643                                         pte->device->moh = 0;
2644                                         send_select_output(pte, pte->device->output, pte->device->volume,
2645                                                                          MUTE_OFF);
2646                                 } else {
2647                                         ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
2648                                         pte->device->moh = 1;
2649                                         send_select_output(pte, pte->device->output, pte->device->volume,
2650                                                                          MUTE_ON);
2651                                 }
2652                         } else
2653                                 ast_log(LOG_WARNING,
2654                                                 "Unable to find peer subchannel for music on hold\n");
2655                         break;
2656                 }
2657         }
2658         return;
2659 }
2660
2661 static void key_ringing(struct unistimsession *pte, char keycode)
2662 {
2663         if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
2664                 HandleCallIncoming(pte);
2665                 return;
2666         }
2667         switch (keycode) {
2668         case KEY_HANGUP:
2669         case KEY_FUNC4:
2670                 IgnoreCall(pte);
2671                 break;
2672         case KEY_FUNC1:
2673                 HandleCallIncoming(pte);
2674                 break;
2675         }
2676         return;
2677 }
2678
2679 static void Keyfavorite(struct unistimsession *pte, char keycode)
2680 {
2681         int fav;
2682
2683         if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
2684                 ast_log(LOG_WARNING, "It's not a favorite key\n");
2685                 return;
2686         }
2687         if (keycode == KEY_FAV0)
2688                 return;
2689         fav = keycode - KEY_FAV0;
2690         if (pte->device->softkeyicon[fav] == 0)
2691                 return;
2692         ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
2693                                         sizeof(pte->device->phone_number));
2694         HandleCallOutgoing(pte);
2695         return;
2696 }
2697
2698 static void key_dial_page(struct unistimsession *pte, char keycode)
2699 {
2700         if (keycode == KEY_FUNC3) {
2701                 if (pte->device->size_phone_number <= 1)
2702                         keycode = KEY_FUNC4;
2703                 else {
2704                         pte->device->size_phone_number -= 2;
2705                         keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
2706                 }
2707         }
2708         if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
2709                 char tmpbuf[] = "Number : ...............";
2710                 int i = 0;
2711
2712                 if (pte->device->size_phone_number >= 15)
2713                         return;
2714                 if (pte->device->size_phone_number == 0)
2715                         send_tone(pte, 0, 0);
2716                 while (i < pte->device->size_phone_number) {
2717                         tmpbuf[i + 9] = pte->device->phone_number[i];
2718                         i++;
2719                 }
2720                 if (keycode == KEY_SHARP)
2721                         keycode = '#';
2722                 else if (keycode == KEY_STAR)
2723                         keycode = '*';
2724                 else
2725                         keycode -= 0x10;
2726                 tmpbuf[i + 9] = keycode;
2727                 pte->device->phone_number[i] = keycode;
2728                 pte->device->size_phone_number++;
2729                 pte->device->phone_number[i + 1] = 0;
2730                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2731                 send_blink_cursor(pte);
2732                 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
2733                 return;
2734         }
2735         if (keycode == KEY_FUNC4) {
2736
2737                 pte->device->size_phone_number = 0;
2738                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
2739                 send_blink_cursor(pte);
2740                 send_cursor_pos(pte, TEXT_LINE2 + 0x09);
2741                 return;
2742         }
2743
2744         if (pte->device->call_forward[0] == -1) {
2745                 if (keycode == KEY_FUNC1) {
2746                         ast_copy_string(pte->device->call_forward, pte->device->phone_number,
2747                                                         sizeof(pte->device->call_forward));
2748                         show_main_page(pte);
2749                 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
2750                         pte->device->call_forward[0] = '\0';
2751                         show_main_page(pte);
2752                 }
2753                 return;
2754         }
2755         switch (keycode) {
2756         case KEY_FUNC2:
2757                 if (ast_strlen_zero(pte->device->redial_number))
2758                         break;
2759                 ast_copy_string(pte->device->phone_number, pte->device->redial_number,
2760                                                 sizeof(pte->device->phone_number));
2761         case KEY_FUNC1:
2762                 HandleCallOutgoing(pte);
2763                 break;
2764         case KEY_HANGUP:
2765                 if (pte->device->lines->subs[SUB_REAL]->owner) {
2766                         /* Stop the silence generator */
2767                         if (pte->device->silence_generator) {
2768                                 if (unistimdebug)
2769                                         ast_verbose("Stopping silence generator\n");
2770                                 ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
2771                                                                                                    owner, pte->device->silence_generator);
2772                                 pte->device->silence_generator = NULL;
2773                         }
2774                         send_tone(pte, 0, 0);
2775                         ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
2776                         pte->device->moh = 0;
2777                         pte->state = STATE_CALL;
2778                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
2779                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
2780                         send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
2781                         send_text_status(pte, "Hangup Transf");
2782                 } else
2783                         show_main_page(pte);
2784                 break;
2785         case KEY_FAV1:
2786         case KEY_FAV2:
2787         case KEY_FAV3:
2788         case KEY_FAV4:
2789         case KEY_FAV5:
2790                 Keyfavorite(pte, keycode);
2791                 break;
2792         case KEY_LOUDSPK:
2793                 if (pte->device->output == OUTPUT_SPEAKER) {
2794                         if (pte->device->receiver_state == STATE_OFFHOOK)
2795                                 send_select_output(pte, pte->device->previous_output, pte->device->volume,
2796                                                                  MUTE_OFF);
2797                         else
2798                                 show_main_page(pte);
2799                 } else
2800                         send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
2801                 break;
2802         case KEY_HEADPHN:
2803                 if (pte->device->output == OUTPUT_HEADPHONE) {
2804                         if (pte->device->receiver_state == STATE_OFFHOOK)
2805                                 send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
2806                         else
2807                                 show_main_page(pte);
2808                 } else
2809                         send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
2810                 break;
2811         }
2812         return;
2813 }
2814
2815 #define SELECTCODEC_START_ENTRY_POS 15
2816 #define SELECTCODEC_MAX_LENGTH 2
2817 #define SELECTCODEC_MSG "Codec number : .."
2818 static void HandleSelectCodec(struct unistimsession *pte)
2819 {
2820         char buf[30], buf2[5];
2821
2822         pte->state = STATE_SELECTCODEC;
2823         strcpy(buf, "Using codec ");
2824         sprintf(buf2, "%d", pte->device->codec_number);
2825         strcat(buf, buf2);
2826         strcat(buf, " (G711u=0,");
2827
2828         send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
2829         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
2830         send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2831         send_blink_cursor(pte);
2832         send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2833         pte->size_buff_entry = 0;
2834         send_text_status(pte, "Select BackSpcErase  Cancel");
2835         return;
2836 }
2837
2838 static void key_select_codec(struct unistimsession *pte, char keycode)
2839 {
2840         if (keycode == KEY_FUNC2) {
2841                 if (pte->size_buff_entry <= 1)
2842                         keycode = KEY_FUNC3;
2843                 else {
2844                         pte->size_buff_entry -= 2;
2845                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2846                 }
2847         }
2848         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2849                 char tmpbuf[] = SELECTCODEC_MSG;
2850                 int i = 0;
2851
2852                 if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
2853                         return;
2854
2855                 while (i < pte->size_buff_entry) {
2856                         tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
2857                         i++;
2858                 }
2859                 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
2860                 pte->buff_entry[i] = keycode - 0x10;
2861                 pte->size_buff_entry++;
2862                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
2863                 send_blink_cursor(pte);
2864                 send_cursor_pos(pte,
2865                                           (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
2866                 return;
2867         }
2868
2869         switch (keycode) {
2870         case KEY_FUNC1:
2871                 if (pte->size_buff_entry == 1)
2872                         pte->device->codec_number = pte->buff_entry[0] - 48;
2873                 else if (pte->size_buff_entry == 2)
2874                         pte->device->codec_number =
2875                                 ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
2876                 show_main_page(pte);
2877                 break;
2878         case KEY_FUNC3:
2879                 pte->size_buff_entry = 0;
2880                 send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
2881                 send_blink_cursor(pte);
2882                 send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
2883                 break;
2884         case KEY_HANGUP:
2885         case KEY_FUNC4:
2886                 show_main_page(pte);
2887                 break;
2888         }
2889         return;
2890 }
2891
2892 #define SELECTEXTENSION_START_ENTRY_POS 0
2893 #define SELECTEXTENSION_MAX_LENGTH 10
2894 #define SELECTEXTENSION_MSG ".........."
2895 static void ShowExtensionPage(struct unistimsession *pte)
2896 {
2897         pte->state = STATE_EXTENSION;
2898
2899         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
2900         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
2901         send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
2902         send_blink_cursor(pte);
2903         send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
2904         send_text_status(pte, "Enter  BackSpcErase");
2905         pte->size_buff_entry = 0;
2906         return;
2907 }
2908
2909 static void key_select_extension(struct unistimsession *pte, char keycode)
2910 {
2911         if (keycode == KEY_FUNC2) {
2912                 if (pte->size_buff_entry <= 1)
2913                         keycode = KEY_FUNC3;
2914                 else {
2915                         pte->size_buff_entry -= 2;
2916                         keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
2917                 }
2918         }
2919         if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
2920                 char tmpbuf[] = SELECTEXTENSION_MSG;
2921                 int i = 0;
2922
2923                 if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
2924                         return;
2925
2926                 while (i < pte->size_buff_entry) {
2927                         tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
2928                         i++;
2929                 }
2930                 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
2931                 pte->buff_entry[i] = keycode - 0x10;
2932                 pte->size_buff_entry++;
2933                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
2934                 send_blink_cursor(pte);
2935                 send_cursor_pos(pte,
2936                                           (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
2937                                                                            i));
2938                 return;
2939         }
2940
2941         switch (keycode) {
2942         case KEY_FUNC1:
2943                 if (pte->size_buff_entry < 1)
2944                         return;
2945                 if (autoprovisioning == AUTOPROVISIONING_TN) {
2946                         struct unistim_device *d;
2947
2948                         /* First step : looking for this TN in our device list */
2949                         ast_mutex_lock(&devicelock);
2950                         d = devices;
2951                         pte->buff_entry[pte->size_buff_entry] = '\0';
2952                         while (d) {
2953                                 if (d->id[0] == 'T') {  /* It's a TN device ? */
2954                                         /* It's the TN we're looking for ? */
2955                                         if (!strcmp((d->id) + 1, pte->buff_entry)) {
2956                                                 pte->device = d;
2957                                                 d->session = pte;
2958                                                 d->codec_number = DEFAULT_CODEC;
2959                                                 d->pos_fav = 0;
2960                                                 d->missed_call = 0;
2961                                                 d->receiver_state = STATE_ONHOOK;
2962                                                 strcpy(d->id, pte->macaddr);
2963                                                 pte->device->extension_number[0] = 'T';
2964                                                 pte->device->extension = EXTENSION_TN;
2965                                                 ast_copy_string((pte->device->extension_number) + 1,
2966                                                                                 pte->buff_entry, pte->size_buff_entry + 1);
2967                                                 ast_mutex_unlock(&devicelock);
2968                                                 show_main_page(pte);
2969                                                 refresh_all_favorite(pte);
2970                                                 return;
2971                                         }
2972                                 }
2973                                 d = d->next;
2974                         }
2975                         ast_mutex_unlock(&devicelock);
2976                         send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number.");
2977                         send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
2978                         send_cursor_pos(pte,
2979                                                   (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
2980                                                                                    pte->size_buff_entry));
2981                         send_blink_cursor(pte);
2982                 } else {
2983                         ast_copy_string(pte->device->extension_number, pte->buff_entry,
2984                                                         pte->size_buff_entry + 1);
2985                         if (RegisterExtension(pte)) {
2986                                 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension.");
2987                                 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
2988                                 send_cursor_pos(pte,
2989                                                           (unsigned char) (TEXT_LINE2 +
2990                                                                                            SELECTEXTENSION_START_ENTRY_POS +
2991                                                                                            pte->size_buff_entry));
2992                                 send_blink_cursor(pte);
2993                         } else
2994                                 show_main_page(pte);
2995                 }
2996                 break;
2997         case KEY_FUNC3:
2998                 pte->size_buff_entry = 0;
2999                 send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
3000                 send_blink_cursor(pte);
3001                 send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_ST