+ Legal: use an up-to-date address of Free Software Foundation
[calf.git] / src / osctlnet.cpp
blob285efd9eb2bd5ad8edddaf8f9aec3a46f6103987
1 /* Calf DSP Library
2 * Open Sound Control UDP support
4 * Copyright (C) 2007-2009 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
21 #include <calf/osctl.h>
22 #include <calf/osctlnet.h>
23 #include <assert.h>
24 #include <arpa/inet.h>
25 #include <sys/socket.h>
26 #include <stdlib.h>
27 #include <sstream>
29 using namespace osctl;
30 using namespace std;
32 void osc_socket::bind(const char *hostaddr, int port)
34 socket = ::socket(PF_INET, SOCK_DGRAM, 0);
35 if (socket < 0)
36 throw osc_net_exception("socket");
38 sockaddr_in sadr;
39 sadr.sin_family = AF_INET;
40 sadr.sin_port = htons(port);
41 inet_aton(hostaddr, &sadr.sin_addr);
42 if (::bind(socket, (sockaddr *)&sadr, sizeof(sadr)) < 0)
43 throw osc_net_exception("bind");
44 on_bind();
47 std::string osc_socket::get_uri() const
49 sockaddr_in sadr;
50 socklen_t len = sizeof(sadr);
51 if (getsockname(socket, (sockaddr *)&sadr, &len) < 0)
52 throw osc_net_exception("getsockname");
54 char name[INET_ADDRSTRLEN], buf[32];
56 inet_ntop(AF_INET, &sadr.sin_addr, name, INET_ADDRSTRLEN);
57 sprintf(buf, "%d", ntohs(sadr.sin_port));
59 return string("osc.udp://") + name + ":" + buf + prefix;
62 osc_socket::~osc_socket()
64 close(socket);
67 //////////////////////////////////////////////////////////////
69 void osc_client::set_addr(const char *hostaddr, int port)
71 addr.sin_family = AF_INET;
72 addr.sin_port = htons(port);
73 inet_aton(hostaddr, &addr.sin_addr);
76 void osc_client::set_url(const char *url)
78 if (strncmp(url, "osc.udp://", 10))
79 throw osc_net_bad_address(url);
80 url += 10;
82 const char *pos = strchr(url, ':');
83 const char *pos2 = strchr(url, '/');
84 if (!pos || !pos2)
85 throw osc_net_bad_address(url);
87 // XXXKF perhaps there is a default port for osc.udp?
88 if (pos2 - pos < 0)
89 throw osc_net_bad_address(url);
91 string hostname = string(url, pos - url);
92 int port = atoi(pos + 1);
93 prefix = string(pos2);
94 printf("hostname %s port %d\n", hostname.c_str(), port);
96 addr.sin_family = AF_INET;
97 addr.sin_port = htons(port);
99 hostent *he = gethostbyname(hostname.c_str());
100 if (!he)
101 throw osc_net_dns_exception("gethostbyname");
103 addr.sin_addr = *(struct in_addr *)he->h_addr;
106 bool osc_client::send(const std::string &address, osctl::osc_typed_strstream &stream)
108 std::string type_tag = "," + stream.type_buffer->data;
109 osc_inline_strstream hdr;
110 hdr << prefix + address << "," + stream.type_buffer->data;
111 string str = hdr.data + stream.buffer.data;
113 // printf("sending %s\n", str.buffer.c_str());
115 return ::sendto(socket, str.data(), str.length(), 0, (sockaddr *)&addr, sizeof(addr)) == (int)str.length();
118 bool osc_client::send(const std::string &address)
120 osc_inline_strstream hdr;
121 hdr << prefix + address << ",";
123 return ::sendto(socket, hdr.data.data(), hdr.data.length(), 0, (sockaddr *)&addr, sizeof(addr)) == (int)hdr.data.length();