Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem parsing TR135 path #5

Open
GoogleCodeExporter opened this issue Aug 25, 2015 · 1 comment
Open

Problem parsing TR135 path #5

GoogleCodeExporter opened this issue Aug 25, 2015 · 1 comment

Comments

@GoogleCodeExporter
Copy link

First of all: thank you for the good project. It's seems promising even if it 
lacks for now many features as SSL, download and upload.

I'm trying to use the data model on TR135 paths and I've run into a parse error.
I was trying to access the following parameter:

Device.Services.STBService.1.Components.FrontEndNumberOfEntries

Where
Device: object
Services: object
STBService: multi-object
Components: object
FrontEndNumberOfEntries: a unsigned integer

The function evcpe_repo_locate() cannot parse this path and exit with an error: 
"failed to convert to integer: Components"

I've make a little path that resolved my problem and I hope this is correct. 
The data model design seems to be good but it lack documentation (doxygen as an 
example):

int evcpe_repo_locate(struct evcpe_repo *repo, const char *name,
        struct evcpe_obj **obj, struct evcpe_attr **attr, unsigned int *index)
{
    int rc;
    const char *start, *end;
    int inst_read = 0; /* Set when an instance is read */

    *obj = repo->root;
    *attr = NULL;
    start = end = name;
    while(*end != '\0') {
        if (*end != '.') {
            end ++;
            continue;
        }
        if (end == start) {
            // expression neglecting root object (compatible to all
            // TR-069 enabled device
            *attr = RB_ROOT(&repo->root->attrs);
            *obj = (*attr)->value.object;
        } else if ((*attr) && (*attr)->schema->type == EVCPE_TYPE_MULTIPLE) {
            if (!inst_read) {
                if (!(*index = atoi(start)) && errno) {
                    evcpe_error(__func__, "failed to convert to integer: "
                            "%.*s", end - start, start);
                    rc = EINVAL;
                    goto finally;
                }
                if (*index <= 0) {
                    evcpe_error(__func__, "invalid instance number: "
                            "%d", *index);
                    rc = EINVAL;
                    goto finally;
                }
                if ((rc = evcpe_attr_idx_obj(*attr, (*index) - 1, obj))) {
                    evcpe_error(__func__, "indexed object doesn't exist: "
                            "[%d]", (*index) - 1);
                    goto finally;
                }
            } else {
                /* Read the next object */
                if ((rc = evcpe_obj_get(*obj, start, end - start, attr))) {
                    evcpe_error(__func__, "failed to get attribute: %.*s",
                            end - start, start);
                    goto finally;
                }
                if ((rc = evcpe_attr_get_obj(*attr, obj))) {
                    evcpe_error(__func__, "failed to get object: %.*s",
                            end - start, start);
                    goto finally;
                }
            }
        } else if ((rc = evcpe_obj_get(*obj, start, end - start, attr))) {
            evcpe_error(__func__, "failed to get attribute: %.*s",
                    end - start, start);
            goto finally;
//      } else if (!(*attr)) {
//          evcpe_error(__func__, "attribute doesn't exist: %.*s",
//                  end - start, start);
//          rc = EINVAL;
//          goto finally;
        } else if ((*attr)->schema->type == EVCPE_TYPE_MULTIPLE) {
            inst_read = 0;
        } else if ((*attr)->schema->type == EVCPE_TYPE_OBJECT) {
            *obj = (*attr)->value.object;
        } else {
            evcpe_error(__func__, "not an object/multiple attribute: %s",
                    (*attr)->schema->name);
            rc = EVCPE_CPE_INVALID_PARAM_NAME;
            goto finally;
        }
        start = ++ end;
    }
    if (start != end) {
        if ((rc = evcpe_obj_get(*obj, start, end - start, attr))) {
            evcpe_error(__func__, "failed to get attribute: %.*s",
                    end - start, start);
            goto finally;
        } else if ((*attr)->schema->type == EVCPE_TYPE_OBJECT ||
                (*attr)->schema->type == EVCPE_TYPE_MULTIPLE) {
            evcpe_error(__func__, "not a simple attribute: %.*s",
                    end - start, start);
            rc = EVCPE_CPE_INVALID_PARAM_NAME;
            goto finally;
        }
    }
    rc = 0;

finally:
    return rc;
}

I've added a boolean state to bypass reading the instance number {i} when 
applicable.

Again many thanks for the program and your effort.

Original issue reported on code.google.com by [email protected] on 15 Aug 2011 at 7:07

@GoogleCodeExporter
Copy link
Author

Well, even the above patch does not work in all cases. I've tried the following 
path and it fails miserably: 
"Device.Services.STBService.{i}.Components.FrontEnd.{i}.DVBT.ServiceListDatabase
.LogicalChannel.{i}.LogicalChannelNumber".
It will fail also for a more complex path 
"Device.Services.STBService.{i}.Components.FrontEnd.{i}.DVBT.ServiceListDatabase
.LogicalChannel.{i}.Service.{i}.Name"

I've made a new more generic pâtch that fit my needs. however, I'm still 
looking for a more generic way to deal with instances searching.

[CODE]
int evcpe_repo_locate(struct evcpe_repo *repo, const char *name,
        struct evcpe_obj **obj, struct evcpe_attr **attr, unsigned int *index)
{
    int rc;
    const char *start, *end;

    *obj = repo->root;
    *attr = NULL;
    start = end = name;

    while(*end != '\0') {
        if (*end != '.') {
            end ++;
            continue;
        }
        if (end == start) {
            // expression neglecting root object (compatible to all
            // TR-069 enabled device
            *attr = RB_ROOT(&repo->root->attrs);
            *obj = (*attr)->value.object;
        } else if ((*attr) && (*attr)->schema->type == EVCPE_TYPE_MULTIPLE) {
            if (!(*index = atoi(start)) && errno) {
                evcpe_error(__func__, "failed to convert to integer: "
                        "%.*s", end - start, start);
                rc = ENOMEM;
                goto finally;
            }
            if (*index <= 0) {
                evcpe_error(__func__, "invalid instance number: "
                        "%d", *index);
                rc = ENOMEM;
                goto finally;
            }
            if ((rc = evcpe_attr_idx_obj(*attr, (*index) - 1, obj))) {
                evcpe_error(__func__, "indexed object doesn't exist: "
                        "[%d]", (*index) - 1);
                goto finally;
            }

      /* Skip the {i} instance reference */
      end = start;
      while ((*end != '\0') && (*end != '.')) {
        ++end;
      }
      /* Look for the next child attribute */
      start = ++end;
      while ((*end != '\0') && (*end != '.')) {
        ++end;
      }
      if ((end - start) > 1) {
        if (!(*attr = evcpe_obj_find(*obj, start, (unsigned int)(end - start)))) {
          evcpe_error(__func__, "child attribute does not exists: %.*s",
               (end - start), start);
          goto finally;
        }
        if (EVCPE_TYPE_OBJECT == (*attr)->schema->type) {
          if ((rc = evcpe_attr_get_obj(*attr, obj))) {
            evcpe_error(__func__, "failed to get object: %.*s",
                 (end - start), start);
            goto finally;
          }
        }
        else {
          *obj = NULL;
          *obj_index = 0;
        }
      }
      if ('\0' == *end) {
        /* The end of parameter's name has been reached */
        start = end; /* Simulate a stop condition */
        break;
      }         
        } else if ((rc = evcpe_obj_get(*obj, start, end - start, attr))) {
            evcpe_error(__func__, "failed to get attribute: %.*s",
                    end - start, start);
            goto finally;
//      } else if (!(*attr)) {
//          evcpe_error(__func__, "attribute doesn't exist: %.*s",
//                  end - start, start);
//          rc = EINVAL;
//          goto finally;
        } else if ((*attr)->schema->type == EVCPE_TYPE_MULTIPLE) {
        } else if ((*attr)->schema->type == EVCPE_TYPE_OBJECT) {
            *obj = (*attr)->value.object;
        } else {
            evcpe_error(__func__, "not an object/multiple attribute: %s",
                    (*attr)->schema->name);
            rc = EVCPE_CPE_INVALID_PARAM_NAME;
            goto finally;
        }
        start = ++ end;
    }
    if (start != end) {
        if ((rc = evcpe_obj_get(*obj, start, end - start, attr))) {
            evcpe_error(__func__, "failed to get attribute: %.*s",
                    end - start, start);
            goto finally;
        } else if ((*attr)->schema->type == EVCPE_TYPE_OBJECT ||
                (*attr)->schema->type == EVCPE_TYPE_MULTIPLE) {
            evcpe_error(__func__, "not a simple attribute: %.*s",
                    end - start, start);
            rc = EVCPE_CPE_INVALID_PARAM_NAME;
            goto finally;
        }
    }
    rc = 0;

finally:
    return rc;
}
[/CODE]



Original comment by [email protected] on 22 Sep 2011 at 8:17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant