Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/hidparser.c

    rb53d3b7 rc32688d  
    4747
    4848int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    49                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     49                             usb_hid_report_item_t *report_item);
    5050int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    51                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     51                             usb_hid_report_item_t *report_item);
    5252int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    53                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     53                             usb_hid_report_item_t *report_item);
    5454int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    55                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     55                             usb_hid_report_item_t *report_item);
    5656
    5757void usb_hid_descriptor_print_list(link_t *head);
     
    6363int usb_pow(int a, int b);
    6464
    65 
    6665int usb_pow(int a, int b)
    6766{
     
    8584{
    8685   if(parser == NULL) {
    87         return EINVAL;
     86        return -1;
    8887   }
    8988
     
    111110        int ret;
    112111        usb_hid_report_item_t *report_item=0;
    113         usb_hid_report_item_t *new_report_item;
    114         usb_hid_report_path_t *usage_path;
    115         usb_hid_report_path_t *tmp_usage_path;
     112        usb_hid_report_item_t *new_report_item;
    116113
    117114        size_t offset_input=0;
     
    120117       
    121118
    122         /* parser structure initialization*/
    123         if(usb_hid_parser_init(parser) != EOK) {
    124                 return EINVAL;
    125         }
    126        
    127 
    128         /*report item initialization*/
    129119        if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
    130120                return ENOMEM;
    131121        }
    132122        memset(report_item, 0, sizeof(usb_hid_report_item_t));
    133         list_initialize(&(report_item->link)); 
    134 
    135         /* usage path context initialization */
    136         if(!(usage_path=usb_hid_report_path())){
    137                 return ENOMEM;
    138         }
    139        
     123       
     124        link_initialize(&(report_item->link)); 
     125
    140126        while(i<size){ 
    141127                if(!USB_HID_ITEM_IS_LONG(data[i])){
    142128
    143129                        if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    144                                 return EINVAL; // TODO ERROR CODE
     130                                return -1; // TODO ERROR CODE
    145131                        }
    146132                       
     
    155141                       
    156142                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    157                                                        item_size,report_item, usage_path);
     143                                                 item_size,report_item);
    158144                        usb_log_debug2("ret: %u\n", ret);
    159145                        switch(ret){
    160146                                case USB_HID_NEW_REPORT_ITEM:
    161147                                        // store report item to report and create the new one
    162                                         usb_log_debug("\nNEW REPORT ITEM: %X",ret);
    163 
    164                                         // store current usage path
    165                                         report_item->usage_path = usage_path;
    166 
    167                                         // new current usage path
    168                                         tmp_usage_path = usb_hid_report_path();
    169                                        
    170                                         // copy old path to the new one
    171                                         usb_hid_report_path_clone(tmp_usage_path, usage_path);
    172 
    173                                         // swap
    174                                         usage_path = tmp_usage_path;
    175                                         tmp_usage_path = NULL;
    176 
     148                                        usb_log_debug("\nNEW REPORT ITEM: %X",tag);
    177149                                       
    178150                                        switch(tag) {
     
    212184                                        link_initialize(&(new_report_item->link));
    213185                                        report_item = new_report_item;
    214                                                                                
     186                                       
    215187                                        break;
    216188                                case USB_HID_REPORT_TAG_PUSH:
     
    312284 */
    313285int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    314                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     286                             usb_hid_report_item_t *report_item)
    315287{       
    316288        int ret;
     
    319291                case USB_HID_TAG_CLASS_MAIN:
    320292
    321                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
     293                        if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {
    322294                                return USB_HID_NEW_REPORT_ITEM;
    323295                        }
     
    329301
    330302                case USB_HID_TAG_CLASS_GLOBAL: 
    331                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
     303                        return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);
    332304                        break;
    333305
    334306                case USB_HID_TAG_CLASS_LOCAL:                   
    335                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
     307                        return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);
    336308                        break;
    337309                default:
     
    351323
    352324int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    353                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    354 {               
     325                             usb_hid_report_item_t *report_item)
     326{
    355327        switch(tag)
    356328        {
     
    363335                       
    364336                case USB_HID_REPORT_TAG_COLLECTION:
    365                         usb_hid_report_path_append_item(usage_path, 0, 0);
    366                                                
     337                        // TODO
    367338                        return USB_HID_NO_ACTION;
    368339                        break;
    369340                       
    370341                case USB_HID_REPORT_TAG_END_COLLECTION:
    371                         // TODO
    372                         // znici posledni uroven ve vsech usage paths
    373                         // otazka jestli nema nicit dve, respektive novou posledni vynulovat?
    374                         usb_hid_report_remove_last_item(usage_path);
     342                        /* should be ignored */
    375343                        return USB_HID_NO_ACTION;
    376344                        break;
     
    393361
    394362int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    395                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     363                             usb_hid_report_item_t *report_item)
    396364{
    397365        // TODO take care about the bit length of data
     
    399367        {
    400368                case USB_HID_REPORT_TAG_USAGE_PAGE:
    401                         // zmeni to jenom v poslednim poli aktualni usage path
    402                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL,
    403                                 usb_hid_report_tag_data_int32(data,item_size));
     369                        report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);
    404370                        break;
    405371                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     
    452418 */
    453419int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    454                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     420                             usb_hid_report_item_t *report_item)
    455421{
    456422        switch(tag)
    457423        {
    458424                case USB_HID_REPORT_TAG_USAGE:
    459                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,
    460                                 usb_hid_report_tag_data_int32(data,item_size));
     425                        report_item->usage = usb_hid_report_tag_data_int32(data,item_size);
    461426                        break;
    462427                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    526491{
    527492        usb_hid_report_item_t *report_item;
    528         usb_hid_report_usage_path_t *path_item;
    529         link_t *path;
    530493        link_t *item;
    531494       
     
    544507                usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    545508                usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
    546                 usb_log_debug("\tUSAGE PATH:\n");
    547 
    548                 path = report_item->usage_path->link.next;
    549                 while(path != &report_item->usage_path->link)   {
    550                         path_item = list_get_instance(path, usb_hid_report_usage_path_t, link);
    551                         usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage);
    552                         path = path->next;
    553                 }
    554                
    555                
    556 //              usb_log_debug("\tUSAGE: %X\n", report_item->usage);
    557 //              usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
     509                usb_log_debug("\tUSAGE: %X\n", report_item->usage);
     510                usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
    558511                usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    559512                usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
     
    577530void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    578531{
    579         if(parser == NULL) {
    580                 return;
    581         }
    582        
    583532        usb_log_debug("INPUT:\n");
    584533        usb_hid_descriptor_print_list(&parser->input);
     
    612561       
    613562            report_item = list_get_instance(next, usb_hid_report_item_t, link);
    614 
    615                 while(!list_empty(&report_item->usage_path->link)) {
    616                         usb_hid_report_remove_last_item(report_item->usage_path);
    617                 }
    618 
    619                
    620563            next = next->next;
    621564           
     
    657600int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    658601    const uint8_t *data, size_t size,
    659     usb_hid_report_path_t *path, int flags,
    660602    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    661603{
     
    673615        size_t j=0;
    674616
    675         if(parser == NULL) {
    676                 return EINVAL;
    677         }
    678 
    679        
    680617        // get the size of result keycodes array
    681         key_count = usb_hid_report_input_length(parser, path, flags);
     618        usb_hid_report_path_t path;
     619        path.usage_page = BAD_HACK_USAGE_PAGE;
     620        key_count = usb_hid_report_input_length(parser, &path);
    682621
    683622        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
     
    690629
    691630                item = list_get_instance(list_item, usb_hid_report_item_t, link);
    692                 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 
    693                    (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
     631                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
     632                   (item->usage_page == path.usage_page)) {
    694633                        for(j=0; j<(size_t)(item->count); j++) {
    695634                                if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
     
    701640                                        // bitmapa
    702641                                        if((item_value = usb_hid_translate_data(item, data, j)) != 0) {
    703                                                 keys[i++] = (item->count - 1 - j) + item->usage_minimum;
     642                                                keys[i++] = j + item->usage_minimum;
    704643                                        }
    705644                                        else {
     
    797736
    798737int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    799         usb_hid_report_path_t *path, int flags)
    800 {       
     738        const usb_hid_report_path_t *path)
     739{
    801740        int ret = 0;
    802741        link_t *item;
    803742        usb_hid_report_item_t *report_item;
    804743
    805         if(parser == NULL) {
    806                 return EINVAL;
    807         }
    808        
    809744        item = (&parser->input)->next;
    810745        while(&parser->input != item) {
    811746                report_item = list_get_instance(item, usb_hid_report_item_t, link);
    812747                if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    813                    (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
     748                   (report_item->usage_page == path->usage_page)) {
    814749                        ret += report_item->count;
    815750                }
     
    822757
    823758
    824 /**
    825  *
    826  */
    827 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,
    828                                     int32_t usage_page, int32_t usage)
    829 {       
    830         usb_hid_report_usage_path_t *item;
    831 
    832         if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {
    833                 return ENOMEM;
    834         }
    835         list_initialize(&item->link);
    836 
    837         item->usage = usage;
    838         item->usage_page = usage_page;
    839        
    840         list_append (&usage_path->link, &item->link);
    841         usage_path->depth++;
    842         return EOK;
    843 }
    844 
    845 /**
    846  *
    847  */
    848 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
    849 {
    850         usb_hid_report_usage_path_t *item;
    851        
    852         if(!list_empty(&usage_path->link)){
    853                 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);             
    854                 list_remove(usage_path->link.prev);
    855                 usage_path->depth--;
    856                 free(item);
    857         }
    858 }
    859 
    860 /**
    861  *
    862  */
    863 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
    864 {
    865         usb_hid_report_usage_path_t *item;
    866        
    867         if(!list_empty(&usage_path->link)){     
    868                 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
    869                 memset(item, 0, sizeof(usb_hid_report_usage_path_t));
    870         }
    871 }
    872 
    873 /**
    874  *
    875  */
    876 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data)
    877 {
    878         usb_hid_report_usage_path_t *item;
    879        
    880         if(!list_empty(&usage_path->link)){     
    881                 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
    882 
    883                 switch(tag) {
    884                         case USB_HID_TAG_CLASS_GLOBAL:
    885                                 item->usage_page = data;
    886                                 break;
    887                         case USB_HID_TAG_CLASS_LOCAL:
    888                                 item->usage = data;
    889                                 break;
    890                 }
    891         }
    892        
    893 }
    894 
    895 /**
    896  *
    897  */
    898 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
    899                                       usb_hid_report_path_t *path,
    900                                       int flags)
    901 {
    902         usb_hid_report_usage_path_t *report_item;
    903         usb_hid_report_usage_path_t *path_item;
    904 
    905         link_t *report_link;
    906         link_t *path_link;
    907 
    908         int only_page;
    909 
    910         if(path->depth == 0){
    911                 return EOK;
    912         }
    913 
    914 
    915         if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
    916                 flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;
    917         }
    918        
    919         switch(flags){
    920                 /* path must be completly identical */
    921                 case USB_HID_PATH_COMPARE_STRICT:
    922                                 if(report_path->depth != path->depth){
    923                                         return 1;
    924                                 }
    925 
    926                                 report_link = report_path->link.next;
    927                                 path_link = path->link.next;
    928                        
    929                                 while((report_link != &report_path->link) && (path_link != &path->link)) {
    930                                         report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
    931                                         path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
    932 
    933                                         if((report_item->usage_page != path_item->usage_page) ||
    934                                            ((only_page == 0) && (report_item->usage != path_item->usage))) {
    935                                                    return 1;
    936                                         } else {
    937                                                 report_link = report_link->next;
    938                                                 path_link = path_link->next;                   
    939                                         }
    940                        
    941                                 }
    942 
    943                                 if((report_link == &report_path->link) && (path_link == &path->link)) {
    944                                         return EOK;
    945                                 }
    946                                 else {
    947                                         return 1;
    948                                 }                                               
    949                         break;
    950 
    951                 /* given path must be the end of the report one*/
    952                 case USB_HID_PATH_COMPARE_END:
    953                                 report_link = report_path->link.prev;
    954                                 path_link = path->link.prev;
    955 
    956                                 if(list_empty(&path->link)){
    957                                         return EOK;
    958                                 }
    959                        
    960                                 while((report_link != &report_path->link) && (path_link != &path->link)) {
    961                                         report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
    962                                         path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
    963 
    964                                         if((report_item->usage_page != path_item->usage_page) ||
    965                                            ((only_page == 0) && (report_item->usage != path_item->usage))) {
    966                                                    return 1;
    967                                         } else {
    968                                                 report_link = report_link->prev;
    969                                                 path_link = path_link->prev;                   
    970                                         }
    971                        
    972                                 }
    973 
    974                                 if(path_link == &path->link) {
    975                                         return EOK;
    976                                 }
    977                                 else {
    978                                         return 1;
    979                                 }                                               
    980                        
    981                         break;
    982 
    983                 default:
    984                         return EINVAL;
    985         }
    986        
    987        
    988        
    989        
    990 }
    991 
    992 /**
    993  *
    994  */
    995 usb_hid_report_path_t *usb_hid_report_path(void)
    996 {
    997         usb_hid_report_path_t *path;
    998         path = malloc(sizeof(usb_hid_report_path_t));
    999         if(!path){
    1000                 return NULL;
    1001         }
    1002         else {
    1003                 path->depth = 0;
    1004                 list_initialize(&path->link);
    1005                 return path;
    1006         }
    1007 }
    1008 
    1009 /**
    1010  *
    1011  */
    1012 void usb_hid_report_path_free(usb_hid_report_path_t *path)
    1013 {
    1014         while(!list_empty(&path->link)){
    1015                 usb_hid_report_remove_last_item(path);
    1016         }
    1017 }
    1018 
    1019 
    1020 /**
    1021  *
    1022  */
    1023 int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path)
    1024 {
    1025         usb_hid_report_usage_path_t *path_item;
    1026         link_t *path_link;
    1027 
    1028        
    1029         if(list_empty(&usage_path->link)){
    1030                 return EOK;
    1031         }
    1032 
    1033         path_link = usage_path->link.next;
    1034         while(path_link != &usage_path->link) {
    1035                 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
    1036                 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);
    1037 
    1038                 path_link = path_link->next;
    1039         }
    1040 
    1041         return EOK;
    1042 }
    1043 
    1044759
    1045760/**
Note: See TracChangeset for help on using the changeset viewer.