Skip to content

Commit d181244

Browse files
committed
Fix pairing
1 parent d07c6e6 commit d181244

File tree

4 files changed

+76
-20
lines changed

4 files changed

+76
-20
lines changed

README.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,38 @@ Based on libraop by philippe44 (all rights reserved). See upstream repo for more
66

77
## Building
88

9+
**IMPORTANT:** Always use `STATIC=1` to statically link OpenSSL from crosstools. This ensures the binary is self-contained and doesn't depend on system OpenSSL libraries.
10+
911
```sh
1012
apt-get update
1113
apt-get install -y build-essential cmake libssl-dev
1214
git clone https://github.com/music-assistant/libraop.git
1315
cd libraop
1416
git submodule update --init
1517

16-
# Build project for linux with static OpenSSL
17-
make HOST=linux PLATFORM=aarch64 STATIC=1
18+
# Build for Linux aarch64 (ALWAYS use STATIC=1!)
19+
make HOST=linux PLATFORM=aarch64 STATIC=1 -j4
1820

19-
# Build project for macOS with static OpenSSL
20-
make HOST=macos PLATFORM=arm64 STATIC=1
21+
# Build for macOS ARM64 (ALWAYS use STATIC=1!)
22+
make HOST=macos PLATFORM=arm64 STATIC=1 -j4
2123
```
2224

23-
**IMPORTANT:** Always use `STATIC=1` to statically link OpenSSL from crosstools. This ensures the binary is self-contained and doesn't depend on system OpenSSL libraries.
25+
### Development Workflow
26+
27+
When working on the code and testing changes:
28+
29+
```sh
30+
# Clean previous build
31+
make clean
32+
33+
# Rebuild with static OpenSSL (REQUIRED)
34+
make HOST=macos PLATFORM=arm64 STATIC=1 -j4
35+
36+
# Test the binary
37+
./bin/cliraop-macos-arm64 -pair <device_ip>
38+
```
39+
40+
**Common Mistakes:**
41+
-`make` without `STATIC=1` - will link against system OpenSSL (broken)
42+
-`CC=cc make HOST=macos PLATFORM=arm64` - will link against system OpenSSL (broken)
43+
-`make HOST=macos PLATFORM=arm64 STATIC=1` - correct way with static OpenSSL

src/cliraop.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,11 +528,13 @@ int main(int argc, char *argv[])
528528

529529
if (AppleTVpairing(NULL, &pair_secret, player.hostname, player.port))
530530
{
531-
printf("\nPairing successful!\nSecret: %s\n", pair_secret ? pair_secret : "(none)");
531+
fprintf(stderr, "\nPairing successful!\nSecret: %s\n", pair_secret ? pair_secret : "(none)");
532+
fflush(stderr);
532533
}
533534
else
534535
{
535-
printf("Pairing failed.\n");
536+
fprintf(stderr, "Pairing failed.\n");
537+
fflush(stderr);
536538
}
537539
exit(0);
538540
}

src/pairing.cpp

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,16 @@ extern "C" {
132132
bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const char *target_ip, int port) {
133133
// make sure we can safely free these
134134
A = a = NULL;
135+
bool success = false;
135136

136137
if (!target_ip || !*target_ip) {
137-
printf("Error: IP address is required for pairing\n");
138+
fprintf(stderr, "Error: IP address is required for pairing\n");
139+
fflush(stderr);
138140
return false;
139141
}
140142

141-
printf("Pairing with device at %s:%d\n", target_ip, port);
143+
fprintf(stderr, "Pairing with device at %s:%d\n", target_ip, port);
144+
fflush(stderr);
142145

143146
struct sockaddr_in peer = { };
144147
key_data_t headers[16] = { };
@@ -154,6 +157,11 @@ bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const ch
154157
kd_add(headers, "Content-Type", "application/octet-stream");
155158

156159
char *buffer = http_send(sock, "POST /pair-pin-start HTTP/1.1", headers);
160+
if (!buffer) {
161+
kd_free(headers);
162+
closesocket(sock);
163+
return false;
164+
}
157165
//printf("%s", buffer);
158166
NFREE(buffer);
159167
kd_free(headers);
@@ -172,7 +180,8 @@ bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const ch
172180
if (1) {
173181
#endif
174182
char pin[5];
175-
printf("enter PIN code displayed on AppleTV: ");
183+
fprintf(stderr, "enter PIN code displayed on AppleTV:\n");
184+
fflush(stderr);
176185
#ifndef TEST_VECTOR
177186
(void)!scanf("%4s", pin);
178187
#else
@@ -196,9 +205,15 @@ bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const ch
196205
kd_vadd(headers, "Content-Length", "%zu", data.size());
197206

198207
char* httpStr = http_send(sock, "POST /pair-setup-pin HTTP/1.1", headers);
208+
if (!httpStr) {
209+
kd_free(headers);
210+
closesocket(sock);
211+
return false;
212+
}
199213
send(sock, (const char*) data.data(), data.size(), 0);
200214
//printf("%s", httpStr);
201-
printf("step1 ... verifying pin\n");
215+
fprintf(stderr, "step1 ... verifying pin\n");
216+
fflush(stderr);
202217
NFREE(httpStr);
203218
kd_free(headers);
204219

@@ -234,8 +249,14 @@ bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const ch
234249
kd_vadd(headers, "Content-Length", "%zu", data.size());
235250

236251
char* httpStr = http_send(sock, "POST /pair-setup-pin HTTP/1.1", headers);
252+
if (!httpStr) {
253+
kd_free(headers);
254+
closesocket(sock);
255+
return false;
256+
}
237257
send(sock, (const char*)data.data(), data.size(), 0);
238-
printf("step2 ... verifying M1\n");
258+
fprintf(stderr, "step2 ... verifying M1\n");
259+
fflush(stderr);
239260
//printf("%s", httpStr);
240261
NFREE(httpStr);
241262
kd_free(headers);
@@ -304,9 +325,15 @@ bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const ch
304325
kd_vadd(headers, "Content-Length", "%zu", data.size());
305326

306327
char* httpStr = http_send(sock, "POST /pair-setup-pin HTTP/1.1", headers);
328+
if (!httpStr) {
329+
kd_free(headers);
330+
closesocket(sock);
331+
return false;
332+
}
307333
send(sock, (const char*)data.data(), data.size(), 0);
308334
//printf("%s", httpStr);
309-
printf("step3 ... verifying AES\n");
335+
fprintf(stderr, "step3 ... verifying AES\n");
336+
fflush(stderr);
310337
NFREE(httpStr);
311338
kd_free(headers);
312339

@@ -320,24 +347,31 @@ bool AppleTVpairing(struct mdnssd_handle_s* mDNShandle, char **pSecret, const ch
320347
if (1) {
321348
#endif
322349

323-
printf("success!\nsecret is %s\n", *pSecret);
350+
fprintf(stderr, "success!\nsecret is %s\n", *pSecret);
351+
fflush(stderr);
352+
success = true;
324353
} else {
325-
printf("can't authentify, error %s", resource);
354+
fprintf(stderr, "can't authentify, error %s\n", resource);
355+
fflush(stderr);
326356
}
327357
}
328358
} else {
329-
printf("pin failed %s", resource);
359+
fprintf(stderr, "pin failed %s\n", resource);
360+
fflush(stderr);
330361
}
331362

332363
NFREE(body);
333-
}
364+
} else {
365+
fprintf(stderr, "device did not respond to pairing request\n");
366+
fflush(stderr);
367+
}
334368

335369
if (a) BN_free(a);
336370
if (A) BN_free(A);
337371

338372
kd_free(headers);
339373
if (sock != -1) closesocket(sock);
340-
return true;
374+
return success;
341375
}
342376

343377
} // extern "C"

src/raop_client.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,8 @@ bool raopcl_connect(struct raopcl_s *p, struct in_addr peer, uint16_t destport,
10091009
// RTSP pairing verify for AppleTV
10101010
if (*p->secret && !rtspcl_pair_verify(p->rtspcl, p->secret)) goto erexit;
10111011

1012-
// Send pubkey for MFi devices
1013-
if (strchr(p->et, '4')) rtspcl_auth_setup(p->rtspcl);
1012+
// Send pubkey for MFi devices (but not if we already did pair-verify)
1013+
if (strchr(p->et, '4') && !*p->secret) rtspcl_auth_setup(p->rtspcl);
10141014

10151015
// build sdp parameter
10161016
buf = strdup(inet_ntoa(peer));

0 commit comments

Comments
 (0)