diff options
-rw-r--r-- | apps/iap.c | 1141 |
1 files changed, 578 insertions, 563 deletions
diff --git a/apps/iap.c b/apps/iap.c index d432a16dc3..7447c67ba9 100644 --- a/apps/iap.c +++ b/apps/iap.c | |||
@@ -218,636 +218,651 @@ static void iap_set_remote_volume(void) | |||
218 | iap_send_pkt(data, sizeof(data)); | 218 | iap_send_pkt(data, sizeof(data)); |
219 | } | 219 | } |
220 | 220 | ||
221 | void iap_handlepkt(void) | 221 | static void iap_handlepkt_mode0(void) |
222 | { | 222 | { |
223 | unsigned int cmd = serbuf[2]; | ||
224 | switch (cmd) { | ||
225 | |||
226 | case 0x24: | ||
227 | { | ||
228 | /* ipod video send this */ | ||
229 | unsigned char data[] = {0x00, 0x25, 0x00, 0x00, 0x00, | ||
230 | 0x00, 0x00, 0x00, 0x00, 0x01}; | ||
231 | iap_send_pkt(data, sizeof(data)); | ||
232 | break; | ||
233 | } | ||
223 | 234 | ||
224 | if(!iap_setupflag) return; | 235 | case 0x18: |
225 | if(serbuf[0] == 0) return; | 236 | { |
226 | 237 | /* ciphered authentication command */ | |
227 | /* if we are waiting for a remote button to go out, | 238 | /* Isn't used since we don't send the 0x00 0x17 command */ |
228 | delay the handling of the new packet */ | 239 | break; |
229 | if(!iap_remotetick) | 240 | } |
230 | { | ||
231 | queue_post(&button_queue, SYS_IAP_HANDLEPKT, 0); | ||
232 | return; | ||
233 | } | ||
234 | 241 | ||
235 | /* Handle Mode 0 */ | 242 | case 0x15: |
236 | if (serbuf[1] == 0x00) | ||
237 | { | ||
238 | switch (serbuf[2]) | ||
239 | { | 243 | { |
240 | case 0x24: | 244 | unsigned char data0[] = {0x00, 0x16, 0x00}; |
241 | { | 245 | iap_send_pkt(data0, sizeof(data0)); |
242 | /* ipod video send this */ | 246 | unsigned char data1[] = {0x00, 0x27, 0x00}; |
243 | unsigned char data[] = {0x00, 0x25, 0x00, 0x00, 0x00, | 247 | iap_send_pkt(data1, sizeof(data1)); |
244 | 0x00, 0x00, 0x00, 0x00,0x01}; | 248 | /* authentication ack, mandatory to enable some hardware */ |
245 | iap_send_pkt(data, sizeof(data)); | 249 | unsigned char data2[] = {0x00, 0x19, 0x00}; |
246 | break; | 250 | iap_send_pkt(data2, sizeof(data2)); |
247 | } | 251 | if (radio_present == 1) |
252 | { | ||
253 | /* get tuner capacities */ | ||
254 | unsigned char data3[] = {0x07, 0x01}; | ||
255 | iap_send_pkt(data3, sizeof(data3)); | ||
256 | } | ||
257 | iap_set_remote_volume(); | ||
258 | break; | ||
259 | } | ||
248 | 260 | ||
249 | case 0x18: | 261 | case 0x13: |
250 | { | 262 | { |
251 | /* ciphered authentication command */ | 263 | unsigned char data[] = {0x00, 0x02, 0x00, 0x13}; |
252 | /* Isn't used since we don't send the 0x00 0x17 command */ | 264 | iap_send_pkt(data, sizeof(data)); |
253 | break; | ||
254 | } | ||
255 | 265 | ||
256 | case 0x15: | 266 | if (serbuf[6] == 0x35) |
267 | /* FM transmitter sends this: */ | ||
268 | /* FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (??)*/ | ||
257 | { | 269 | { |
258 | unsigned char data0[] = {0x00, 0x16, 0x00}; | 270 | unsigned char data2[] = {0x00, 0x27, 0x00}; |
259 | iap_send_pkt(data0, sizeof(data0)); | ||
260 | unsigned char data1[] = {0x00, 0x27, 0x00}; | ||
261 | iap_send_pkt(data1, sizeof(data1)); | ||
262 | /* authentication ack, mandatory to enable some hardware */ | ||
263 | unsigned char data2[] = {0x00, 0x19, 0x00}; | ||
264 | iap_send_pkt(data2, sizeof(data2)); | 271 | iap_send_pkt(data2, sizeof(data2)); |
265 | if (radio_present == 1) | 272 | unsigned char data3[] = {0x05, 0x02}; |
266 | { | 273 | iap_send_pkt(data3, sizeof(data3)); |
267 | /* get tuner capacities */ | ||
268 | unsigned char data3[] = {0x07, 0x01}; | ||
269 | iap_send_pkt(data3, sizeof(data3)); | ||
270 | } | ||
271 | iap_set_remote_volume(); | ||
272 | break; | ||
273 | } | 274 | } |
274 | 275 | ||
275 | case 0x13: | 276 | else |
276 | { | 277 | { |
277 | unsigned char data[] = {0x00, 0x02, 0x00, 0x13}; | 278 | /* ipod fm remote sends this: */ |
278 | iap_send_pkt(data, sizeof(data)); | 279 | /* FF 55 0E 00 13 00 00 00 8D 00 00 00 0E 00 00 00 03 41 */ |
279 | 280 | if (serbuf[6] |= 0x80) | |
280 | if (serbuf[6] == 0x35) | 281 | radio_present = 1; |
281 | /* FM transmitter sends this: */ | 282 | unsigned char data4[] = {0x00, 0x14}; |
282 | /* FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (??)*/ | 283 | iap_send_pkt(data4, sizeof(data4)); |
283 | { | ||
284 | unsigned char data2[] = {0x00, 0x27, 0x00}; | ||
285 | iap_send_pkt(data2, sizeof(data2)); | ||
286 | unsigned char data3[] = {0x05, 0x02}; | ||
287 | iap_send_pkt(data3, sizeof(data3)); | ||
288 | } | ||
289 | |||
290 | else | ||
291 | { | ||
292 | /* ipod fm remote sends this: */ | ||
293 | /* FF 55 0E 00 13 00 00 00 8D 00 00 00 0E 00 00 00 03 41 */ | ||
294 | if (serbuf[6] |= 0x80) | ||
295 | radio_present = 1; | ||
296 | unsigned char data4[] = {0x00, 0x14}; | ||
297 | iap_send_pkt(data4, sizeof(data4)); | ||
298 | } | ||
299 | break; | ||
300 | } | 284 | } |
285 | break; | ||
286 | } | ||
301 | 287 | ||
302 | /* Init */ | 288 | /* Init */ |
303 | case 0x0F: | 289 | case 0x0F: |
304 | { | 290 | { |
305 | unsigned char data[] = {0x00, 0x10, 0x00, 0x01, 0x05}; | 291 | unsigned char data[] = {0x00, 0x10, 0x00, 0x01, 0x05}; |
306 | data[2] = serbuf[3]; | 292 | data[2] = serbuf[3]; |
307 | iap_send_pkt(data, sizeof(data)); | 293 | iap_send_pkt(data, sizeof(data)); |
308 | break; | 294 | break; |
309 | } | 295 | } |
310 | 296 | ||
311 | /* get model info */ | 297 | /* get model info */ |
312 | case 0x0D: | 298 | case 0x0D: |
313 | { | 299 | { |
314 | /* ipod is supposed to work only with 5G and nano 2G */ | 300 | /* ipod is supposed to work only with 5G and nano 2G */ |
315 | /*{0x00, 0x0E, 0x00, 0x0B, 0x00, 0x05, 0x50, 0x41, 0x31, 0x34, | 301 | /*{0x00, 0x0E, 0x00, 0x0B, 0x00, 0x05, 0x50, 0x41, 0x31, 0x34, |
316 | 0x37, 0x4C, 0x4C, 0x00}; PA147LL (IPOD 5G 60 GO) */ | 302 | 0x37, 0x4C, 0x4C, 0x00}; PA147LL (IPOD 5G 60 GO) */ |
317 | unsigned char data[] = {0x00, 0x0E, 0x00, 0x0B, 0x00, 0x10, | 303 | unsigned char data[] = {0x00, 0x0E, 0x00, 0x0B, 0x00, 0x10, |
318 | 'R', 'O', 'C', 'K', 'B', 'O', 'X', 0x00}; | 304 | 'R', 'O', 'C', 'K', 'B', 'O', 'X', 0x00}; |
319 | iap_send_pkt(data, sizeof(data)); | 305 | iap_send_pkt(data, sizeof(data)); |
320 | break; | 306 | break; |
321 | } | 307 | } |
322 | 308 | ||
323 | /* Ipod FM remote sends this: FF 55 02 00 09 F5 */ | 309 | /* Ipod FM remote sends this: FF 55 02 00 09 F5 */ |
324 | case 0x09: | 310 | case 0x09: |
325 | { | 311 | { |
326 | /* ipod5G firmware version */ | 312 | /* ipod5G firmware version */ |
327 | unsigned char data[] = {0x00, 0x0A, 0x01, 0x02, 0x01 }; | 313 | unsigned char data[] = {0x00, 0x0A, 0x01, 0x02, 0x01 }; |
328 | iap_send_pkt(data, sizeof(data)); | 314 | iap_send_pkt(data, sizeof(data)); |
329 | break; | 315 | break; |
330 | } | 316 | } |
317 | |||
318 | /* FM transmitter sends this: */ | ||
319 | /* FF 55 02 00 05 F9 (mode switch: AiR mode) */ | ||
320 | case 0x05: | ||
321 | { | ||
322 | unsigned char data[] = {0x00, 0x02, 0x06, | ||
323 | 0x05, 0x00, 0x00, 0x0B, 0xB8, 0x28}; | ||
324 | iap_send_pkt(data, sizeof(data)); | ||
325 | unsigned char data2[] = {0x00, 0x02, 0x00, 0x05}; | ||
326 | iap_send_pkt(data2, sizeof(data2)); | ||
327 | break; | ||
328 | } | ||
331 | 329 | ||
330 | case 0x01: | ||
331 | { | ||
332 | /* FM transmitter sends this: */ | 332 | /* FM transmitter sends this: */ |
333 | /* FF 55 02 00 05 F9 (mode switch: AiR mode) */ | 333 | /* FF 55 06 00 01 05 00 02 01 F1 (mode switch) */ |
334 | case 0x05: | 334 | if(serbuf[3] == 0x05) |
335 | { | 335 | { |
336 | unsigned char data[] = {0x00, 0x02, 0x06, | 336 | sleep(HZ/3); |
337 | 0x05, 0x00, 0x00, 0x0B, 0xB8, 0x28}; | 337 | unsigned char data[] = {0x05, 0x02}; |
338 | iap_send_pkt(data, sizeof(data)); | 338 | iap_send_pkt(data, sizeof(data)); |
339 | unsigned char data2[] = {0x00, 0x02, 0x00, 0x05}; | ||
340 | iap_send_pkt(data2, sizeof(data2)); | ||
341 | break; | ||
342 | } | 339 | } |
343 | 340 | /* FM remote sends this: */ | |
344 | case 0x01: | 341 | /* FF 55 03 00 01 02 FA (1st thing sent) */ |
342 | else if(serbuf[3] == 0x02) | ||
345 | { | 343 | { |
346 | /* FM transmitter sends this: */ | 344 | /* useful only for apple firmware */ |
347 | /* FF 55 06 00 01 05 00 02 01 F1 (mode switch) */ | ||
348 | if(serbuf[3] == 0x05) | ||
349 | { | ||
350 | sleep(HZ/3); | ||
351 | unsigned char data[] = {0x05, 0x02}; | ||
352 | iap_send_pkt(data, sizeof(data)); | ||
353 | } | ||
354 | /* FM remote sends this: */ | ||
355 | /* FF 55 03 00 01 02 FA (1st thing sent) */ | ||
356 | else if(serbuf[3] == 0x02) | ||
357 | { | ||
358 | /* useful only for apple firmware */ | ||
359 | } | ||
360 | break; | ||
361 | } | 345 | } |
346 | break; | ||
347 | } | ||
362 | 348 | ||
363 | /* default response is with cmd ok packet */ | 349 | /* default response is with cmd ok packet */ |
364 | default: | 350 | default: |
365 | { | 351 | { |
366 | unsigned char data[] = {0x00, 0x02, 0x00, 0x00}; | 352 | unsigned char data[] = {0x00, 0x02, 0x00, 0x00}; |
367 | data[3] = serbuf[2]; /* respond with cmd */ | 353 | data[3] = cmd; /* respond with cmd */ |
368 | iap_send_pkt(data, sizeof(data)); | 354 | iap_send_pkt(data, sizeof(data)); |
369 | break; | 355 | break; |
370 | } | ||
371 | } | 356 | } |
372 | } | 357 | } |
373 | /* Handle Mode 2 */ | 358 | } |
374 | else if (serbuf[1] == 0x02) | 359 | |
360 | static void iap_handlepkt_mode2(void) | ||
361 | { | ||
362 | if(serbuf[2] != 0) return; | ||
363 | iap_remotebtn = BUTTON_NONE; | ||
364 | iap_remotetick = false; | ||
365 | |||
366 | if(serbuf[0] >= 3 && serbuf[3] != 0) | ||
375 | { | 367 | { |
376 | if(serbuf[2] != 0) return; | 368 | if(serbuf[3] & 1) |
377 | iap_remotebtn = BUTTON_NONE; | 369 | iap_remotebtn |= BUTTON_RC_PLAY; |
378 | iap_remotetick = false; | 370 | if(serbuf[3] & 2) |
379 | 371 | iap_remotebtn |= BUTTON_RC_VOL_UP; | |
380 | if(serbuf[0] >= 3 && serbuf[3] != 0) | 372 | if(serbuf[3] & 4) |
373 | iap_remotebtn |= BUTTON_RC_VOL_DOWN; | ||
374 | if(serbuf[3] & 8) | ||
375 | iap_remotebtn |= BUTTON_RC_RIGHT; | ||
376 | if(serbuf[3] & 16) | ||
377 | iap_remotebtn |= BUTTON_RC_LEFT; | ||
378 | } | ||
379 | else if(serbuf[0] >= 4 && serbuf[4] != 0) | ||
380 | { | ||
381 | if(serbuf[4] & 1) /* play */ | ||
381 | { | 382 | { |
382 | if(serbuf[3] & 1) | 383 | if (audio_status() != AUDIO_STATUS_PLAY) |
383 | iap_remotebtn |= BUTTON_RC_PLAY; | ||
384 | if(serbuf[3] & 2) | ||
385 | iap_remotebtn |= BUTTON_RC_VOL_UP; | ||
386 | if(serbuf[3] & 4) | ||
387 | iap_remotebtn |= BUTTON_RC_VOL_DOWN; | ||
388 | if(serbuf[3] & 8) | ||
389 | iap_remotebtn |= BUTTON_RC_RIGHT; | ||
390 | if(serbuf[3] & 16) | ||
391 | iap_remotebtn |= BUTTON_RC_LEFT; | ||
392 | } | ||
393 | else if(serbuf[0] >= 4 && serbuf[4] != 0) | ||
394 | { | ||
395 | if(serbuf[4] & 1) /* play */ | ||
396 | { | 384 | { |
397 | if (audio_status() != AUDIO_STATUS_PLAY) | 385 | iap_remotebtn |= BUTTON_RC_PLAY; |
398 | { | 386 | iap_repeatbtn = 2; |
399 | iap_remotebtn |= BUTTON_RC_PLAY; | 387 | iap_remotetick = false; |
400 | iap_repeatbtn = 2; | 388 | iap_changedctr = 1; |
401 | iap_remotetick = false; | ||
402 | iap_changedctr = 1; | ||
403 | } | ||
404 | } | ||
405 | if(serbuf[4] & 2) /* pause */ | ||
406 | { | ||
407 | if (audio_status() == AUDIO_STATUS_PLAY) | ||
408 | { | ||
409 | iap_remotebtn |= BUTTON_RC_PLAY; | ||
410 | iap_repeatbtn = 2; | ||
411 | iap_remotetick = false; | ||
412 | iap_changedctr = 1; | ||
413 | } | ||
414 | } | 389 | } |
415 | if((serbuf[4] & 128) && !iap_btnshuffle) /* shuffle */ | 390 | } |
391 | if(serbuf[4] & 2) /* pause */ | ||
392 | { | ||
393 | if (audio_status() == AUDIO_STATUS_PLAY) | ||
416 | { | 394 | { |
417 | iap_btnshuffle = true; | 395 | iap_remotebtn |= BUTTON_RC_PLAY; |
418 | if(!global_settings.playlist_shuffle) | 396 | iap_repeatbtn = 2; |
419 | { | 397 | iap_remotetick = false; |
420 | global_settings.playlist_shuffle = 1; | 398 | iap_changedctr = 1; |
421 | settings_save(); | ||
422 | if (audio_status() & AUDIO_STATUS_PLAY) | ||
423 | playlist_randomise(NULL, current_tick, true); | ||
424 | } | ||
425 | else if(global_settings.playlist_shuffle) | ||
426 | { | ||
427 | global_settings.playlist_shuffle = 0; | ||
428 | settings_save(); | ||
429 | if (audio_status() & AUDIO_STATUS_PLAY) | ||
430 | playlist_sort(NULL, true); | ||
431 | } | ||
432 | } | 399 | } |
433 | else | ||
434 | iap_btnshuffle = false; | ||
435 | } | 400 | } |
436 | else if(serbuf[0] >= 5 && serbuf[5] != 0) | 401 | if((serbuf[4] & 128) && !iap_btnshuffle) /* shuffle */ |
437 | { | 402 | { |
438 | if((serbuf[5] & 1) && !iap_btnrepeat) /* repeat */ | 403 | iap_btnshuffle = true; |
404 | if(!global_settings.playlist_shuffle) | ||
439 | { | 405 | { |
440 | int oldmode = global_settings.repeat_mode; | 406 | global_settings.playlist_shuffle = 1; |
441 | iap_btnrepeat = true; | ||
442 | |||
443 | if (oldmode == REPEAT_ONE) | ||
444 | global_settings.repeat_mode = REPEAT_OFF; | ||
445 | else if (oldmode == REPEAT_ALL) | ||
446 | global_settings.repeat_mode = REPEAT_ONE; | ||
447 | else if (oldmode == REPEAT_OFF) | ||
448 | global_settings.repeat_mode = REPEAT_ALL; | ||
449 | |||
450 | settings_save(); | 407 | settings_save(); |
451 | if (audio_status() & AUDIO_STATUS_PLAY) | 408 | if (audio_status() & AUDIO_STATUS_PLAY) |
452 | audio_flush_and_reload_tracks(); | 409 | playlist_randomise(NULL, current_tick, true); |
453 | } | 410 | } |
454 | else | 411 | else if(global_settings.playlist_shuffle) |
455 | iap_btnrepeat = false; | ||
456 | |||
457 | if(serbuf[5] & 16) /* ffwd */ | ||
458 | { | 412 | { |
459 | iap_remotebtn |= BUTTON_RC_RIGHT; | 413 | global_settings.playlist_shuffle = 0; |
460 | } | 414 | settings_save(); |
461 | if(serbuf[5] & 32) /* frwd */ | 415 | if (audio_status() & AUDIO_STATUS_PLAY) |
462 | { | 416 | playlist_sort(NULL, true); |
463 | iap_remotebtn |= BUTTON_RC_LEFT; | ||
464 | } | 417 | } |
465 | } | 418 | } |
419 | else | ||
420 | iap_btnshuffle = false; | ||
466 | } | 421 | } |
467 | /* Handle Mode 3 */ | 422 | else if(serbuf[0] >= 5 && serbuf[5] != 0) |
468 | else if (serbuf[1] == 0x03) | ||
469 | { | 423 | { |
470 | switch(serbuf[2]) | 424 | if((serbuf[5] & 1) && !iap_btnrepeat) /* repeat */ |
471 | { | 425 | { |
472 | /* some kind of status packet? */ | 426 | int oldmode = global_settings.repeat_mode; |
473 | case 0x01: | 427 | iap_btnrepeat = true; |
474 | { | 428 | |
475 | unsigned char data[] = {0x03, 0x02, 0x00, 0x00, 0x00, 0x00}; | 429 | if (oldmode == REPEAT_ONE) |
476 | iap_send_pkt(data, sizeof(data)); | 430 | global_settings.repeat_mode = REPEAT_OFF; |
477 | break; | 431 | else if (oldmode == REPEAT_ALL) |
478 | } | 432 | global_settings.repeat_mode = REPEAT_ONE; |
433 | else if (oldmode == REPEAT_OFF) | ||
434 | global_settings.repeat_mode = REPEAT_ALL; | ||
479 | 435 | ||
480 | case 0x08: | 436 | settings_save(); |
481 | { | 437 | if (audio_status() & AUDIO_STATUS_PLAY) |
482 | /* ACK */ | 438 | audio_flush_and_reload_tracks(); |
483 | unsigned char data[] = {0x03, 0x00, 0x00, 0x08}; | 439 | } |
484 | iap_send_pkt(data, sizeof(data)); | 440 | else |
485 | break; | 441 | iap_btnrepeat = false; |
486 | } | 442 | |
487 | 443 | if(serbuf[5] & 16) /* ffwd */ | |
488 | case 0x0C: | 444 | { |
489 | { | 445 | iap_remotebtn |= BUTTON_RC_RIGHT; |
490 | /* request ipod volume */ | 446 | } |
491 | if (serbuf[3] == 0x04) | 447 | if(serbuf[5] & 32) /* frwd */ |
492 | { | 448 | { |
493 | iap_set_remote_volume(); | 449 | iap_remotebtn |= BUTTON_RC_LEFT; |
494 | } | ||
495 | break; | ||
496 | } | ||
497 | /* get volume from accessory */ | ||
498 | case 0x0E: | ||
499 | if (serbuf[3] == 0x04) | ||
500 | global_settings.volume = (-58)+((int)serbuf[5]+1)/4; | ||
501 | sound_set_volume(global_settings.volume); | ||
502 | break; | ||
503 | } | 450 | } |
504 | } | 451 | } |
505 | /* Handle Mode 4 */ | 452 | } |
506 | else if (serbuf[1] == 0x04) | 453 | |
454 | static void iap_handlepkt_mode3(void) | ||
455 | { | ||
456 | unsigned int cmd = serbuf[2]; | ||
457 | switch (cmd) | ||
507 | { | 458 | { |
508 | switch (((unsigned long)serbuf[2] << 8) | serbuf[3]) | 459 | /* some kind of status packet? */ |
460 | case 0x01: | ||
509 | { | 461 | { |
510 | /* Get data updated??? flag */ | 462 | unsigned char data[] = {0x03, 0x02, 0x00, 0x00, 0x00, 0x00}; |
511 | case 0x0009: | 463 | iap_send_pkt(data, sizeof(data)); |
512 | { | 464 | break; |
513 | unsigned char data[] = {0x04, 0x00, 0x0A, 0x00}; | 465 | } |
514 | data[3] = iap_updateflag ? 0 : 1; | 466 | |
515 | iap_send_pkt(data, sizeof(data)); | 467 | case 0x08: |
516 | break; | 468 | { |
517 | } | 469 | /* ACK */ |
518 | /* Set data updated??? flag */ | 470 | unsigned char data[] = {0x03, 0x00, 0x00, 0x08}; |
519 | case 0x000B: | 471 | iap_send_pkt(data, sizeof(data)); |
520 | { | 472 | break; |
521 | iap_updateflag = serbuf[4] ? 0 : 1; | 473 | } |
522 | /* respond with cmd ok packet */ | 474 | |
523 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x0B}; | 475 | case 0x0C: |
524 | iap_send_pkt(data, sizeof(data)); | 476 | { |
525 | break; | 477 | /* request ipod volume */ |
526 | } | 478 | if (serbuf[3] == 0x04) |
527 | /* Get iPod size? */ | ||
528 | case 0x0012: | ||
529 | { | ||
530 | unsigned char data[] = {0x04, 0x00, 0x13, 0x01, 0x0B}; | ||
531 | iap_send_pkt(data, sizeof(data)); | ||
532 | break; | ||
533 | } | ||
534 | /* Get count of given types */ | ||
535 | case 0x0018: | ||
536 | { | ||
537 | unsigned char data[] = {0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00}; | ||
538 | unsigned long num = 0; | ||
539 | switch(serbuf[4]) /* type number */ | ||
540 | { | ||
541 | case 0x01: /* total number of playlists */ | ||
542 | num = 1; | ||
543 | break; | ||
544 | case 0x05: /* total number of songs */ | ||
545 | num = 1; | ||
546 | } | ||
547 | data[3] = num >> 24; | ||
548 | data[4] = num >> 16; | ||
549 | data[5] = num >> 8; | ||
550 | data[6] = num; | ||
551 | iap_send_pkt(data, sizeof(data)); | ||
552 | break; | ||
553 | } | ||
554 | /* Get time and status */ | ||
555 | case 0x001C: | ||
556 | { | ||
557 | unsigned char data[] = {0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, | ||
558 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
559 | struct mp3entry *id3 = audio_current_track(); | ||
560 | unsigned long time_total = id3->length; | ||
561 | unsigned long time_elapsed = id3->elapsed; | ||
562 | int status = audio_status(); | ||
563 | data[3] = time_total >> 24; | ||
564 | data[4] = time_total >> 16; | ||
565 | data[5] = time_total >> 8; | ||
566 | data[6] = time_total; | ||
567 | data[7] = time_elapsed >> 24; | ||
568 | data[8] = time_elapsed >> 16; | ||
569 | data[9] = time_elapsed >> 8; | ||
570 | data[10] = time_elapsed; | ||
571 | if (status == AUDIO_STATUS_PLAY) | ||
572 | data[11] = 0x01; /* play */ | ||
573 | else if (status & AUDIO_STATUS_PAUSE) | ||
574 | data[11] = 0x02; /* pause */ | ||
575 | iap_send_pkt(data, sizeof(data)); | ||
576 | break; | ||
577 | } | ||
578 | /* Get current pos in playlist */ | ||
579 | case 0x001E: | ||
580 | { | ||
581 | unsigned char data[] = {0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00}; | ||
582 | long playlist_pos = playlist_next(0); | ||
583 | playlist_pos -= playlist_get_first_index(NULL); | ||
584 | if(playlist_pos < 0) | ||
585 | playlist_pos += playlist_amount(); | ||
586 | data[3] = playlist_pos >> 24; | ||
587 | data[4] = playlist_pos >> 16; | ||
588 | data[5] = playlist_pos >> 8; | ||
589 | data[6] = playlist_pos; | ||
590 | iap_send_pkt(data, sizeof(data)); | ||
591 | break; | ||
592 | } | ||
593 | /* Get title of a song number */ | ||
594 | case 0x0020: | ||
595 | /* Get artist of a song number */ | ||
596 | case 0x0022: | ||
597 | /* Get album of a song number */ | ||
598 | case 0x0024: | ||
599 | { | ||
600 | unsigned char data[70] = {0x04, 0x00, 0xFF}; | ||
601 | struct mp3entry id3; | ||
602 | int fd; | ||
603 | size_t len; | ||
604 | long tracknum = (signed long)serbuf[4] << 24 | | ||
605 | (signed long)serbuf[5] << 16 | | ||
606 | (signed long)serbuf[6] << 8 | serbuf[7]; | ||
607 | data[2] = serbuf[3] + 1; | ||
608 | memcpy(&id3, audio_current_track(), sizeof(id3)); | ||
609 | tracknum += playlist_get_first_index(NULL); | ||
610 | if(tracknum >= playlist_amount()) | ||
611 | tracknum -= playlist_amount(); | ||
612 | |||
613 | /* If the tracknumber is not the current one, | ||
614 | read id3 from disk */ | ||
615 | if(playlist_next(0) != tracknum) | ||
616 | { | ||
617 | struct playlist_track_info info; | ||
618 | playlist_get_track_info(NULL, tracknum, &info); | ||
619 | fd = open(info.filename, O_RDONLY); | ||
620 | memset(&id3, 0, sizeof(struct mp3entry)); | ||
621 | get_metadata(&id3, fd, info.filename); | ||
622 | close(fd); | ||
623 | } | ||
624 | |||
625 | /* Return the requested track data */ | ||
626 | switch(serbuf[3]) | ||
627 | { | ||
628 | case 0x20: | ||
629 | len = strlcpy((char *)&data[3], id3.title, 64); | ||
630 | iap_send_pkt(data, 4+len); | ||
631 | break; | ||
632 | case 0x22: | ||
633 | len = strlcpy((char *)&data[3], id3.artist, 64); | ||
634 | iap_send_pkt(data, 4+len); | ||
635 | break; | ||
636 | case 0x24: | ||
637 | len = strlcpy((char *)&data[3], id3.album, 64); | ||
638 | iap_send_pkt(data, 4+len); | ||
639 | break; | ||
640 | } | ||
641 | break; | ||
642 | } | ||
643 | /* Set polling mode */ | ||
644 | case 0x0026: | ||
645 | { | 479 | { |
646 | iap_pollspeed = serbuf[4] ? 1 : 0; | 480 | iap_set_remote_volume(); |
647 | /*responsed with cmd ok packet */ | ||
648 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x26}; | ||
649 | iap_send_pkt(data, sizeof(data)); | ||
650 | break; | ||
651 | } | 481 | } |
652 | /* AiR playback control */ | 482 | break; |
653 | case 0x0029: | 483 | } |
654 | { | 484 | /* get volume from accessory */ |
655 | /* respond with cmd ok packet */ | 485 | case 0x0E: |
656 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x29}; | 486 | { |
657 | iap_send_pkt(data, sizeof(data)); | 487 | if (serbuf[3] == 0x04) |
658 | switch(serbuf[4]) | 488 | global_settings.volume = (-58)+((int)serbuf[5]+1)/4; |
659 | { | 489 | sound_set_volume(global_settings.volume); /* indent BUG? */ |
660 | case 0x01: /* play/pause */ | 490 | break; |
661 | iap_remotebtn = BUTTON_RC_PLAY; | 491 | } |
662 | iap_repeatbtn = 2; | 492 | } |
663 | iap_remotetick = false; | 493 | } |
664 | iap_changedctr = 1; | 494 | |
665 | break; | 495 | static void iap_handlepkt_mode4(void) |
666 | case 0x02: /* stop */ | 496 | { |
667 | iap_remotebtn = BUTTON_RC_PLAY|BUTTON_REPEAT; | 497 | unsigned int cmd = (serbuf[2] << 8) | serbuf[3]; |
668 | iap_repeatbtn = 2; | 498 | switch (cmd) |
669 | iap_remotetick = false; | 499 | { |
670 | iap_changedctr = 1; | 500 | /* Get data updated??? flag */ |
671 | break; | 501 | case 0x0009: |
672 | case 0x03: /* skip++ */ | 502 | { |
673 | iap_remotebtn = BUTTON_RC_RIGHT; | 503 | unsigned char data[] = {0x04, 0x00, 0x0A, 0x00}; |
674 | iap_repeatbtn = 2; | 504 | data[3] = iap_updateflag ? 0 : 1; |
675 | iap_remotetick = false; | 505 | iap_send_pkt(data, sizeof(data)); |
676 | break; | 506 | break; |
677 | case 0x04: /* skip-- */ | 507 | } |
678 | iap_remotebtn = BUTTON_RC_LEFT; | 508 | /* Set data updated??? flag */ |
679 | iap_repeatbtn = 2; | 509 | case 0x000B: |
680 | iap_remotetick = false; | 510 | { |
681 | break; | 511 | iap_updateflag = serbuf[4] ? 0 : 1; |
682 | case 0x05: /* ffwd */ | 512 | /* respond with cmd ok packet */ |
683 | iap_remotebtn = BUTTON_RC_RIGHT; | 513 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x0B}; |
684 | iap_remotetick = false; | 514 | iap_send_pkt(data, sizeof(data)); |
685 | if(iap_pollspeed) iap_pollspeed = 5; | 515 | break; |
686 | break; | 516 | } |
687 | case 0x06: /* frwd */ | 517 | /* Get iPod size? */ |
688 | iap_remotebtn = BUTTON_RC_LEFT; | 518 | case 0x0012: |
689 | iap_remotetick = false; | 519 | { |
690 | if(iap_pollspeed) iap_pollspeed = 5; | 520 | unsigned char data[] = {0x04, 0x00, 0x13, 0x01, 0x0B}; |
691 | break; | 521 | iap_send_pkt(data, sizeof(data)); |
692 | case 0x07: /* end ffwd/frwd */ | 522 | break; |
693 | iap_remotebtn = BUTTON_NONE; | 523 | } |
694 | iap_remotetick = false; | 524 | /* Get count of given types */ |
695 | if(iap_pollspeed) iap_pollspeed = 1; | 525 | case 0x0018: |
696 | break; | 526 | { |
697 | } | 527 | unsigned char data[] = {0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00}; |
698 | break; | 528 | unsigned long num = 0; |
529 | switch(serbuf[4]) /* type number */ | ||
530 | { | ||
531 | case 0x01: /* total number of playlists */ | ||
532 | num = 1; | ||
533 | break; | ||
534 | case 0x05: /* total number of songs */ | ||
535 | num = 1; | ||
536 | } | ||
537 | data[3] = num >> 24; | ||
538 | data[4] = num >> 16; | ||
539 | data[5] = num >> 8; | ||
540 | data[6] = num; | ||
541 | iap_send_pkt(data, sizeof(data)); | ||
542 | break; | ||
543 | } | ||
544 | /* Get time and status */ | ||
545 | case 0x001C: | ||
546 | { | ||
547 | unsigned char data[] = {0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, | ||
548 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
549 | struct mp3entry *id3 = audio_current_track(); | ||
550 | unsigned long time_total = id3->length; | ||
551 | unsigned long time_elapsed = id3->elapsed; | ||
552 | int status = audio_status(); | ||
553 | data[3] = time_total >> 24; | ||
554 | data[4] = time_total >> 16; | ||
555 | data[5] = time_total >> 8; | ||
556 | data[6] = time_total; | ||
557 | data[7] = time_elapsed >> 24; | ||
558 | data[8] = time_elapsed >> 16; | ||
559 | data[9] = time_elapsed >> 8; | ||
560 | data[10] = time_elapsed; | ||
561 | if (status == AUDIO_STATUS_PLAY) | ||
562 | data[11] = 0x01; /* play */ | ||
563 | else if (status & AUDIO_STATUS_PAUSE) | ||
564 | data[11] = 0x02; /* pause */ | ||
565 | iap_send_pkt(data, sizeof(data)); | ||
566 | break; | ||
567 | } | ||
568 | /* Get current pos in playlist */ | ||
569 | case 0x001E: | ||
570 | { | ||
571 | unsigned char data[] = {0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00}; | ||
572 | long playlist_pos = playlist_next(0); | ||
573 | playlist_pos -= playlist_get_first_index(NULL); | ||
574 | if(playlist_pos < 0) | ||
575 | playlist_pos += playlist_amount(); | ||
576 | data[3] = playlist_pos >> 24; | ||
577 | data[4] = playlist_pos >> 16; | ||
578 | data[5] = playlist_pos >> 8; | ||
579 | data[6] = playlist_pos; | ||
580 | iap_send_pkt(data, sizeof(data)); | ||
581 | break; | ||
582 | } | ||
583 | /* Get title of a song number */ | ||
584 | case 0x0020: | ||
585 | /* Get artist of a song number */ | ||
586 | case 0x0022: | ||
587 | /* Get album of a song number */ | ||
588 | case 0x0024: | ||
589 | { | ||
590 | unsigned char data[70] = {0x04, 0x00, 0xFF}; | ||
591 | struct mp3entry id3; | ||
592 | int fd; | ||
593 | size_t len; | ||
594 | long tracknum = (signed long)serbuf[4] << 24 | | ||
595 | (signed long)serbuf[5] << 16 | | ||
596 | (signed long)serbuf[6] << 8 | serbuf[7]; | ||
597 | data[2] = serbuf[3] + 1; | ||
598 | memcpy(&id3, audio_current_track(), sizeof(id3)); | ||
599 | tracknum += playlist_get_first_index(NULL); | ||
600 | if(tracknum >= playlist_amount()) | ||
601 | tracknum -= playlist_amount(); | ||
602 | |||
603 | /* If the tracknumber is not the current one, | ||
604 | read id3 from disk */ | ||
605 | if(playlist_next(0) != tracknum) | ||
606 | { | ||
607 | struct playlist_track_info info; | ||
608 | playlist_get_track_info(NULL, tracknum, &info); | ||
609 | fd = open(info.filename, O_RDONLY); | ||
610 | memset(&id3, 0, sizeof(struct mp3entry)); | ||
611 | get_metadata(&id3, fd, info.filename); | ||
612 | close(fd); | ||
613 | } | ||
614 | |||
615 | /* Return the requested track data */ | ||
616 | switch(serbuf[3]) | ||
617 | { | ||
618 | case 0x20: | ||
619 | len = strlcpy((char *)&data[3], id3.title, 64); | ||
620 | iap_send_pkt(data, 4+len); | ||
621 | break; | ||
622 | case 0x22: | ||
623 | len = strlcpy((char *)&data[3], id3.artist, 64); | ||
624 | iap_send_pkt(data, 4+len); | ||
625 | break; | ||
626 | case 0x24: | ||
627 | len = strlcpy((char *)&data[3], id3.album, 64); | ||
628 | iap_send_pkt(data, 4+len); | ||
629 | break; | ||
699 | } | 630 | } |
700 | /* Get shuffle mode */ | 631 | break; |
701 | case 0x002C: | 632 | } |
633 | /* Set polling mode */ | ||
634 | case 0x0026: | ||
635 | { | ||
636 | iap_pollspeed = serbuf[4] ? 1 : 0; | ||
637 | /*responsed with cmd ok packet */ | ||
638 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x26}; | ||
639 | iap_send_pkt(data, sizeof(data)); | ||
640 | break; | ||
641 | } | ||
642 | /* AiR playback control */ | ||
643 | case 0x0029: | ||
644 | { | ||
645 | /* respond with cmd ok packet */ | ||
646 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x29}; | ||
647 | iap_send_pkt(data, sizeof(data)); | ||
648 | switch(serbuf[4]) | ||
702 | { | 649 | { |
703 | unsigned char data[] = {0x04, 0x00, 0x2D, 0x00}; | 650 | case 0x01: /* play/pause */ |
704 | data[3] = global_settings.playlist_shuffle ? 1 : 0; | 651 | iap_remotebtn = BUTTON_RC_PLAY; |
705 | iap_send_pkt(data, sizeof(data)); | 652 | iap_repeatbtn = 2; |
706 | break; | 653 | iap_remotetick = false; |
654 | iap_changedctr = 1; | ||
655 | break; | ||
656 | case 0x02: /* stop */ | ||
657 | iap_remotebtn = BUTTON_RC_PLAY|BUTTON_REPEAT; | ||
658 | iap_repeatbtn = 2; | ||
659 | iap_remotetick = false; | ||
660 | iap_changedctr = 1; | ||
661 | break; | ||
662 | case 0x03: /* skip++ */ | ||
663 | iap_remotebtn = BUTTON_RC_RIGHT; | ||
664 | iap_repeatbtn = 2; | ||
665 | iap_remotetick = false; | ||
666 | break; | ||
667 | case 0x04: /* skip-- */ | ||
668 | iap_remotebtn = BUTTON_RC_LEFT; | ||
669 | iap_repeatbtn = 2; | ||
670 | iap_remotetick = false; | ||
671 | break; | ||
672 | case 0x05: /* ffwd */ | ||
673 | iap_remotebtn = BUTTON_RC_RIGHT; | ||
674 | iap_remotetick = false; | ||
675 | if(iap_pollspeed) iap_pollspeed = 5; | ||
676 | break; | ||
677 | case 0x06: /* frwd */ | ||
678 | iap_remotebtn = BUTTON_RC_LEFT; | ||
679 | iap_remotetick = false; | ||
680 | if(iap_pollspeed) iap_pollspeed = 5; | ||
681 | break; | ||
682 | case 0x07: /* end ffwd/frwd */ | ||
683 | iap_remotebtn = BUTTON_NONE; | ||
684 | iap_remotetick = false; | ||
685 | if(iap_pollspeed) iap_pollspeed = 1; | ||
686 | break; | ||
707 | } | 687 | } |
708 | /* Set shuffle mode */ | 688 | break; |
709 | case 0x002E: | 689 | } |
690 | /* Get shuffle mode */ | ||
691 | case 0x002C: | ||
692 | { | ||
693 | unsigned char data[] = {0x04, 0x00, 0x2D, 0x00}; | ||
694 | data[3] = global_settings.playlist_shuffle ? 1 : 0; | ||
695 | iap_send_pkt(data, sizeof(data)); | ||
696 | break; | ||
697 | } | ||
698 | /* Set shuffle mode */ | ||
699 | case 0x002E: | ||
700 | { | ||
701 | if(serbuf[4] && !global_settings.playlist_shuffle) | ||
710 | { | 702 | { |
711 | if(serbuf[4] && !global_settings.playlist_shuffle) | 703 | global_settings.playlist_shuffle = 1; |
712 | { | 704 | settings_save(); |
713 | global_settings.playlist_shuffle = 1; | 705 | if (audio_status() & AUDIO_STATUS_PLAY) |
714 | settings_save(); | 706 | playlist_randomise(NULL, current_tick, true); |
715 | if (audio_status() & AUDIO_STATUS_PLAY) | ||
716 | playlist_randomise(NULL, current_tick, true); | ||
717 | } | ||
718 | else if(!serbuf[4] && global_settings.playlist_shuffle) | ||
719 | { | ||
720 | global_settings.playlist_shuffle = 0; | ||
721 | settings_save(); | ||
722 | if (audio_status() & AUDIO_STATUS_PLAY) | ||
723 | playlist_sort(NULL, true); | ||
724 | } | ||
725 | |||
726 | |||
727 | /* respond with cmd ok packet */ | ||
728 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x2E}; | ||
729 | iap_send_pkt(data, sizeof(data)); | ||
730 | break; | ||
731 | } | 707 | } |
732 | /* Get repeat mode */ | 708 | else if(!serbuf[4] && global_settings.playlist_shuffle) |
733 | case 0x002F: | ||
734 | { | 709 | { |
735 | unsigned char data[] = {0x04, 0x00, 0x30, 0x00}; | 710 | global_settings.playlist_shuffle = 0; |
736 | if(global_settings.repeat_mode == REPEAT_OFF) | 711 | settings_save(); |
737 | data[3] = 0; | 712 | if (audio_status() & AUDIO_STATUS_PLAY) |
738 | else if(global_settings.repeat_mode == REPEAT_ONE) | 713 | playlist_sort(NULL, true); |
739 | data[3] = 1; | ||
740 | else | ||
741 | data[3] = 2; | ||
742 | iap_send_pkt(data, sizeof(data)); | ||
743 | break; | ||
744 | } | 714 | } |
745 | /* Set repeat mode */ | ||
746 | case 0x0031: | ||
747 | { | ||
748 | int oldmode = global_settings.repeat_mode; | ||
749 | if (serbuf[4] == 0) | ||
750 | global_settings.repeat_mode = REPEAT_OFF; | ||
751 | else if (serbuf[4] == 1) | ||
752 | global_settings.repeat_mode = REPEAT_ONE; | ||
753 | else if (serbuf[4] == 2) | ||
754 | global_settings.repeat_mode = REPEAT_ALL; | ||
755 | 715 | ||
756 | if (oldmode != global_settings.repeat_mode) | 716 | |
757 | { | 717 | /* respond with cmd ok packet */ |
758 | settings_save(); | 718 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x2E}; |
759 | if (audio_status() & AUDIO_STATUS_PLAY) | 719 | iap_send_pkt(data, sizeof(data)); |
760 | audio_flush_and_reload_tracks(); | 720 | break; |
761 | } | 721 | } |
722 | /* Get repeat mode */ | ||
723 | case 0x002F: | ||
724 | { | ||
725 | unsigned char data[] = {0x04, 0x00, 0x30, 0x00}; | ||
726 | if(global_settings.repeat_mode == REPEAT_OFF) | ||
727 | data[3] = 0; | ||
728 | else if(global_settings.repeat_mode == REPEAT_ONE) | ||
729 | data[3] = 1; | ||
730 | else | ||
731 | data[3] = 2; | ||
732 | iap_send_pkt(data, sizeof(data)); | ||
733 | break; | ||
734 | } | ||
735 | /* Set repeat mode */ | ||
736 | case 0x0031: | ||
737 | { | ||
738 | int oldmode = global_settings.repeat_mode; | ||
739 | if (serbuf[4] == 0) | ||
740 | global_settings.repeat_mode = REPEAT_OFF; | ||
741 | else if (serbuf[4] == 1) | ||
742 | global_settings.repeat_mode = REPEAT_ONE; | ||
743 | else if (serbuf[4] == 2) | ||
744 | global_settings.repeat_mode = REPEAT_ALL; | ||
762 | 745 | ||
763 | /* respond with cmd ok packet */ | 746 | if (oldmode != global_settings.repeat_mode) |
764 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x31}; | ||
765 | iap_send_pkt(data, sizeof(data)); | ||
766 | break; | ||
767 | } | ||
768 | /* Get Screen Size */ | ||
769 | case 0x0033: | ||
770 | { | 747 | { |
771 | unsigned char data[] = {0x04, 0x00, 0x34, | 748 | settings_save(); |
772 | LCD_WIDTH >> 8, LCD_WIDTH & 0xff, | 749 | if (audio_status() & AUDIO_STATUS_PLAY) |
773 | LCD_HEIGHT >> 8, LCD_HEIGHT & 0xff, | 750 | audio_flush_and_reload_tracks(); |
774 | 0x01}; | ||
775 | iap_send_pkt(data, sizeof(data)); | ||
776 | break; | ||
777 | } | ||
778 | /* Get number songs in current playlist */ | ||
779 | case 0x0035: | ||
780 | { | ||
781 | unsigned char data[] = {0x04, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00}; | ||
782 | unsigned long playlist_amt = playlist_amount(); | ||
783 | data[3] = playlist_amt >> 24; | ||
784 | data[4] = playlist_amt >> 16; | ||
785 | data[5] = playlist_amt >> 8; | ||
786 | data[6] = playlist_amt; | ||
787 | iap_send_pkt(data, sizeof(data)); | ||
788 | break; | ||
789 | } | ||
790 | /* Jump to track number in current playlist */ | ||
791 | case 0x0037: | ||
792 | { | ||
793 | int paused = (is_wps_fading() || (audio_status() & AUDIO_STATUS_PAUSE)); | ||
794 | long tracknum = (signed long)serbuf[4] << 24 | | ||
795 | (signed long)serbuf[5] << 16 | | ||
796 | (signed long)serbuf[6] << 8 | serbuf[7]; | ||
797 | audio_pause(); | ||
798 | audio_skip(tracknum - playlist_next(0)); | ||
799 | if (!paused) | ||
800 | audio_resume(); | ||
801 | |||
802 | /* respond with cmd ok packet */ | ||
803 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x00}; | ||
804 | data[4] = serbuf[2]; | ||
805 | data[5] = serbuf[3]; | ||
806 | iap_send_pkt(data, sizeof(data)); | ||
807 | break; | ||
808 | } | ||
809 | default: | ||
810 | { | ||
811 | /* default response is with cmd ok packet */ | ||
812 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x00}; | ||
813 | data[4] = serbuf[2]; | ||
814 | data[5] = serbuf[3]; | ||
815 | iap_send_pkt(data, sizeof(data)); | ||
816 | break; | ||
817 | } | 751 | } |
752 | |||
753 | /* respond with cmd ok packet */ | ||
754 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x31}; | ||
755 | iap_send_pkt(data, sizeof(data)); | ||
756 | break; | ||
757 | } | ||
758 | /* Get Screen Size */ | ||
759 | case 0x0033: | ||
760 | { | ||
761 | unsigned char data[] = {0x04, 0x00, 0x34, | ||
762 | LCD_WIDTH >> 8, LCD_WIDTH & 0xff, | ||
763 | LCD_HEIGHT >> 8, LCD_HEIGHT & 0xff, | ||
764 | 0x01}; | ||
765 | iap_send_pkt(data, sizeof(data)); | ||
766 | break; | ||
767 | } | ||
768 | /* Get number songs in current playlist */ | ||
769 | case 0x0035: | ||
770 | { | ||
771 | unsigned char data[] = {0x04, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00}; | ||
772 | unsigned long playlist_amt = playlist_amount(); | ||
773 | data[3] = playlist_amt >> 24; | ||
774 | data[4] = playlist_amt >> 16; | ||
775 | data[5] = playlist_amt >> 8; | ||
776 | data[6] = playlist_amt; | ||
777 | iap_send_pkt(data, sizeof(data)); | ||
778 | break; | ||
779 | } | ||
780 | /* Jump to track number in current playlist */ | ||
781 | case 0x0037: | ||
782 | { | ||
783 | int paused = (is_wps_fading() || (audio_status() & AUDIO_STATUS_PAUSE)); | ||
784 | long tracknum = (signed long)serbuf[4] << 24 | | ||
785 | (signed long)serbuf[5] << 16 | | ||
786 | (signed long)serbuf[6] << 8 | serbuf[7]; | ||
787 | audio_pause(); | ||
788 | audio_skip(tracknum - playlist_next(0)); | ||
789 | if (!paused) | ||
790 | audio_resume(); | ||
791 | |||
792 | /* respond with cmd ok packet */ | ||
793 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x00}; | ||
794 | data[4] = serbuf[2]; | ||
795 | data[5] = serbuf[3]; | ||
796 | iap_send_pkt(data, sizeof(data)); | ||
797 | break; | ||
798 | } | ||
799 | default: | ||
800 | { | ||
801 | /* default response is with cmd ok packet */ | ||
802 | unsigned char data[] = {0x04, 0x00, 0x01, 0x00, 0x00, 0x00}; | ||
803 | data[4] = serbuf[2]; | ||
804 | data[5] = serbuf[3]; | ||
805 | iap_send_pkt(data, sizeof(data)); | ||
806 | break; | ||
818 | } | 807 | } |
819 | } | 808 | } |
820 | /* Handle Mode 7 */ | 809 | } |
821 | else if (serbuf[1] == 0x07) | 810 | |
811 | static void iap_handlepkt_mode7(void) | ||
812 | { | ||
813 | unsigned int cmd = serbuf[2]; | ||
814 | switch (cmd) | ||
822 | { | 815 | { |
823 | switch(serbuf[2]) | 816 | /* tuner capabilities */ |
817 | case 0x02: | ||
824 | { | 818 | { |
825 | /* tuner capabilities */ | 819 | /* do nothing */ |
826 | case 0x02: | 820 | |
827 | { | 821 | unsigned char data[] = {0x00, 0x27, 0x00}; |
828 | /* do nothing */ | 822 | iap_send_pkt(data, sizeof(data)); |
829 | 823 | break; | |
830 | unsigned char data[] = {0x00, 0x27, 0x00}; | 824 | } |
831 | iap_send_pkt(data, sizeof(data)); | 825 | /* actual tuner frequency */ |
832 | break; | 826 | case 0x0A: |
833 | } | 827 | /* fall through */ |
834 | /* actual tuner frequency */ | 828 | /* tuner frequency from scan */ |
835 | case 0x0A: | 829 | case 0x13: |
836 | /* fall through */ | 830 | { |
837 | /* tuner frequency from scan */ | 831 | rmt_tuner_freq(serbuf); |
838 | case 0x13: | 832 | break; |
839 | { | 833 | } |
840 | rmt_tuner_freq(serbuf); | 834 | /* RDS station name 0x21 1E 00 + ASCII text*/ |
841 | break; | 835 | case 0x21: |
842 | } | 836 | { |
843 | /* RDS station name 0x21 1E 00 + ASCII text*/ | 837 | rmt_tuner_rds_data(serbuf); |
844 | case 0x21: | 838 | break; |
845 | { | ||
846 | rmt_tuner_rds_data(serbuf); | ||
847 | break; | ||
848 | } | ||
849 | } | 839 | } |
850 | } | 840 | } |
841 | } | ||
842 | |||
843 | void iap_handlepkt(void) | ||
844 | { | ||
845 | |||
846 | if(!iap_setupflag) return; | ||
847 | if(serbuf[0] == 0) return; | ||
848 | |||
849 | /* if we are waiting for a remote button to go out, | ||
850 | delay the handling of the new packet */ | ||
851 | if(!iap_remotetick) | ||
852 | { | ||
853 | queue_post(&button_queue, SYS_IAP_HANDLEPKT, 0); | ||
854 | return; | ||
855 | } | ||
856 | |||
857 | unsigned char mode = serbuf[1]; | ||
858 | switch (mode) { | ||
859 | case 0: iap_handlepkt_mode0(); break; | ||
860 | case 2: iap_handlepkt_mode2(); break; | ||
861 | case 3: iap_handlepkt_mode3(); break; | ||
862 | case 4: iap_handlepkt_mode4(); break; | ||
863 | case 7: iap_handlepkt_mode7(); break; | ||
864 | } | ||
865 | |||
851 | serbuf[0] = 0; | 866 | serbuf[0] = 0; |
852 | } | 867 | } |
853 | 868 | ||