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