Commit | Line | Data |
---|---|---|
2340bcd3 JVH |
1 | #include <stdlib.h> |
2 | #include <unistd.h> | |
3 | #include <stdio.h> | |
4 | #include <string.h> | |
5 | #include <assert.h> | |
6 | ||
7 | #include <ao/ao.h> | |
8 | ||
9 | #include "dnssd.h" | |
10 | #include "airplay.h" | |
11 | #include "raop.h" | |
12 | #include "rsakey.h" | |
13 | #include "utils.h" | |
14 | ||
15 | #define CHALLENGE "LfBLs2pkGT4yYAJrxj2K9Q==" | |
16 | static unsigned char ipaddr[] = { 192, 168, 1, 10 }; | |
17 | static unsigned char hwaddr[] = { 0x00, 0x5A, 0xDB, 0xE4, 0xE6, 0xFD }; | |
18 | ||
19 | #define AESENC "B69yRGHoriZZeJNKghotJi6Pt7dEPEwKSoieM6dk8YE1D23/jyOsg0ZoJZmodHB4lR9Q9CmeoqgU0GX1KkYNafCrNUlXxJAZuMTISGmyeDegnH73ul1NQwIjfphGgwrx7dp7J+p4lyQi+Yt/daQyjE//Od0viD37GQtI9B7GukaiWrMl94wJmSLUL94VpKUxnD9E7T/LesX7bEMfUgSQUpIE+T2anp6eRqE/5R3kNYdEH9JcCEFu5DLqbbvMqgc0ewr81BNeVG5ck1iI2eF+OJVm9g082ZXqGAPFGwmcYiiLfjrQY5hnEUi7IeWqgX5Xd82DyW9BeDzT5MXVyI/GwQ==" | |
20 | ||
21 | static void | |
22 | test_rsa(const char *pemstr) | |
23 | { | |
24 | char buffer[2048]; | |
25 | int ret; | |
26 | rsakey_t *rsakey; | |
27 | ||
28 | rsakey = rsakey_init_pem(pemstr); | |
29 | if (!rsakey) { | |
30 | printf("Initializing RSA failed\n"); | |
31 | return; | |
32 | } | |
33 | ||
34 | rsakey_sign(rsakey, buffer, sizeof(buffer), CHALLENGE, | |
35 | ipaddr, sizeof(ipaddr), hwaddr, sizeof(hwaddr)); | |
36 | printf("Signature:\n%s\n", buffer); | |
37 | ||
38 | ret = rsakey_decrypt(rsakey, (unsigned char *)buffer, sizeof(buffer), AESENC); | |
39 | printf("Decrypted length: %d\n", ret); | |
40 | ||
41 | rsakey_destroy(rsakey); | |
42 | } | |
43 | ||
44 | static void | |
45 | photo_cb(char *data, int datalen) | |
46 | { | |
47 | char template[512]; | |
48 | int written = 0; | |
49 | int fd, ret; | |
50 | ||
51 | printf("Got photo with data length: %d\n", datalen); | |
52 | ||
53 | memset(template, 0, sizeof(template)); | |
54 | strcpy(template, "/tmp/tmpXXXXXX.JPG"); | |
55 | fd = mkstemps(template, 4); | |
56 | ||
57 | while (written < datalen) { | |
58 | ret = write(fd, data+written, datalen-written); | |
59 | if (ret <= 0) break; | |
60 | written += ret; | |
61 | } | |
62 | if (written == datalen) { | |
63 | printf("Wrote to file %s\n", template); | |
64 | } | |
65 | close(fd); | |
66 | } | |
67 | ||
68 | static void | |
69 | play_cb() | |
70 | { | |
71 | } | |
72 | ||
73 | static void | |
74 | stop_cb() | |
75 | { | |
76 | } | |
77 | ||
78 | static void | |
79 | rate_set_cb() | |
80 | { | |
81 | } | |
82 | ||
83 | static void | |
84 | scrub_get_cb() | |
85 | { | |
86 | } | |
87 | ||
88 | static void | |
89 | scrub_set_cb() | |
90 | { | |
91 | } | |
92 | ||
93 | static void | |
94 | playback_info_cb() | |
95 | { | |
96 | } | |
97 | ||
98 | static void * | |
99 | audio_init(void *opaque, int bits, int channels, int samplerate) | |
100 | { | |
101 | int driver; | |
102 | ao_sample_format format; | |
103 | ao_option *ao_opts = NULL; | |
104 | ao_device *device; | |
105 | ||
106 | printf("Opening audio device\n"); | |
107 | driver = ao_driver_id("pulse"); | |
108 | ||
109 | memset(&format, 0, sizeof(format)); | |
110 | format.bits = bits; | |
111 | format.channels = channels; | |
112 | format.rate = samplerate; | |
113 | format.byte_format = AO_FMT_LITTLE; | |
114 | ||
115 | ao_append_option(&ao_opts, "id", "0"); | |
116 | device = ao_open_live(driver, &format, ao_opts); | |
117 | if (!device) { | |
118 | fprintf(stderr, "Error opening audio device.\n"); | |
119 | } else { | |
120 | printf("Opening device successful\n"); | |
121 | } | |
122 | return device; | |
123 | } | |
124 | ||
125 | static void | |
126 | audio_process(void *ptr, const void *buffer, int buflen) | |
127 | { | |
128 | ao_device *device = ptr; | |
129 | ||
130 | assert(device); | |
131 | ||
132 | printf("Got %d bytes of audio\n", buflen); | |
133 | ao_play(device, (char *)buffer, buflen); | |
134 | } | |
135 | ||
136 | static void | |
137 | audio_flush(void *ptr) | |
138 | { | |
139 | } | |
140 | ||
141 | static void | |
142 | audio_destroy(void *ptr) | |
143 | { | |
144 | ao_device *device = ptr; | |
145 | ||
146 | printf("Closing audio device\n"); | |
147 | ao_close(device); | |
148 | } | |
149 | ||
150 | int | |
151 | main(int argc, char *argv[]) | |
152 | { | |
153 | const char *name = "AppleTV"; | |
154 | unsigned short raop_port = 5000; | |
155 | unsigned short airplay_port = 7000; | |
156 | const char hwaddr[] = { 0x48, 0x5d, 0x60, 0x7c, 0xee, 0x22 }; | |
157 | char *pemstr; | |
158 | ||
159 | dnssd_t *dnssd; | |
160 | airplay_t *airplay; | |
161 | airplay_callbacks_t ap_cbs; | |
162 | raop_t *raop; | |
163 | raop_callbacks_t raop_cbs; | |
164 | ||
165 | if (utils_read_file(&pemstr, "airport.key") < 0) { | |
166 | return -1; | |
167 | } | |
168 | if (argc > 1) { | |
169 | test_rsa(pemstr); | |
170 | } | |
171 | ||
172 | ao_initialize(); | |
173 | ||
174 | dnssd = dnssd_init(hwaddr, sizeof(hwaddr), NULL); | |
175 | dnssd_register_raop(dnssd, name, raop_port); | |
176 | dnssd_register_airplay(dnssd, name, airplay_port); | |
177 | ||
178 | ap_cbs.photo_cb = &photo_cb; | |
179 | ap_cbs.play_cb = &play_cb; | |
180 | ap_cbs.stop_cb = &stop_cb; | |
181 | ap_cbs.rate_set_cb = &rate_set_cb; | |
182 | ap_cbs.scrub_get_cb = &scrub_get_cb; | |
183 | ap_cbs.scrub_set_cb = &scrub_set_cb; | |
184 | ap_cbs.playback_info_cb = &playback_info_cb; | |
185 | ||
186 | raop_cbs.audio_init = audio_init; | |
187 | raop_cbs.audio_process = audio_process; | |
188 | raop_cbs.audio_flush = audio_flush; | |
189 | raop_cbs.audio_destroy = audio_destroy; | |
190 | ||
191 | airplay = airplay_init(&ap_cbs, hwaddr, sizeof(hwaddr)); | |
192 | airplay_start(airplay, airplay_port); | |
193 | ||
194 | raop = raop_init(&raop_cbs, pemstr, hwaddr, sizeof(hwaddr)); | |
195 | raop_start(raop, &raop_port); | |
196 | ||
197 | sleep(100); | |
198 | ||
199 | raop_stop(raop); | |
200 | raop_destroy(raop); | |
201 | ||
202 | airplay_stop(airplay); | |
203 | airplay_destroy(airplay); | |
204 | ||
205 | dnssd_unregister_airplay(dnssd); | |
206 | dnssd_unregister_raop(dnssd); | |
207 | dnssd_destroy(dnssd); | |
208 | ||
209 | ao_shutdown(); | |
210 | ||
211 | return 0; | |
212 | } | |
213 |