diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2011-04-27 06:24:28 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2011-04-27 06:24:28 +0000 |
commit | 1a68986bc5d13db4508797700dff99638dccc88c (patch) | |
tree | da6dff1c17a319c3aeae35112b9cbf2a80476616 /apps/iap.c | |
parent | 82e97363f1f7b1f0e534849925b7145f28deed8b (diff) | |
download | rockbox-1a68986bc5d13db4508797700dff99638dccc88c.tar.gz rockbox-1a68986bc5d13db4508797700dff99638dccc88c.zip |
FS#12079 - Support for new commands in iap.c, by Ophir Lojkine
This allows access to the playlists from an ipod dock.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29788 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/iap.c')
-rw-r--r-- | apps/iap.c | 117 |
1 files changed, 115 insertions, 2 deletions
diff --git a/apps/iap.c b/apps/iap.c index 2941326ad0..fa2c7d6beb 100644 --- a/apps/iap.c +++ b/apps/iap.c | |||
@@ -43,6 +43,10 @@ | |||
43 | #include "tuner.h" | 43 | #include "tuner.h" |
44 | #include "ipod_remote_tuner.h" | 44 | #include "ipod_remote_tuner.h" |
45 | 45 | ||
46 | #define MAX_NAME_LENGTH 20 | ||
47 | #include "filetree.h" | ||
48 | #include "dir.h" | ||
49 | |||
46 | static volatile int iap_pollspeed = 0; | 50 | static volatile int iap_pollspeed = 0; |
47 | static volatile bool iap_remotetick = true; | 51 | static volatile bool iap_remotetick = true; |
48 | static bool iap_setupflag = false, iap_updateflag = false; | 52 | static bool iap_setupflag = false, iap_updateflag = false; |
@@ -58,6 +62,8 @@ static int serbuf_i = 0; | |||
58 | static unsigned char response[TX_BUFLEN]; | 62 | static unsigned char response[TX_BUFLEN]; |
59 | static int responselen; | 63 | static int responselen; |
60 | 64 | ||
65 | static char cur_dbrecord[5] = {0}; | ||
66 | |||
61 | static void iap_task(void) | 67 | static void iap_task(void) |
62 | { | 68 | { |
63 | static int count = 0; | 69 | static int count = 0; |
@@ -527,6 +533,33 @@ static void cmd_ok_mode4(unsigned int cmd) | |||
527 | iap_send_pkt(data, sizeof(data)); | 533 | iap_send_pkt(data, sizeof(data)); |
528 | } | 534 | } |
529 | 535 | ||
536 | static void get_playlist_name(unsigned char *dest, | ||
537 | unsigned long item_offset, | ||
538 | size_t max_length) | ||
539 | { | ||
540 | if (item_offset == 0) return; | ||
541 | DIR* dp; | ||
542 | struct dirent* playlist_file = NULL; | ||
543 | |||
544 | dp = opendir(global_settings.playlist_catalog_dir); | ||
545 | |||
546 | char *extension; | ||
547 | unsigned long nbr = 0; | ||
548 | while ((nbr < item_offset) && ((playlist_file = readdir(dp)) != NULL)) | ||
549 | { | ||
550 | /*Increment only if there is a playlist extension*/ | ||
551 | if ((extension=strrchr(playlist_file->d_name, '.')) != NULL){ | ||
552 | if ((strcmp(extension, ".m3u") == 0 || | ||
553 | strcmp(extension, ".m3u8") == 0)) | ||
554 | nbr++; | ||
555 | } | ||
556 | } | ||
557 | if (playlist_file != NULL) { | ||
558 | strlcpy(dest, playlist_file->d_name, max_length); | ||
559 | } | ||
560 | closedir(dp); | ||
561 | } | ||
562 | |||
530 | static void iap_handlepkt_mode4(void) | 563 | static void iap_handlepkt_mode4(void) |
531 | { | 564 | { |
532 | unsigned int cmd = (serbuf[2] << 8) | serbuf[3]; | 565 | unsigned int cmd = (serbuf[2] << 8) | serbuf[3]; |
@@ -559,20 +592,48 @@ static void iap_handlepkt_mode4(void) | |||
559 | iap_send_pkt(data, sizeof(data)); | 592 | iap_send_pkt(data, sizeof(data)); |
560 | break; | 593 | break; |
561 | } | 594 | } |
562 | 595 | ||
596 | /* SelectDBRecord */ | ||
597 | case 0x0017: | ||
598 | { | ||
599 | memcpy(cur_dbrecord, serbuf + 4, 5); | ||
600 | cmd_ok_mode4(cmd); | ||
601 | break; | ||
602 | } | ||
603 | |||
563 | /* GetNumberCategorizedDBRecords */ | 604 | /* GetNumberCategorizedDBRecords */ |
564 | case 0x0018: | 605 | case 0x0018: |
565 | { | 606 | { |
566 | /* ReturnNumberCategorizedDBRecords */ | 607 | /* ReturnNumberCategorizedDBRecords */ |
567 | unsigned char data[] = {0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00}; | 608 | unsigned char data[] = {0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00}; |
568 | unsigned long num = 0; | 609 | unsigned long num = 0; |
610 | |||
611 | DIR* dp; | ||
612 | unsigned long nbr_total_playlists = 0; | ||
613 | struct dirent* playlist_file = NULL; | ||
614 | char *extension; | ||
615 | |||
569 | switch(serbuf[4]) /* type number */ | 616 | switch(serbuf[4]) /* type number */ |
570 | { | 617 | { |
571 | case 0x01: /* total number of playlists */ | 618 | case 0x01: /* total number of playlists */ |
572 | num = 1; | 619 | dp = opendir(global_settings.playlist_catalog_dir); |
620 | while ((playlist_file = readdir(dp)) != NULL) | ||
621 | { | ||
622 | /*Increment only if there is a playlist extension*/ | ||
623 | if ((extension=strrchr(playlist_file->d_name, '.')) | ||
624 | != NULL) { | ||
625 | if ((strcmp(extension, ".m3u") == 0 || | ||
626 | strcmp(extension, ".m3u8") == 0)) | ||
627 | nbr_total_playlists++; | ||
628 | } | ||
629 | } | ||
630 | closedir(dp); | ||
631 | /*Add 1 for the main playlist*/ | ||
632 | num = nbr_total_playlists + 1; | ||
573 | break; | 633 | break; |
574 | case 0x05: /* total number of songs */ | 634 | case 0x05: /* total number of songs */ |
575 | num = 1; | 635 | num = 1; |
636 | break; | ||
576 | } | 637 | } |
577 | data[3] = num >> 24; | 638 | data[3] = num >> 24; |
578 | data[4] = num >> 16; | 639 | data[4] = num >> 16; |
@@ -582,6 +643,27 @@ static void iap_handlepkt_mode4(void) | |||
582 | break; | 643 | break; |
583 | } | 644 | } |
584 | 645 | ||
646 | /* RetrieveCategorizedDatabaseRecords */ | ||
647 | case 0x001A: | ||
648 | { | ||
649 | /* ReturnCategorizedDatabaseRecord */ | ||
650 | unsigned char data[7 + MAX_NAME_LENGTH] = | ||
651 | {0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, | ||
652 | 'R', 'O', 'C', 'K', 'B', 'O', 'X', '\0'}; | ||
653 | |||
654 | unsigned long item_offset = (serbuf[5] << 24) | (serbuf[6] << 16) | | ||
655 | (serbuf[7] << 8) | serbuf[8]; | ||
656 | |||
657 | get_playlist_name(data + 7, item_offset, MAX_NAME_LENGTH); | ||
658 | /*Remove file extension*/ | ||
659 | char *dot=NULL; | ||
660 | dot = (strrchr(data+7, '.')); | ||
661 | if (dot != NULL) | ||
662 | *dot = '\0'; | ||
663 | iap_send_pkt(data, sizeof(data)); | ||
664 | break; | ||
665 | } | ||
666 | |||
585 | /* GetPlayStatus */ | 667 | /* GetPlayStatus */ |
586 | case 0x001C: | 668 | case 0x001C: |
587 | { | 669 | { |
@@ -685,6 +767,37 @@ static void iap_handlepkt_mode4(void) | |||
685 | break; | 767 | break; |
686 | } | 768 | } |
687 | 769 | ||
770 | /* PlayCurrentSelection */ | ||
771 | case 0x0028: | ||
772 | { | ||
773 | switch (cur_dbrecord[0]) | ||
774 | { | ||
775 | case 0x01: | ||
776 | {/*Playlist*/ | ||
777 | unsigned long item_offset = (cur_dbrecord[1] << 24)| | ||
778 | (cur_dbrecord[2] << 16)| | ||
779 | (cur_dbrecord[3] << 8) | | ||
780 | cur_dbrecord[4]; | ||
781 | unsigned char selected_playlist | ||
782 | [sizeof(global_settings.playlist_catalog_dir) + 1 + MAX_NAME_LENGTH] = {0}; | ||
783 | |||
784 | strcpy(selected_playlist, | ||
785 | global_settings.playlist_catalog_dir); | ||
786 | int len = strlen(selected_playlist); | ||
787 | selected_playlist[len] = '/'; | ||
788 | get_playlist_name (selected_playlist + len + 1, | ||
789 | item_offset, | ||
790 | MAX_NAME_LENGTH); | ||
791 | ft_play_playlist(selected_playlist, | ||
792 | global_settings.playlist_catalog_dir, | ||
793 | strrchr(selected_playlist, '/') + 1); | ||
794 | break; | ||
795 | } | ||
796 | } | ||
797 | cmd_ok_mode4(cmd); | ||
798 | break; | ||
799 | } | ||
800 | |||
688 | /* PlayControl */ | 801 | /* PlayControl */ |
689 | case 0x0029: | 802 | case 0x0029: |
690 | { | 803 | { |