|
a/scctl_src/scctl.cpp |
|
b/scctl_src/scctl.cpp |
|
... |
|
... |
58 |
using namespace UPnPClient;
|
58 |
using namespace UPnPClient;
|
59 |
using namespace UPnPP;
|
59 |
using namespace UPnPP;
|
60 |
using namespace std;
|
60 |
using namespace std;
|
61 |
using namespace Songcast;
|
61 |
using namespace Songcast;
|
62 |
|
62 |
|
|
|
63 |
#define OPT_L 0x1
|
|
|
64 |
#define OPT_S 0x2
|
|
|
65 |
#define OPT_f 0x4
|
|
|
66 |
#define OPT_h 0x8
|
|
|
67 |
#define OPT_l 0x10
|
|
|
68 |
#define OPT_m 0x20
|
|
|
69 |
#define OPT_p 0x40
|
|
|
70 |
#define OPT_r 0x80
|
|
|
71 |
#define OPT_s 0x100
|
|
|
72 |
#define OPT_x 0x200
|
|
|
73 |
|
|
|
74 |
static const string sep("||");
|
|
|
75 |
|
63 |
string showReceivers()
|
76 |
string showReceivers(int ops)
|
64 |
{
|
77 |
{
|
65 |
vector<ReceiverState> vscs;
|
78 |
vector<ReceiverState> vscs;
|
66 |
listReceivers(vscs);
|
79 |
listReceivers(vscs);
|
67 |
ostringstream out;
|
80 |
ostringstream out;
|
68 |
|
81 |
string dsep = (ops & OPT_m) ? sep : " ";
|
|
|
82 |
|
69 |
for (auto& scs: vscs) {
|
83 |
for (auto& scs: vscs) {
|
70 |
switch (scs.state) {
|
84 |
switch (scs.state) {
|
71 |
case ReceiverState::SCRS_GENERROR: out << "Error ";break;
|
85 |
case ReceiverState::SCRS_GENERROR: out << "Error " << dsep;break;
|
72 |
case ReceiverState::SCRS_NOOH: out << "Nooh ";break;
|
86 |
case ReceiverState::SCRS_NOOH: out << "Nooh " << dsep;break;
|
73 |
case ReceiverState::SCRS_NOTRECEIVER: out << "Off ";break;
|
87 |
case ReceiverState::SCRS_NOTRECEIVER: out << "Off " << dsep;break;
|
74 |
case ReceiverState::SCRS_STOPPED: out << "Stop ";break;
|
88 |
case ReceiverState::SCRS_STOPPED: out << "Stop " << dsep;break;
|
75 |
case ReceiverState::SCRS_PLAYING: out << "Play ";break;
|
89 |
case ReceiverState::SCRS_PLAYING: out << "Play " << dsep;break;
|
76 |
}
|
90 |
}
|
77 |
out << scs.nm << " ";
|
91 |
out << scs.nm << dsep;
|
78 |
out << scs.UDN << " ";
|
92 |
out << scs.UDN << dsep;
|
79 |
if (scs.state == ReceiverState::SCRS_PLAYING) {
|
93 |
if (scs.state == ReceiverState::SCRS_PLAYING) {
|
80 |
out << scs.uri;
|
94 |
out << scs.uri;
|
81 |
} else if (scs.state == ReceiverState::SCRS_GENERROR) {
|
95 |
} else if (scs.state == ReceiverState::SCRS_GENERROR) {
|
82 |
out << scs.reason;
|
96 |
out << scs.reason;
|
83 |
}
|
97 |
}
|
84 |
out << endl;
|
98 |
out << endl;
|
85 |
}
|
99 |
}
|
86 |
return out.str();
|
100 |
return out.str();
|
87 |
}
|
101 |
}
|
88 |
|
102 |
|
89 |
string showSenders()
|
103 |
string showSenders(int ops)
|
90 |
{
|
104 |
{
|
91 |
vector<SenderState> vscs;
|
105 |
vector<SenderState> vscs;
|
92 |
listSenders(vscs);
|
106 |
listSenders(vscs);
|
93 |
ostringstream out;
|
107 |
ostringstream out;
|
|
|
108 |
string dsep = (ops & OPT_m) ? sep : " ";
|
94 |
|
109 |
|
95 |
for (auto& scs: vscs) {
|
110 |
for (auto& scs: vscs) {
|
96 |
out << scs.nm << " ";
|
111 |
out << scs.nm << dsep;
|
97 |
out << scs.UDN << " ";
|
112 |
out << scs.UDN << dsep;
|
98 |
out << scs.reason << " ";
|
113 |
out << scs.reason << dsep;
|
99 |
out << scs.uri;
|
114 |
out << scs.uri;
|
100 |
out << endl;
|
115 |
out << endl;
|
101 |
}
|
116 |
}
|
102 |
return out.str();
|
117 |
return out.str();
|
103 |
}
|
118 |
}
|
104 |
|
119 |
|
105 |
static char *thisprog;
|
120 |
static char *thisprog;
|
106 |
static char usage [] =
|
121 |
static char usage [] =
|
107 |
" -l List renderers with Songcast Receiver capability\n"
|
122 |
" -l List renderers with Songcast Receiver capability\n"
|
108 |
" -L List Songcast Senders\n"
|
123 |
" -L List Songcast Senders\n"
|
|
|
124 |
" -m : for above modes: use parseable format\n"
|
|
|
125 |
"For the following options the renderers can be designated by their \n"
|
|
|
126 |
"uid (safer) or friendly name\n"
|
109 |
" -s <master> <slave> [slave ...] : Set up the slaves renderers as Songcast\n"
|
127 |
" -s <master> <slave> [slave ...] : Set up the slaves renderers as Songcast\n"
|
110 |
" Receivers and make them play from the same uri as the master receiver\n"
|
128 |
" Receivers and make them play from the same uri as the master receiver\n"
|
111 |
" -x <renderer> [renderer ...] Reset renderers from Songcast to Playlist\n"
|
129 |
" -x <renderer> [renderer ...] Reset renderers from Songcast to Playlist\n"
|
|
|
130 |
" -r <sender> <renderer> <renderer> : set up the renderers in Receiver mode\n"
|
|
|
131 |
" playing data from the sender. This is like -s but we get the uri from \n"
|
|
|
132 |
" the sender instead of a sibling receiver\n"
|
112 |
" -S Run as server\n"
|
133 |
" -S Run as server\n"
|
113 |
" -f If no server is found, scctl will fork one after performing the\n"
|
134 |
" -f If no server is found, scctl will fork one after performing the\n"
|
114 |
" requested command, so that the next execution will not have to wait for\n"
|
135 |
" requested command, so that the next execution will not have to wait for\n"
|
115 |
" the discovery timeout.\n"
|
136 |
" the discovery timeout.\n"
|
116 |
" -r <sender> <renderer> <renderer> : set up the renderers in Receiver mode\n"
|
|
|
117 |
" playing data from the sender. This is like -s but we get the uri from \n"
|
|
|
118 |
" the sender instead of a sibling receiver\n"
|
|
|
119 |
" -h This help.\n"
|
137 |
" -h This help.\n"
|
120 |
"\n"
|
138 |
"\n"
|
121 |
"Renderers may be designated by friendly name or UUID\n"
|
139 |
"Renderers may be designated by friendly name or UUID\n"
|
122 |
"\n"
|
140 |
"\n"
|
123 |
;
|
141 |
;
|
|
|
142 |
|
|
|
143 |
static int op_flags;
|
|
|
144 |
|
124 |
static void
|
145 |
static void
|
125 |
Usage(FILE *fp = stderr)
|
146 |
Usage(FILE *fp = stderr)
|
126 |
{
|
147 |
{
|
127 |
fprintf(fp, "%s: usage:\n%s", thisprog, usage);
|
148 |
fprintf(fp, "%s: usage:\n%s", thisprog, usage);
|
128 |
exit(1);
|
149 |
exit(1);
|
129 |
}
|
150 |
}
|
130 |
|
151 |
|
131 |
static int op_flags;
|
|
|
132 |
#define OPT_l 0x1
|
|
|
133 |
#define OPT_s 0x2
|
|
|
134 |
#define OPT_x 0x4
|
|
|
135 |
#define OPT_S 0x8
|
|
|
136 |
#define OPT_h 0x10
|
|
|
137 |
#define OPT_f 0x20
|
|
|
138 |
#define OPT_p 0x40
|
|
|
139 |
#define OPT_r 0x80
|
|
|
140 |
#define OPT_L 0x100
|
|
|
141 |
|
|
|
142 |
int runserver();
|
152 |
int runserver();
|
143 |
bool tryserver(int flags, int argc, char *argv[]);
|
153 |
bool tryserver(int flags, int argc, char *argv[]);
|
144 |
|
154 |
|
145 |
int main(int argc, char *argv[])
|
155 |
int main(int argc, char *argv[])
|
146 |
{
|
156 |
{
|
147 |
thisprog = argv[0];
|
157 |
thisprog = argv[0];
|
148 |
|
158 |
|
149 |
int ret;
|
159 |
int ret;
|
150 |
while ((ret = getopt(argc, argv, "fhLlrsSx")) != -1) {
|
160 |
while ((ret = getopt(argc, argv, "fhmLlrsSx")) != -1) {
|
151 |
switch (ret) {
|
161 |
switch (ret) {
|
152 |
case 'f': op_flags |= OPT_f; break;
|
162 |
case 'f': op_flags |= OPT_f; break;
|
153 |
case 'h': Usage(stdout); break;
|
163 |
case 'h': Usage(stdout); break;
|
154 |
case 'l':
|
164 |
case 'l':
|
155 |
if (op_flags & ~OPT_f)
|
|
|
156 |
Usage();
|
|
|
157 |
op_flags |= OPT_l;
|
165 |
op_flags |= OPT_l;
|
158 |
break;
|
166 |
break;
|
159 |
case 'L':
|
167 |
case 'L':
|
160 |
if (op_flags & ~OPT_f)
|
|
|
161 |
Usage();
|
|
|
162 |
op_flags |= OPT_L;
|
168 |
op_flags |= OPT_L;
|
163 |
break;
|
169 |
break;
|
|
|
170 |
case 'm':
|
|
|
171 |
op_flags |= OPT_m;
|
|
|
172 |
break;
|
164 |
case 'r':
|
173 |
case 'r':
|
165 |
if (op_flags & ~OPT_f)
|
|
|
166 |
Usage();
|
|
|
167 |
op_flags |= OPT_r;
|
174 |
op_flags |= OPT_r;
|
168 |
break;
|
175 |
break;
|
169 |
case 's':
|
176 |
case 's':
|
170 |
if (op_flags & ~OPT_f)
|
|
|
171 |
Usage();
|
|
|
172 |
op_flags |= OPT_s;
|
177 |
op_flags |= OPT_s;
|
173 |
break;
|
178 |
break;
|
174 |
case 'S':
|
179 |
case 'S':
|
175 |
if (op_flags & ~OPT_f)
|
|
|
176 |
Usage();
|
|
|
177 |
op_flags |= OPT_S;
|
180 |
op_flags |= OPT_S;
|
178 |
break;
|
181 |
break;
|
179 |
case 'x':
|
182 |
case 'x':
|
180 |
if (op_flags & ~OPT_f)
|
|
|
181 |
Usage();
|
|
|
182 |
op_flags |= OPT_x;
|
183 |
op_flags |= OPT_x;
|
183 |
break;
|
184 |
break;
|
184 |
default: Usage();
|
185 |
default: Usage();
|
185 |
}
|
186 |
}
|
186 |
}
|
187 |
}
|
|
... |
|
... |
191 |
if (!(op_flags & OPT_S) && tryserver(op_flags, argc -optind,
|
192 |
if (!(op_flags & OPT_S) && tryserver(op_flags, argc -optind,
|
192 |
&argv[optind])) {
|
193 |
&argv[optind])) {
|
193 |
exit(0);
|
194 |
exit(0);
|
194 |
}
|
195 |
}
|
195 |
|
196 |
|
|
|
197 |
// At least one action needed.
|
196 |
if ((op_flags & ~OPT_f) == 0)
|
198 |
if ((op_flags & ~(OPT_f|OPT_m)) == 0)
|
197 |
Usage();
|
199 |
Usage();
|
198 |
|
200 |
|
199 |
LibUPnP *mylib = LibUPnP::getLibUPnP();
|
201 |
LibUPnP *mylib = LibUPnP::getLibUPnP();
|
200 |
if (!mylib) {
|
202 |
if (!mylib) {
|
201 |
cerr << "Can't get LibUPnP" << endl;
|
203 |
cerr << "Can't get LibUPnP" << endl;
|
|
... |
|
... |
214 |
}
|
216 |
}
|
215 |
|
217 |
|
216 |
if ((op_flags & OPT_l)) {
|
218 |
if ((op_flags & OPT_l)) {
|
217 |
if (args.size())
|
219 |
if (args.size())
|
218 |
Usage();
|
220 |
Usage();
|
219 |
string out = showReceivers();
|
221 |
string out = showReceivers(op_flags);
|
220 |
cout << out;
|
222 |
cout << out;
|
221 |
} else if ((op_flags & OPT_L)) {
|
223 |
} else if ((op_flags & OPT_L)) {
|
222 |
if (args.size())
|
224 |
if (args.size())
|
223 |
Usage();
|
225 |
Usage();
|
224 |
string out = showSenders();
|
226 |
string out = showSenders(op_flags);
|
225 |
cout << out;
|
227 |
cout << out;
|
226 |
} else if ((op_flags & OPT_r)) {
|
228 |
} else if ((op_flags & OPT_r)) {
|
227 |
if (args.size() < 2)
|
229 |
if (args.size() < 2)
|
228 |
Usage();
|
230 |
Usage();
|
229 |
setReceiversFromSender(args[0], vector<string>(args.begin() + 1,
|
231 |
setReceiversFromSender(args[0], vector<string>(args.begin() + 1,
|
|
... |
|
... |
377 |
string out;
|
379 |
string out;
|
378 |
if (opflags & OPT_p) {
|
380 |
if (opflags & OPT_p) {
|
379 |
// ping
|
381 |
// ping
|
380 |
out = "Ok\n";
|
382 |
out = "Ok\n";
|
381 |
} else if (opflags & OPT_l) {
|
383 |
} else if (opflags & OPT_l) {
|
382 |
out = showReceivers();
|
384 |
out = showReceivers(opflags);
|
383 |
} else if (opflags & OPT_r) {
|
385 |
} else if (opflags & OPT_L) {
|
384 |
if (toks.size() < 3)
|
386 |
out = showSenders(opflags);
|
385 |
return 1;
|
|
|
386 |
vector<string>::iterator beg = toks.begin();
|
|
|
387 |
beg++;
|
|
|
388 |
string sender = *beg;
|
|
|
389 |
beg++;
|
|
|
390 |
vector<string> receivers(beg, toks.end());
|
|
|
391 |
setReceiversFromSender(sender, receivers);
|
|
|
392 |
} else if (opflags & OPT_s) {
|
387 |
} else if (opflags & OPT_s) {
|
393 |
if (toks.size() < 3)
|
388 |
if (toks.size() < 3)
|
394 |
return 1;
|
389 |
return 1;
|
395 |
vector<string>::iterator beg = toks.begin();
|
390 |
vector<string>::iterator beg = toks.begin();
|
396 |
beg++;
|
391 |
beg++;
|
|
... |
|
... |
409 |
return 1;
|
404 |
return 1;
|
410 |
vector<string>::iterator beg = toks.begin();
|
405 |
vector<string>::iterator beg = toks.begin();
|
411 |
beg++;
|
406 |
beg++;
|
412 |
vector<string> slaves(beg, toks.end());
|
407 |
vector<string> slaves(beg, toks.end());
|
413 |
stopReceivers(slaves);
|
408 |
stopReceivers(slaves);
|
|
|
409 |
} else if (opflags & OPT_r) {
|
|
|
410 |
if (toks.size() < 3)
|
|
|
411 |
return 1;
|
|
|
412 |
vector<string>::iterator beg = toks.begin();
|
|
|
413 |
beg++;
|
|
|
414 |
string sender = *beg;
|
|
|
415 |
beg++;
|
|
|
416 |
vector<string> receivers(beg, toks.end());
|
|
|
417 |
setReceiversFromSender(sender, receivers);
|
414 |
} else {
|
418 |
} else {
|
415 |
LOGERR("scctl: server: bad cmd:" << toks[0] << endl);
|
419 |
LOGERR("scctl: server: bad cmd:" << toks[0] << endl);
|
416 |
return 1;
|
420 |
return 1;
|
417 |
}
|
421 |
}
|
418 |
|
422 |
|
|
... |
|
... |
449 |
// Run
|
453 |
// Run
|
450 |
signal(SIGCHLD, SIG_IGN);
|
454 |
signal(SIGCHLD, SIG_IGN);
|
451 |
signal(SIGPIPE, SIG_IGN);
|
455 |
signal(SIGPIPE, SIG_IGN);
|
452 |
|
456 |
|
453 |
// Initialize lib at once, will be ready when we need it
|
457 |
// Initialize lib at once, will be ready when we need it
|
454 |
showReceivers();
|
458 |
showReceivers(0);
|
455 |
|
459 |
|
456 |
MyNetconServLis *servlis = new MyNetconServLis();
|
460 |
MyNetconServLis *servlis = new MyNetconServLis();
|
457 |
if (servlis == 0) {
|
461 |
if (servlis == 0) {
|
458 |
LOGERR("scctl: server: new NetconServLis failed\n");
|
462 |
LOGERR("scctl: server: new NetconServLis failed\n");
|
459 |
return 1;
|
463 |
return 1;
|