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., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 #include <calf/osctl.h>
22 #include <calf/osctlnet.h>
24 #include <arpa/inet.h>
25 #include <sys/socket.h>
29 using namespace osctl
;
32 void osc_socket::bind(const char *hostaddr
, int port
)
34 socket
= ::socket(PF_INET
, SOCK_DGRAM
, 0);
36 throw osc_net_exception("socket");
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");
47 std::string
osc_socket::get_uri() const
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()
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
);
82 const char *pos
= strchr(url
, ':');
83 const char *pos2
= strchr(url
, '/');
85 throw osc_net_bad_address(url
);
87 // XXXKF perhaps there is a default port for osc.udp?
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());
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();