source: roaraudio/libroar/basic.c @ 521:f7ca1f94e9e5

Last change on this file since 521:f7ca1f94e9e5 was 521:f7ca1f94e9e5, checked in by phi, 16 years ago

added roar_socket_get_local_nodename() and use it as default hostname

File size: 6.2 KB
Line 
1//basic.c:
2
3#include "libroar.h"
4
5int roar_connect_raw (char * server) {
6 char user_sock[80];
7 char * roar_server;
8 int i;
9 int port = 0;
10 int fh = -1;
11 int is_decnet = 0;
12 char * obj = NULL;
13
14 if ( server == NULL && (roar_server = getenv("ROAR_SERVER")) != NULL )
15  server = roar_server;
16
17 if ( server == NULL && (i = readlink("/etc/roarserver", user_sock, 79)) != -1 ) {
18   user_sock[i] = 0;
19   server = user_sock;
20 }
21
22 if ( server == NULL || *server == 0 ) {
23  /* connect via defaults */
24
25
26  snprintf(user_sock, 79, "%s/%s", getenv("HOME"), ROAR_DEFAULT_SOCK_USER);
27
28  if ( (fh = roar_socket_connect(user_sock, 0)) != -1 )
29   return fh;
30
31  if ( (fh = roar_socket_connect(ROAR_DEFAULT_SOCK_GLOBAL, 0)) != -1 )
32   return fh;
33
34  if ( (fh = roar_socket_connect(ROAR_DEFAULT_HOST, ROAR_DEFAULT_PORT)) != -1 )
35   return fh;
36
37 } else {
38  /* connect via (char*)server */
39  // find a port:
40  if ( *server != '/' ) { // don't test AF_UNIX sockets for ports
41   for (i = 0; server[i] != 0; i++) {
42    if ( server[i] == ':' ) {
43     if ( server[i+1] == ':' ) { // DECnet, leave unchanged
44      is_decnet = 1;
45      obj = &server[i+2];
46      break;
47     }
48
49     port = atoi(server+i+1);
50     server[i] = 0;
51     break;
52    }
53   }
54  }
55
56  if ( is_decnet ) {
57    *user_sock = 0;
58   if ( *server == ':' ) {
59    if ( roar_socket_get_local_nodename() )
60     strcat(user_sock, roar_socket_get_local_nodename());
61   }
62
63   strcat(user_sock, server);
64   server = user_sock;
65   if ( *obj == 0 ) {
66    strcat(user_sock, ROAR_DEFAULT_OBJECT);
67   }
68  }
69
70  if ( port || is_decnet ) {
71   fh = roar_socket_connect(server, port);
72   // restore the original string
73   server[i] = ':';
74  } else {
75   fh = roar_socket_connect(server, ROAR_DEFAULT_PORT);
76  }
77 }
78
79 ROAR_DBG("roar_connect_raw(*) = %i", fh);
80
81 return fh;
82}
83
84int roar_connect    (struct roar_connection * con, char * server) {
85 con->fh = roar_connect_raw(server);
86
87 if ( con->fh == -1 )
88  return -1;
89
90 return 0;
91}
92
93int roar_disconnect (struct roar_connection * con) {
94 struct roar_message m;
95
96 m.datalen = 0;
97 m.stream  = 0;
98 m.pos     = 0;
99 m.cmd     = ROAR_CMD_QUIT;
100
101 roar_req(con, &m, NULL);
102
103 close(con->fh);
104
105 con->fh = -1;
106
107 return 0;
108}
109
110int roar_identify   (struct roar_connection * con, char * name) {
111 struct roar_message mes;
112 pid_t pid;
113 int max_len;
114
115 ROAR_DBG("roar_identify(*): try to identify myself...");
116
117 mes.cmd    = ROAR_CMD_IDENTIFY;
118 mes.stream = 0;
119 mes.pos    = 0;
120
121 ROAR_DBG("roar_identify(*): name=%p", name);
122
123 if ( name == NULL )
124  name = "libroar client";
125
126 ROAR_DBG("roar_identify(*): name=%p", name);
127
128 max_len = strlen(name);
129 ROAR_DBG("roar_identify(*): strlen(name) = %i", max_len);
130
131 if ( max_len > (LIBROAR_BUFFER_MSGDATA - 5) )
132  max_len = LIBROAR_BUFFER_MSGDATA - 5;
133
134 mes.datalen = 5 + max_len;
135 mes.data[0] = 1;
136
137 pid = getpid();
138 *(uint32_t*)(mes.data+1) = ROAR_HOST2NET32(pid);
139 ROAR_DBG("roar_identify(*): pid = %i", pid);
140
141 strncpy(mes.data+5, name, max_len);
142
143 return roar_req(con, &mes, NULL);
144}
145
146#define _ROAR_MESS_BUF_LEN (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 4 /* pos */ + 2 /* datalen */)
147int roar_send_message (struct roar_connection * con, struct roar_message * mes, char * data) {
148 char buf[_ROAR_MESS_BUF_LEN];
149
150 ROAR_DBG("roar_send_message(*): try to send an request...");
151
152 buf[0] = _ROAR_MESSAGE_VERSION;
153 buf[1] = (unsigned char) mes->cmd;
154 *(uint16_t*)(buf+2) = ROAR_HOST2NET16(mes->stream);
155 *(uint32_t*)(buf+4) = ROAR_HOST2NET32(mes->pos);
156 *(uint16_t*)(buf+8) = ROAR_HOST2NET16(mes->datalen);
157
158 if ( write(con->fh, buf, _ROAR_MESS_BUF_LEN) != _ROAR_MESS_BUF_LEN )
159  return -1;
160
161 if ( mes->datalen != 0 )
162  if ( write(con->fh, data == NULL ? mes->data : data, mes->datalen) != mes->datalen )
163   return -1;
164
165 ROAR_DBG("roar_send_message(*) = 0");
166 return 0;
167}
168
169int roar_recv_message (struct roar_connection * con, struct roar_message * mes, char ** data) {
170 char buf[_ROAR_MESS_BUF_LEN];
171
172 ROAR_DBG("roar_recv_message(*): try to get a response form the server...");
173
174 if ( data )
175  *data = NULL;
176
177 if ( read(con->fh, buf, _ROAR_MESS_BUF_LEN) != _ROAR_MESS_BUF_LEN )
178  return -1;
179
180 ROAR_DBG("roar_recv_message(*): Got a header");
181
182 if ( buf[0] != _ROAR_MESSAGE_VERSION )
183  return -1;
184
185 mes->cmd     = (unsigned char)buf[1];
186 mes->stream  = ROAR_NET2HOST16(*(uint16_t*)(buf+2));
187 mes->pos     = ROAR_NET2HOST32(*(uint32_t*)(buf+4));
188 mes->datalen = ROAR_NET2HOST16(*(uint16_t*)(buf+8));
189
190 ROAR_DBG("roar_recv_message(*): command=%i(%s)", mes->cmd,
191           mes->cmd == ROAR_CMD_OK ? "OK" : (mes->cmd == ROAR_CMD_ERROR ? "ERROR" : "UNKNOWN"));
192
193 if ( mes->datalen == 0 ) {
194  ROAR_DBG("roar_recv_message(*): no data in this pkg");
195  ROAR_DBG("roar_recv_message(*) = 0");
196  return 0;
197 }
198
199 if ( mes->datalen <= LIBROAR_BUFFER_MSGDATA ) {
200  if ( read(con->fh, mes->data, mes->datalen) == mes->datalen ) {
201   ROAR_DBG("roar_recv_message(*): Got data!");
202   ROAR_DBG("roar_recv_message(*) = 0");
203   return 0;
204  }
205  return -1;
206 } else {
207  if ( data == NULL )
208   return -1;
209
210  if ( (*data = malloc(mes->datalen)) == NULL )
211   return -1;
212
213  if ( mes->datalen == 0 )
214   return 0;
215
216  if ( read(con->fh, *data, mes->datalen) == mes->datalen ) {
217   ROAR_DBG("roar_recv_message(*): Got data!");
218   ROAR_DBG("roar_recv_message(*) = 0");
219   return 0;
220  }
221  return -1;
222 }
223
224 return -1;
225}
226
227int roar_req (struct roar_connection * con, struct roar_message * mes, char ** data) {
228 if ( roar_send_message(con, mes, data ? *data : NULL) != 0 )
229  return -1;
230
231 if ( data )
232  free(*data);
233
234 return roar_recv_message(con, mes, data);
235}
236
237int roar_debug_message_print (struct roar_message * mes) {
238 if ( mes == NULL )
239  return -1;
240
241 ROAR_DBG("roar_debug_message_print(*): Command: %i", mes->cmd);
242 ROAR_DBG("roar_debug_message_print(*): Stream : %u", mes->stream);
243 ROAR_DBG("roar_debug_message_print(*): Pos    : %u", mes->pos);
244 ROAR_DBG("roar_debug_message_print(*): Datalen: %i", mes->datalen);
245
246 ROAR_DBG("roar_debug_message_print(*) = 0");
247 return 0;
248}
249
250int roar_debug_audio_info_print (struct roar_audio_info * info) {
251 if ( info == NULL )
252  return -1;
253
254 ROAR_DBG("roar_debug_audio_info_print(*): Rate    : %i", info->rate);
255 ROAR_DBG("roar_debug_audio_info_print(*): Channels: %i", info->channels);
256 ROAR_DBG("roar_debug_audio_info_print(*): Bits    : %i", info->bits);
257 ROAR_DBG("roar_debug_audio_info_print(*): Codec   : %i", info->codec);
258
259 ROAR_DBG("roar_debug_audio_info_print(*) = 0");
260 return 0;
261}
262
263//ll
Note: See TracBrowser for help on using the repository browser.