17 #include <sipwitch-config.h>
25 #include <avahi-client/client.h>
26 #include <avahi-client/publish.h>
27 #include <avahi-common/alternative.h>
28 #include <avahi-common/thread-watch.h>
29 #include <avahi-common/malloc.h>
30 #include <avahi-common/error.h>
31 #include <avahi-common/timeval.h>
34 class __LOCAL zeroconf :
public modules::generic
39 void setClient(AvahiClientState state);
40 void setGroup(AvahiEntryGroupState state);
42 inline void setClient(AvahiClient *c)
45 static zeroconf plugin;
48 void start(service *cfg);
49 void stop(service *cfg);
50 void reload(service *cfg);
51 void publish(service *cfg);
53 AvahiThreadedPoll *poller;
55 AvahiEntryGroup *group;
63 static void client_callback(AvahiClient *c, AvahiClientState state,
void *userdata)
72 static void group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state,
void *userdata)
81 protocol =
"_sip._udp";
85 name = avahi_strdup(
"sipwitch");
86 shell::log(shell::ERR,
"zeroconf plugin using avahi");
89 void zeroconf::setGroup(AvahiEntryGroupState state)
95 case AVAHI_ENTRY_GROUP_ESTABLISHED:
96 shell::log(shell::INFO,
"zeroconf %s service(s) established",
name);
98 case AVAHI_ENTRY_GROUP_COLLISION:
99 newname = avahi_alternative_service_name(
name);
100 shell::log(shell::NOTIFY,
"zeroconf service %s renamed %s",
name, newname);
103 setClient(AVAHI_CLIENT_S_RUNNING);
105 case AVAHI_ENTRY_GROUP_FAILURE:
106 shell::log(shell::ERR,
"zeroconf service failure; error=%s",
107 avahi_strerror(avahi_client_errno(client)));
114 void zeroconf::setClient(AvahiClientState state)
117 AvahiProtocol avifamily = AVAHI_PROTO_UNSPEC;
120 case AVAHI_CLIENT_S_RUNNING:
122 case AVAHI_CLIENT_FAILURE:
124 shell::log(shell::ERR,
"zeroconf failure; error=%s",
125 avahi_strerror(avahi_client_errno(client)));
127 case AVAHI_CLIENT_S_COLLISION:
128 case AVAHI_CLIENT_S_REGISTERING:
130 avahi_entry_group_reset(group);
137 group = avahi_entry_group_new(client, group_callback, NULL);
141 shell::log(shell::INFO,
"zeroconf adding sip on port %d", sip_port);
148 snprintf(domain,
sizeof(domain),
"domain=%s", sip_domain);
149 snprintf(prefix,
sizeof(prefix),
"prefix=%u", sip_prefix);
150 snprintf(range,
sizeof(range),
"range=%u", sip_range);
151 snprintf(uuid,
sizeof(uuid),
"uuid=%s", session_uuid);
152 ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, avifamily,
153 (AvahiPublishFlags)0,
name, protocol, NULL, NULL, sip_port,
154 "type=sipwitch", domain, prefix, range, uuid, NULL);
157 ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, avifamily,
158 (AvahiPublishFlags)0,
name, protocol, NULL, NULL, sip_port,
159 "type=sipwitch", NULL);
162 shell::log(shell::ERR,
"zeroconf %s failed; error=%s",
163 protocol, avahi_strerror(ret));
165 ret = avahi_entry_group_commit(group);
169 shell::log(shell::ERR,
"zeroconf service commit failure; error=%s",
170 avahi_strerror(ret));
173 void zeroconf::stop(service *cfg)
176 avahi_threaded_poll_stop(poller);
178 avahi_client_free(client);
188 void zeroconf::start(service *cfg)
190 poller = avahi_threaded_poll_new();
193 shell::log(shell::ERR,
"zeroconf service failed to start");
197 client = avahi_client_new(avahi_threaded_poll_get(poller),
198 (AvahiClientFlags)0, client_callback, NULL, &error);
200 shell::log(shell::INFO,
"zeroconf service started");
201 avahi_threaded_poll_start(poller);
204 void zeroconf::reload(service *cfg)
206 if(sip_protocol == IPPROTO_TCP)
207 protocol =
"_sip._tcp";
210 void zeroconf::publish(service *cfg)
219 static bool started =
false;
220 AvahiProtocol avifamily = AVAHI_PROTO_UNSPEC;
223 if(started && group && sip_domain) {
224 snprintf(domain,
sizeof(domain),
"domain=%s", sip_domain);
225 snprintf(prefix,
sizeof(prefix),
"prefix=%u", sip_prefix);
226 snprintf(range,
sizeof(range),
"range=%u", sip_range);
227 snprintf(uuid,
sizeof(uuid),
"uuid=%s", session_uuid);
228 ret = avahi_entry_group_update_service_txt(group, AVAHI_IF_UNSPEC, avifamily,
229 (AvahiPublishFlags)0,
name, protocol, NULL,
230 "type=sipwitch", domain, prefix, range, uuid, NULL);
232 else if(started && group) {
233 ret = avahi_entry_group_update_service_txt(group, AVAHI_IF_UNSPEC, avifamily,
234 (AvahiPublishFlags)0,
name, protocol, NULL,
235 "type=sipwitch", NULL);
239 shell::log(shell::ERR,
"zeroconf %s failed; error=%s",
240 protocol, avahi_strerror(ret));
255 zeroconf::zeroconf() :
258 shell::log(shell::ERR,
"zeroconf plugin could not be built");
A more generic service class for use by plugins.
Top level include directory for GNU Telephony SIP Witch Server.
Common interfaces and clases for plugins.