[ifxmips]
[openwrt.git] / package / tapi_sip / src / tapi_sip.c
1
2 #include <stdbool.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <sys/ioctl.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <poll.h>
9 #include <string.h>
10
11 #include <linux/input.h>
12 #include "dialdetector.h"
13
14 #include <tapi-ioctl.h>
15
16 #include <tapi-device.h>
17 #include <tapi-port.h>
18
19 #include "contact.h"
20 #include "session.h"
21 #include "sip_client.h"
22 #include "sip_agent.h"
23 #include "tapi_agent.h"
24
25 static struct tapi_device dev;
26 static struct tapi_agent *ports;
27
28 static struct sip_client sip_client;
29
30 static void release_session(struct session *session)
31 {
32         free(session);
33 }
34
35 static void dial(struct tapi_agent *caller, struct agent *callee)
36 {
37         struct session *session;
38
39         session = session_alloc(&dev, &caller->agent, callee, release_session);
40
41         if (!session)
42                 return;
43
44         caller->session = session;
45 }
46
47 static void tel_dial(struct tapi_agent *caller, const char *number)
48 {
49         int callee;
50
51         callee = atoi(number) - 1;
52
53         if (callee < 0 || callee > 1)
54                 return;
55         dial(caller, &ports[callee].agent);
56 }
57
58 static void sip_dial(struct tapi_agent *caller, const char *identifier)
59 {
60         struct sip_agent *callee;
61
62         callee = sip_client_alloc_agent(&sip_client, identifier);
63         if (!callee)
64                 return;
65
66         dial(caller, &callee->agent);
67 }
68
69 static void dial_callback(struct tapi_port *port, size_t num_digits, const unsigned char *digits)
70 {
71         struct tapi_agent *tagent = port_to_tapi_agent(port);
72         char number[100];
73         struct contact *contact;
74         size_t i;
75
76         if (tagent->state != TAPI_AGENT_STATE_IDLE)
77                 return;
78
79         for (i = 0; i < num_digits; ++i) {
80                 if (digits[0] > 9)
81                         break;
82                 number[i] = digits[i] + '0';
83         }
84         number[i] = '\0';
85
86         printf("dial callback: %s\n", number);
87
88         contact = contact_get(number);
89
90         if (!contact)
91                 return;
92
93         if (strncmp("tel:", contact->identifier, 4) == 0) {
94                 tel_dial(tagent, contact->identifier + 4);
95         } else if (strncmp("sip:", contact->identifier, 4) == 0) {
96                 sip_dial(tagent, contact->identifier);
97         }
98         tagent->state = TAPI_AGENT_STATE_ACTIVE;
99 }
100
101 static int incoming_sip_call(struct sip_client *client,
102         struct sip_agent *caller)
103 {
104         struct tapi_agent *callee = NULL;;
105         struct session *session;
106         int i;
107
108         for (i = 0; i < 2; ++i) {
109                 if (ports[i].state == TAPI_AGENT_STATE_IDLE) {
110                         callee = &ports[i];
111                         break;
112                 }
113         }
114
115         if (callee == NULL)
116                 return -1;
117
118         session = session_alloc(&dev, &caller->agent, &callee->agent,
119                 release_session);
120         caller->session = session;
121
122         return 0;
123 }
124
125 int main(int argc, char *argv[])
126 {
127         struct dialdetector *dd, *dd2;
128         struct account *account;
129         struct sip_client_config config;
130         const char *interface = "eth0";
131         int ret;
132         int i;
133
134         if (argc > 1)
135                 interface = argv[1];
136
137         pj_init();
138     pjlib_util_init();
139
140         contacts_init();
141
142         account = get_account();
143         if (!account) {
144                 printf("No account\n");
145                 return 1;
146         }
147
148         ret = tapi_device_open(0, &dev);
149         if (ret) {
150                 printf("Failed to open tapi device: %d\n", ret);
151                 return 1;
152         }
153
154         ports = calloc(dev.num_ports, sizeof(*ports));
155         for (i = 0; i < dev.num_ports; ++i)
156                 tapi_agent_init(&dev, i, &ports[i]);
157
158         dd = dialdetector_alloc(&ports[0].port);
159         dd->dial_callback = dial_callback;
160         dd2 = dialdetector_alloc(&ports[1].port);
161         dd2->dial_callback = dial_callback;
162
163         config.iface = interface;
164         config.host = account->realm;
165         config.port = account->sip_port;
166         config.username = account->username;
167         config.password = account->password;
168
169         config.stun_host = account->stun_host;
170         config.stun_port = account->stun_port;
171
172         sip_client_init(&sip_client, &dev, &config);
173
174         sip_client.incoming_call_cb = incoming_sip_call;
175
176         tapi_mainloop();
177
178         return 0;
179 }