mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Merge uspd as bbfd with history
This commit is contained in:
parent
32511db9d9
commit
f24b03937d
109 changed files with 40278 additions and 0 deletions
19
bbfd/.gitignore
vendored
Normal file
19
bbfd/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
.*.swp
|
||||
.*.swo
|
||||
.built*
|
||||
.configured_*
|
||||
.dep_files
|
||||
.git_update
|
||||
.pkgdir/
|
||||
.prepared_*
|
||||
ipkg-arm_xscale/
|
||||
*.o
|
||||
*.so
|
||||
src/uspd
|
||||
uspd
|
||||
*.gcda
|
||||
*.gcno
|
||||
report/
|
||||
*.log
|
||||
*.xml
|
||||
docs/index.md
|
||||
71
bbfd/.gitlab-ci.yml
Normal file
71
bbfd/.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
include:
|
||||
- project: 'iopsys/gitlab-ci-pipeline'
|
||||
file: '/static-code-analysis.yml'
|
||||
|
||||
variables:
|
||||
COMMON_IMAGE: iopsys/code-analysis:0.26
|
||||
DEBUG: 'TRUE'
|
||||
SOURCE_FOLDER: "./src"
|
||||
RUN_CPPCHECK: "cppcheck --enable=all --error-exitcode=1 --inline-suppr --suppress=missingInclude --include=/usr/include/libubox/list.h -DUSPD_MAX_MSG_LEN=1048576"
|
||||
|
||||
stages:
|
||||
- static_code_analysis
|
||||
- test
|
||||
|
||||
run_unit_test:
|
||||
stage: test
|
||||
image: iopsys/code-analysis:latest
|
||||
allow_failure: false
|
||||
script:
|
||||
- "./gitlab-ci/install-dependencies.sh"
|
||||
- "./gitlab-ci/setup.sh"
|
||||
- "./gitlab-ci/unit-test.sh"
|
||||
artifacts:
|
||||
untracked: true
|
||||
when: always
|
||||
paths:
|
||||
- timestamp.log
|
||||
- unit-test-coverage.xml
|
||||
|
||||
run_functional_test:
|
||||
stage: test
|
||||
image: iopsys/code-analysis:latest
|
||||
allow_failure: false
|
||||
script:
|
||||
- "./gitlab-ci/install-dependencies.sh"
|
||||
- "./gitlab-ci/setup.sh"
|
||||
- "./gitlab-ci/functional-test.sh"
|
||||
|
||||
artifacts:
|
||||
untracked: true
|
||||
when: always
|
||||
reports:
|
||||
junit: ./report/*.xml
|
||||
paths:
|
||||
- funl-result.log
|
||||
- funl-test-coverage.xml
|
||||
- memory-report.xml
|
||||
- timestamp.log
|
||||
- report/
|
||||
|
||||
run_api_test:
|
||||
stage: test
|
||||
image: iopsys/code-analysis:latest
|
||||
allow_failure: false
|
||||
script:
|
||||
- "./gitlab-ci/install-dependencies.sh"
|
||||
- "./gitlab-ci/setup.sh"
|
||||
- "./gitlab-ci/functional-api-test.sh"
|
||||
|
||||
artifacts:
|
||||
untracked: true
|
||||
when: always
|
||||
reports:
|
||||
junit: ./report/*.xml
|
||||
paths:
|
||||
- timestamp.log
|
||||
- api-test-coverage.xml
|
||||
- memory-report.xml
|
||||
- api-result.log
|
||||
- report/
|
||||
|
||||
308
bbfd/LICENSE
Normal file
308
bbfd/LICENSE
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
uspd - USP Daemon exposing USP API over uBus
|
||||
Copyright (C) 2019 iopsys Software Solutions AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
25
bbfd/Makefile
Normal file
25
bbfd/Makefile
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
all:
|
||||
make -C src all
|
||||
|
||||
uspd:
|
||||
make -C src uspd
|
||||
|
||||
test:
|
||||
make -C src test
|
||||
|
||||
unit-test:
|
||||
make -C test/cmocka unit-test USPD_LIB_DIR=$(PWD)
|
||||
|
||||
func-test:
|
||||
make -C src func-test
|
||||
|
||||
clean:
|
||||
make -C src clean
|
||||
make -C test/cmocka clean
|
||||
rm -f uspd
|
||||
find -name '*.gcda' -exec rm {} -fv \;
|
||||
find -name '*.gcno' -exec rm {} -fv \;
|
||||
find -name '*.gcov' -exec rm {} -fv \;
|
||||
find -name '*.so' -exec rm {} -fv \;
|
||||
rm -f *.log *.xml
|
||||
rm -rf report
|
||||
100
bbfd/README.md
Normal file
100
bbfd/README.md
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# USP Daemon (uspd)
|
||||
|
||||
`uspd` is data-model daemon which exposes data-model objects over ubus as required
|
||||
by [TR-069/cwmp](https://cwmp-data-models.broadband-forum.org/) or [TR-369/USP](https://usp.technology/),
|
||||
`uspd` also understand [USP syntax](https://usp.technology/specification/architecture/) as defined in R-ARC.7 - R-ARC.12
|
||||
and provide details for data-model queries.
|
||||
|
||||
> Note 1: The command outputs shown in this readme are examples only, actual output may differ based on device and configuration.
|
||||
|
||||
> Note 2: Long command outputs are compressed for better readability
|
||||
|
||||
## Project Components
|
||||
|
||||
Project consists of following components:
|
||||
|
||||
- Application itself written in C programming language
|
||||
- Documentation in a Markdown format
|
||||
|
||||
## Build Instructions
|
||||
|
||||
`uspd` is written using C programming language and depends on a number of components found in `OpenWrt` for building and running.
|
||||
|
||||
## UCI Config
|
||||
|
||||
`uspd` requires a configuration file to provide more granular objects over `ubus`.
|
||||
Granularity is an optional feature of `uspd`, it can be skipped or set to level 0.
|
||||
The configuration file is an `uci` file `/etc/config/uspd`. Sample configuration file is provided below.
|
||||
|
||||
```bash
|
||||
config uspd 'usp'
|
||||
option granularitylevel '0'
|
||||
option debug 'true'
|
||||
option loglevel '2'
|
||||
option sock '/tmp/usp.sock'
|
||||
option transaction_timeout 60
|
||||
option subprocess_level '1'
|
||||
option refresh_time '5'
|
||||
```
|
||||
|
||||
In the above uci, loglevel can have below value:
|
||||
|
||||
|loglevel | Meaning |
|
||||
|---------| -----------------------------------------|
|
||||
| 0 | Disabled logging |
|
||||
| 1 | Only errors will be logged |
|
||||
| 2 | Only errors and warnings will be logged |
|
||||
| 3 | Log everything except debug |
|
||||
| 4 | Everything will be logged |
|
||||
|
||||
For more info on the `uspd` UCI configuration visit [uci documentation](./docs/api/uci/uspd.md) OR [raw uci schema](https://dev.iopsys.eu/iopsys/uspd/-/tree/module_docs/schemas/uci/uspd.json)
|
||||
|
||||
## Concepts and Workflow
|
||||
|
||||
`uspd` internally uses `libbbfdm` to get the data-model objects. On startup it parses the uci file to check if the granularity is set and then as per the granularity value it registers the required ubus namespaces.
|
||||
|
||||
When a ubus method is called it first checks the `path` parameter to identify if it has special USP syntax, if present it parses and determine the correct objects from `libbbfdm`, then proceeds with the `Get/Set/Operate/Add/Del` operation on the qualified objects.
|
||||
|
||||
So, `uspd` search for `[[+*]+` in path expression, if it matches then segments the path and get the schema from `libbbfdm` and store it in a link-list, then it proceeds with the next segment to filter out the unneeded schema paths. It keeps on doing so till all the expressions are solved and it finally left with qualified objects.
|
||||
Once all the expressions are solved, it starts getting the values for qualified objects and store it in a `stack` to print the output in pretty format.
|
||||
|
||||
For operate command, it solve the path expression and then call `bbf_operate` from `libbbfdm` to execute the operate command.
|
||||
|
||||
`uspd` uses `dm_entry_param_method` API from `libbbfdm` to get the device tree schema and it's values.
|
||||
|
||||
In short, it covers/supports the new syntax introduced in `TR-369` by using the existing data-model available with `libbbfdm`.
|
||||
|
||||
|
||||
## Important topics
|
||||
* [UBUS methods](./docs/guide/ubus_methods.md)
|
||||
* [UBUS Errors](./docs/guide/ubus_errors.md)
|
||||
* [UBUS examples](./docs/guide/ubus_example.md)
|
||||
* [Parallel UBUS call](./docs/guide/ubus_parallel_call.md)
|
||||
* [Third party datamodel integration](./docs/guide/data_model_integration.md)
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Build-Time Dependencies
|
||||
|
||||
To successfully build uspd, following libraries are needed:
|
||||
|
||||
| Dependency | Link | License |
|
||||
| ---------- | ------------------------------------------- | -------------- |
|
||||
| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 |
|
||||
| libubox | https://git.openwrt.org/project/libubox.git | BSD |
|
||||
| libubus | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
|
||||
| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT |
|
||||
| libbbfdm | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 |
|
||||
|
||||
|
||||
### Run-Time Dependencies
|
||||
|
||||
In order to run the `uspd`, following dependencies are needed to be running/available before `uspd`.
|
||||
|
||||
| Dependency | Link | License |
|
||||
| ---------- | ---------------------------------------- | -------- |
|
||||
| ubusd | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
|
||||
| libbbfdm | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 |
|
||||
|
||||
System daemon `ubusd` is used to expose the USP functionality over `ubus`.
|
||||
7
bbfd/docs/.pages
Normal file
7
bbfd/docs/.pages
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
title: "USP Daemon Documentation"
|
||||
|
||||
nav:
|
||||
- "api"
|
||||
- "guide"
|
||||
- "spec"
|
||||
- "..."
|
||||
6
bbfd/docs/api/.pages
Normal file
6
bbfd/docs/api/.pages
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
title: "USP Daemon API"
|
||||
|
||||
nav:
|
||||
- "ubus"
|
||||
- "uci"
|
||||
- "..."
|
||||
4
bbfd/docs/api/ubus/.pages
Normal file
4
bbfd/docs/api/ubus/.pages
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
title: "USP Daemon UBUS"
|
||||
|
||||
nav:
|
||||
- "..."
|
||||
3162
bbfd/docs/api/ubus/usp.md
Normal file
3162
bbfd/docs/api/ubus/usp.md
Normal file
File diff suppressed because it is too large
Load diff
4694
bbfd/docs/api/ubus/usp.raw.md
Normal file
4694
bbfd/docs/api/ubus/usp.raw.md
Normal file
File diff suppressed because it is too large
Load diff
4
bbfd/docs/api/uci/.pages
Normal file
4
bbfd/docs/api/uci/.pages
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
title: "USP Daemon UCI"
|
||||
|
||||
nav:
|
||||
- "..."
|
||||
216
bbfd/docs/api/uci/uspd.md
Normal file
216
bbfd/docs/api/uci/uspd.md
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
# UCI Config
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="font-weight: bold">uspd</div>
|
||||
<table style="width:100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">section</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">description</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">multi</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">options</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">uspd</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">USP daemon Settings</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">false</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<table style="width:100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">name</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">type</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">required</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">default</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: bold; font-size: 14px">description</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">granularitylevel</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">integer</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">0</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">Creates ubus objects along with object names, depth of object name depends
|
||||
on granularitylevel</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">debug</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">boolean</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">no</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd"></div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">Enabled debug logging</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">sock</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">string</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even"></div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">Path for ubus socket to register uspd services</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">transaction_timeout</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">integer</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">no</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">10</div>
|
||||
</td>
|
||||
<td class="td_row_odd">
|
||||
<div class="td_row_odd">Transaction timeout value in seconds</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">loglevel</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">integer</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">1</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">Internal loglevel for debugging {0: No Logs; 1: Errors only; 2: Errors
|
||||
and warnings; 3: Error, warning and info; 4: Everything}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">subprocess_level</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">integer</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">2</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">This parameter configures when subprocess can be used for get operation. Level here denotes the Datamodel object depth up-to which subprocess will be used to collect the get data. For example, if this is configured to 1, then only get for 'Device.' shall be called within the subprocess. If configured as level 2, then all the get with up-to depth 2 like 'Device.WiFi.', 'Device.IP.' shall be called in subprocess.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">bbf_caching_time</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">integer</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">0</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">Max caching time in seconds for ubus output used in datamodel parameters. If not configured, output shall be cleared end the end of call.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">dm_version</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">string</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even"></div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">Configures the datamodel version to use for datamodel parameters, if not configured show all defined datamodel</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">refresh_time</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">integer</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">no</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">5</div>
|
||||
</td>
|
||||
<td class="td_row_even">
|
||||
<div class="td_row_even">The time period in seconds after which uspd will refresh the datamodel instances in a periodic manner. If configured to '0' then instance updater will be disabled. If not configured at all then after every 5 seconds datamodel instances will be refreshed.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.eot
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.eot
Normal file
Binary file not shown.
5301
bbfd/docs/css/assets/fonts/Madera-Bold.svg
Normal file
5301
bbfd/docs/css/assets/fonts/Madera-Bold.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 330 KiB |
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.ttf
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.ttf
Normal file
Binary file not shown.
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.woff
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.woff
Normal file
Binary file not shown.
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.woff2
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Bold.woff2
Normal file
Binary file not shown.
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.eot
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.eot
Normal file
Binary file not shown.
5284
bbfd/docs/css/assets/fonts/Madera-Regular.svg
Normal file
5284
bbfd/docs/css/assets/fonts/Madera-Regular.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 329 KiB |
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.ttf
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.ttf
Normal file
Binary file not shown.
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.woff
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.woff
Normal file
Binary file not shown.
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.woff2
Normal file
BIN
bbfd/docs/css/assets/fonts/Madera-Regular.woff2
Normal file
Binary file not shown.
124
bbfd/docs/css/colors.css
Executable file
124
bbfd/docs/css/colors.css
Executable file
|
|
@ -0,0 +1,124 @@
|
|||
////
|
||||
/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
/// copy of this software and associated documentation files (the "Software"),
|
||||
/// to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
/// and/or sell copies of the Software, and to permit persons to whom the
|
||||
/// Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
/// DEALINGS
|
||||
////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Color variables
|
||||
:root {
|
||||
|
||||
// Default color shades
|
||||
--md-default-fg-color: hsla(0, 0%, 0%, 0.87);
|
||||
--md-default-fg-color--light: hsla(0, 0%, 0%, 0.54);
|
||||
--md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32);
|
||||
--md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07);
|
||||
--md-default-bg-color: hsla(0, 0%, 100%, 1);
|
||||
--md-default-bg-color--light: hsla(0, 0%, 100%, 0.7);
|
||||
--md-default-bg-color--lighter: hsla(0, 0%, 100%, 0.3);
|
||||
--md-default-bg-color--lightest: hsla(0, 0%, 100%, 0.12);
|
||||
|
||||
// Primary color shades
|
||||
--md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1);
|
||||
--md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1);
|
||||
--md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1);
|
||||
--md-primary-bg-color: hsla(0, 0%, 100%, 1);
|
||||
--md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7);
|
||||
|
||||
// Accent color shades
|
||||
--md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1);
|
||||
--md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1);
|
||||
--md-accent-bg-color: hsla(0, 0%, 100%, 1);
|
||||
--md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7);
|
||||
|
||||
// Light theme (default)
|
||||
> * {
|
||||
|
||||
// Code color shades
|
||||
--md-code-fg-color: hsla(200, 18%, 26%, 1);
|
||||
--md-code-bg-color: hsla(0, 0%, 96%, 1);
|
||||
|
||||
// Code highlighting color shades
|
||||
--md-code-hl-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5);
|
||||
--md-code-hl-number-color: hsla(0, 67%, 50%, 1);
|
||||
--md-code-hl-special-color: hsla(340, 83%, 47%, 1);
|
||||
--md-code-hl-function-color: hsla(291, 45%, 50%, 1);
|
||||
--md-code-hl-constant-color: hsla(250, 63%, 60%, 1);
|
||||
--md-code-hl-keyword-color: hsla(219, 54%, 51%, 1);
|
||||
--md-code-hl-string-color: hsla(150, 63%, 30%, 1);
|
||||
--md-code-hl-name-color: var(--md-code-fg-color);
|
||||
--md-code-hl-operator-color: var(--md-default-fg-color--light);
|
||||
--md-code-hl-punctuation-color: var(--md-default-fg-color--light);
|
||||
--md-code-hl-comment-color: var(--md-default-fg-color--light);
|
||||
--md-code-hl-generic-color: var(--md-default-fg-color--light);
|
||||
--md-code-hl-variable-color: var(--md-default-fg-color--light);
|
||||
|
||||
// Typeset color shades
|
||||
--md-typeset-color: var(--md-default-fg-color);
|
||||
|
||||
// Typeset `a` color shades
|
||||
--md-typeset-a-color: var(--md-primary-fg-color);
|
||||
|
||||
// Typeset `mark` color shades
|
||||
--md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5);
|
||||
|
||||
// Typeset `del` and `ins` color shades
|
||||
--md-typeset-del-color: hsla(6, 90%, 60%, 0.15);
|
||||
--md-typeset-ins-color: hsla(150, 90%, 44%, 0.15);
|
||||
|
||||
// Typeset `kbd` color shades
|
||||
--md-typeset-kbd-color: hsla(0, 0%, 98%, 1);
|
||||
--md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1);
|
||||
--md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1);
|
||||
|
||||
// Typeset `table` color shades
|
||||
--md-typeset-table-color: hsla(0, 0%, 0%, 0.12);
|
||||
|
||||
// Admonition color shades
|
||||
--md-admonition-fg-color: var(--md-default-fg-color);
|
||||
--md-admonition-bg-color: var(--md-default-bg-color);
|
||||
|
||||
// Footer color shades
|
||||
--md-footer-fg-color: hsla(0, 0%, 100%, 1);
|
||||
--md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7);
|
||||
--md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3);
|
||||
--md-footer-bg-color: hsla(0, 0%, 0%, 0.87);
|
||||
--md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32);
|
||||
}
|
||||
|
||||
// Shadow depth 1
|
||||
--md-shadow-z1:
|
||||
0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.05),
|
||||
0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.1);
|
||||
|
||||
// Shadow depth 2
|
||||
--md-shadow-z2:
|
||||
0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.1),
|
||||
0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.25);
|
||||
|
||||
// Shadow depth 3
|
||||
--md-shadow-z3:
|
||||
0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.2),
|
||||
0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.35);
|
||||
}
|
||||
2601
bbfd/docs/css/extra.css
Executable file
2601
bbfd/docs/css/extra.css
Executable file
File diff suppressed because it is too large
Load diff
28
bbfd/docs/css/iopsys-white.svg
Normal file
28
bbfd/docs/css/iopsys-white.svg
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Lager_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 460 84" style="enable-background:new 0 0 460 84;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="2.8" y="4.3" class="st0" width="16.7" height="76.1"/>
|
||||
<path class="st0" d="M88.8,3C65.3,3,48.3,20.8,48.3,42.4v0.2c0,21.6,16.9,39.1,40.3,39.1c23.5,0,40.6-17.7,40.6-39.4v-0.2
|
||||
C129.1,20.5,112.3,3,88.8,3z M111.6,42.6c0,13-9.4,23.7-22.8,23.7c-13.5,0-23-10.9-23-23.9v-0.2c0-13,9.4-23.7,22.8-23.7
|
||||
c13.5,0,23.1,10.9,23.1,23.9v0.2H111.6z"/>
|
||||
<path class="st0" d="M271.4,34.9c-13.2-3.4-16.4-5-16.4-10v-0.2c0-3.7,3.4-6.6,9.8-6.6s13,2.8,19.8,7.5l8.7-12.6
|
||||
c-7.7-6.2-17.2-9.7-28.3-9.7c-15.5,0-26.6,9.1-26.6,22.9v0.2c0,15.1,9.9,19.4,25.2,23.3c12.7,3.3,15.3,5.4,15.3,9.7v0.2
|
||||
c0,4.5-4.1,7.2-11,7.2c-8.7,0-15.9-3.6-22.7-9.2l-9.9,11.9c9.1,8.2,20.8,12.2,32.3,12.2c16.4,0,27.9-8.5,27.9-23.6v-0.2
|
||||
C295.5,44.5,286.8,38.9,271.4,34.9z"/>
|
||||
<polygon class="st0" points="347.3,34.9 329.1,4.3 309.5,4.3 338.8,50.4 338.8,80.4 355.5,80.4 355.5,50.1 384.8,4.3 365.7,4.3
|
||||
"/>
|
||||
<path class="st0" d="M432.2,34.9c-13.2-3.4-16.4-5-16.4-10v-0.2c0-3.7,3.4-6.6,9.8-6.6s13,2.8,19.8,7.5l8.7-12.6
|
||||
c-7.7-6.2-17.2-9.7-28.3-9.7c-15.6,0-26.6,9.1-26.6,22.9v0.2c0,15.1,9.9,19.4,25.2,23.3c12.7,3.3,15.3,5.4,15.3,9.7v0.2
|
||||
c0,4.5-4.1,7.2-11,7.2c-8.7,0-15.9-3.6-22.7-9.2l-9.9,11.9c9.1,8.2,20.8,12.2,32.3,12.2c16.4,0,27.9-8.5,27.9-23.6v-0.2
|
||||
C456.3,44.5,447.6,38.9,432.2,34.9z"/>
|
||||
<path class="st0" d="M186,4.3h-31.5v15.3h30c8.5,0,13.8,4.1,13.8,11.7v0.2c0,6.6-5,11.7-13.4,11.7h-30.4v37.2h16.9V58.3h12.9
|
||||
c17.3,0,31.1-9.2,31.1-27.1V31C215.5,15.2,204.3,4.3,186,4.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
17
bbfd/docs/css/pdf.css
Normal file
17
bbfd/docs/css/pdf.css
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
@page {
|
||||
size: a4 portrait;
|
||||
margin: 25mm 10mm 25mm 10mm;
|
||||
counter-increment: page;
|
||||
font-family: 'Madera', 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
|
||||
white-space: pre;
|
||||
color: grey;
|
||||
@top-left {
|
||||
content: '© 2022 IOPSYS';
|
||||
}
|
||||
@top-center {
|
||||
content: string(chapter);
|
||||
}
|
||||
@top-right {
|
||||
content: 'Page ' counter(page);
|
||||
}
|
||||
}
|
||||
4
bbfd/docs/guide/.pages
Normal file
4
bbfd/docs/guide/.pages
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
title: "USP Daemon Developer Guide"
|
||||
|
||||
nav:
|
||||
- "..."
|
||||
326
bbfd/docs/guide/data_model_integration.md
Normal file
326
bbfd/docs/guide/data_model_integration.md
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
# Third party data model integration
|
||||
|
||||
It is also possible to itegrate thrid party data model to the uspd to expose it to the ubus. To do so certain APIs in data model library needs to be implemented to make the data model compatible with uspd. APIs are described below.
|
||||
|
||||
|
||||
## List of libbbf methods used in uspd to integrate third party data model
|
||||
|
||||
### Refernces
|
||||
Deatils of bbf data model librabry can be found at [link](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/docs)
|
||||
|
||||
following are the libbbf methods used in uspd to access the data model defined in libbbf
|
||||
|
||||
``` dm_get_supported_dm
|
||||
dm_entry_param_method
|
||||
dm_entry_apply
|
||||
dm_ctx_init
|
||||
dm_ctx_init_sub
|
||||
dm_ctx_clean
|
||||
dm_ctx_clean_sub
|
||||
set_bbfdatamodel_type
|
||||
dm_entry_restart_services
|
||||
dm_entry_revert_changes
|
||||
dm_debug_browse_path
|
||||
get_dm_type
|
||||
dm_entry_manage_services
|
||||
dm_config_ubus
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Methods
|
||||
Description of the methods are given below
|
||||
|
||||
### dm_get_supported_dm
|
||||
|
||||
used to get the complete data model schema in one browse
|
||||
|
||||
```
|
||||
int dm_get_supported_dm(struct dmctx *ctx, char *path, bool first_level, schema_type_t schema_type)
|
||||
|
||||
inputs
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture. The list of parameters will be updated in ctx.list_parameter. each node in the list is of type
|
||||
struct dm_parameter which contains char *name (name of the parameter), char *data, char *type and char *additional_data;
|
||||
the content of fields are as follows-
|
||||
|
||||
| Type | Data | Addtional Data |
|
||||
|------------- |------------ |--------------------- |
|
||||
|DMT_COMMAND |in parameters |command type(sync/async) |
|
||||
| |out parameter | |
|
||||
|DMT_EVENT |in parameters |NA |
|
||||
|$ref(type) |writable(0/1) |unique keys |
|
||||
| | | |
|
||||
|
||||
char * path
|
||||
Complete object element path for which the data model schema is to be read. default path is "Device."
|
||||
|
||||
bool first_level
|
||||
if true, read only paramters at next level to path
|
||||
|
||||
schem_type_t schema_type
|
||||
enumeration to type of the schema to be get. Possible values are
|
||||
ALL_SCHEMA - Complete schema
|
||||
PARAM_ONLY - Parameters only
|
||||
EVENT_ONLY - Events only
|
||||
COMMAND_ONLY - Commands only
|
||||
|
||||
return
|
||||
int fault
|
||||
contains the fault code if API is not able to read the data model.
|
||||
```
|
||||
### dm_entry_param_method
|
||||
|
||||
used to read the data model based on the input given
|
||||
|
||||
```
|
||||
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2)
|
||||
|
||||
inputs
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture. The list of parameter will be updated in ctx.list_parameter. each node in the list is of type
|
||||
struct dm_parameter which contains char *name, char *data, char *type and char *additional_data;
|
||||
the content of fields are updated based on the cmd and are as follows-
|
||||
cmd | Name | Type | Data | Addtional Data |
|
||||
|------------- |------------- |------------- |------------ |--------------------- |
|
||||
|CMD_GET_VALUE |Parameter |$ref(type) |Value | NA |
|
||||
|CMD_GET_NAME |Parameter |$ref(type) |writable(0/1) | NA |
|
||||
|CMD_SET_VALUE |path | NA | NA | NA |
|
||||
|CMD_ADD_OBJECT |path | NA | NA | NA |
|
||||
|CMD_DEL_OBJECT |path | NA | NA | NA |
|
||||
|CMD_USP_OPERATE |path | NA | NA | NA |
|
||||
|CMD_USP_LIST_OPERATE |parameter |DMT_COMMAND |in/out parameters |cmd type (sync/async) |
|
||||
|CMD_USP_LIST_EVENT |paramter |DMT_EVENT |in parameters |NA |
|
||||
|CMD_GET_SCHEMA |paramter ||$ref(type) |writable(0/1) |unique keys |
|
||||
|CMD_GET_INSTANCES |parameter | NA |NA |NA |
|
||||
|
||||
int cmd
|
||||
command to API to tell how the data model is to be read, possible values are
|
||||
CMD_GET_VALUE - Read the values of the parameters from data model
|
||||
CMD_GET_NAME - Read the names of the parameters from data model
|
||||
CMD_SET_VALUE - Set value of specified parameters in the data model
|
||||
CMD_ADD_OBJECT - Add object in a multi instance parameter in the data model
|
||||
CMD_DEL_OBJECT - Delete object from a multi instance parameter in the data model
|
||||
CMD_USP_OPERATE - execute the specified command
|
||||
CMD_USP_LIST_OPERATE - Read all the command type parameter from data model.
|
||||
CMD_USP_LIST_EVENT - Read all the event type parameter from data model.
|
||||
CMD_GET_SCHEMA - Read all the parameter type parameter from data model.
|
||||
CMD_GET_INSTANCES - Read all the instance of multi instance parameter from data model.
|
||||
|
||||
char * inparam
|
||||
Complete object element path for which the data model schema is to be read. default path is "Device."
|
||||
|
||||
char *arg1 and char *arg2
|
||||
arguments specific to commands.
|
||||
|
||||
return
|
||||
int fault
|
||||
contains the fault code if API is not able to read the data model. returns 0 on success.
|
||||
```
|
||||
### dm_entry_apply
|
||||
|
||||
This method is called to apply the changes done to data model. used with set_value
|
||||
|
||||
```
|
||||
int dm_entry_apply(struct dmctx *ctx, int cmd)
|
||||
|
||||
inputs
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture. The list of parameter will be updated in ctx.list_parameter
|
||||
|
||||
int cmd
|
||||
command to API to tell how the data model is to be read, possible values are
|
||||
|
||||
CMD_SET_VALUE - Set value of specified parameters in the data model
|
||||
|
||||
char *arg1
|
||||
|
||||
return
|
||||
int fault
|
||||
contains the fault code if API is not able to read the data model.
|
||||
```
|
||||
### dm_ctx_init
|
||||
|
||||
This method is used to initialize the dmctx structure object to read the data model.
|
||||
|
||||
```
|
||||
int dm_ctx_init(struct dmctx *ctx, unsigned int instance_mode)
|
||||
inputs
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture to be initialized.
|
||||
|
||||
unsigned int instance_mode
|
||||
instance mode of the dmctx to be set.
|
||||
return
|
||||
int fault
|
||||
returns 0 on success.
|
||||
```
|
||||
|
||||
### dm_ctx_init_sub
|
||||
|
||||
This method is an extension of dm_ctx_init method. only difference it only intializes dmctx structure object and does not intializes other resources used in reading data model
|
||||
|
||||
```
|
||||
int dm_ctx_init_sub(struct dmctx *ctx, unsigned int instance_mode)
|
||||
inputs
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture to be initialized.
|
||||
|
||||
unsigned int instance_mode
|
||||
instance mode of the dmctx to be set.
|
||||
return
|
||||
int fault
|
||||
returns 0 on success.
|
||||
```
|
||||
|
||||
|
||||
### dm_ctx_clean
|
||||
|
||||
This method is used to free the dmctx structure object and other resources post reading the data model.
|
||||
|
||||
```
|
||||
int dm_ctx_clean(struct dmctx *ctx)
|
||||
|
||||
input
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture to be freed.
|
||||
|
||||
return
|
||||
int fault
|
||||
returns 0 on success.
|
||||
|
||||
```
|
||||
|
||||
### dm_ctx_clean_sub
|
||||
|
||||
This method is an extension of dm_ctx_clean method. only difference is it frees the dmctx structure and does not free other resources used in reading data model
|
||||
|
||||
```
|
||||
int dm_ctx_clean_sub(struct dmctx *ctx)
|
||||
|
||||
input
|
||||
struct dmctx *ctx
|
||||
pointer to struct dmctx strunture to be freed.
|
||||
|
||||
return
|
||||
int fault
|
||||
returns 0 on success.
|
||||
|
||||
```
|
||||
### set_bbfdatamodel_type
|
||||
|
||||
This method is used to set the type of protocol for which the data model is to be read
|
||||
```
|
||||
int set_bbfdatamodel_type(int bbf_type)
|
||||
|
||||
input
|
||||
int cmd
|
||||
the protocol through which the data model is to be read, possible values are
|
||||
BBFDM_USP - Protocol USP
|
||||
BBFDM_CWMP - Protocol CWMP
|
||||
BBFDM_BOTH - Both USP and CWMP
|
||||
|
||||
return
|
||||
int
|
||||
returns 0 on success.
|
||||
```
|
||||
### dm_entry_restart_services
|
||||
|
||||
This method is used to restart the state of data model whenever its state is changed
|
||||
|
||||
```
|
||||
int dm_entry_restart_services(void)
|
||||
|
||||
input
|
||||
None
|
||||
|
||||
return
|
||||
int
|
||||
returns 0 on success.
|
||||
```
|
||||
### dm_entry_revert_changes
|
||||
|
||||
This method is used to restart the state of data model whenever its state is changed
|
||||
|
||||
```
|
||||
int dm_entry_revert_changes(void)
|
||||
|
||||
input
|
||||
None
|
||||
|
||||
return
|
||||
int
|
||||
returns 0 on success.
|
||||
```
|
||||
|
||||
|
||||
### dm_debug_browse_path
|
||||
|
||||
This method returns the last accessed path in the data model
|
||||
|
||||
```
|
||||
int dm_debug_browse_path(char *buff, size_t len)
|
||||
input
|
||||
char *buff
|
||||
pointer to the buffer in which the path will be returned
|
||||
size_t len
|
||||
length of the buffer
|
||||
return
|
||||
int
|
||||
returns 0 on success.
|
||||
```
|
||||
|
||||
|
||||
### get_dm_type
|
||||
|
||||
This method is used to get the type assigned to the data model parameter.
|
||||
|
||||
```
|
||||
int get_dm_type(char *dm_str)
|
||||
|
||||
input
|
||||
char *dm_str
|
||||
data model parameter type, eg. xsd:string, xsd:unit etc.
|
||||
|
||||
return
|
||||
int
|
||||
type of data model assigned to the object eg. DMT_STRING, DMT_UNINT etc.
|
||||
|
||||
```
|
||||
|
||||
### dm_entry_manage_services
|
||||
This method is used to commit the changes made to the data model using either ubus call or uci commit.
|
||||
|
||||
```
|
||||
int dm_entry_manage_services(struct blob_buf *bb, bool restart)
|
||||
|
||||
input
|
||||
struct blob_buf *bb
|
||||
pointer to the struct blob_buf object. contains all the packages updated.
|
||||
bool restart
|
||||
if true packages will be updated through ubus call.
|
||||
if false packages will be updated through uci.
|
||||
|
||||
return
|
||||
int - returns 0 on success.
|
||||
```
|
||||
|
||||
### dm_entry_restart_services
|
||||
|
||||
this method is used to commit all the changes made to the data model.
|
||||
|
||||
```
|
||||
int dm_entry_restart_services(void)
|
||||
|
||||
return
|
||||
int - returns 0 on success.
|
||||
```
|
||||
### dm_config_ubus
|
||||
This method is used to configure ubus.
|
||||
|
||||
```
|
||||
void dm_config_ubus(struct ubus_context *ctx)
|
||||
|
||||
input
|
||||
struct ubus_context *ctx
|
||||
pointer to struct ubus_context object to be intialized.
|
||||
115
bbfd/docs/guide/ubus_errors.md
Normal file
115
bbfd/docs/guide/ubus_errors.md
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# UBUS Errors
|
||||
|
||||
## Path syntax and possible error cases
|
||||
|
||||
Please note some error scenerios with the uspd.
|
||||
|
||||
1. The path parameter value must start with 'Device.'. The command below doesn't have Device before path "Users.User."
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw get '{"path":"Users.User."}'
|
||||
{
|
||||
"fault": 7026
|
||||
}
|
||||
```
|
||||
|
||||
2. The path parameter must end with a '.' if the path element is not a leaf element e.g.,
|
||||
Note that first two commands doesn't end with a '.' while the command with Alias is correct, due to Alias
|
||||
being the leaf element. To find correct schema path user can check with dump_schema option.
|
||||
|
||||
```console
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.4"}'
|
||||
{
|
||||
"fault": 7026
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User"}'
|
||||
{
|
||||
"fault": 9005
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.*"}'
|
||||
{
|
||||
"fault": 7026
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.4.Alias"}'
|
||||
{
|
||||
"Alias": "cpe-4"
|
||||
}
|
||||
```
|
||||
|
||||
3. In path parameter value below, note that, the first search expression 'Type==Normal' is string which should be used as : Type==\"Normal\"
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Type==Normal].IPv4Address.[AddressingType==\"Static\"].IPAddress"}'
|
||||
{
|
||||
"fault": 7008
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Type==\"Normal\"].IPv4Address.[AddressingType==\"Static\"].IPAddress"}'
|
||||
{
|
||||
"Interface": [
|
||||
{
|
||||
"IPv4Address": [
|
||||
{
|
||||
"IPAddress": "2.0.0.3"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
4. The path parameter value must not have an empty search expression
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.[]."}'
|
||||
{
|
||||
"fault": 9005
|
||||
}
|
||||
```
|
||||
|
||||
5. The path parameter value must use proper '.' separated path search expression. Note that a '.' is missing between User and *
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User*."}'
|
||||
{
|
||||
"fault": 7026
|
||||
}
|
||||
```
|
||||
|
||||
6. The path parameter value must be a valid path schema, in example below SSID is used which is invalid schema element for Device.Users.User.{i}.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.1.SSID"}'
|
||||
{
|
||||
"fault": 7026
|
||||
}
|
||||
```
|
||||
|
||||
7. Please note that in search expression, string comparison only work with "==" or "!=". Whereas in command below its =
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.[Username=\"user\"].Alias"}'
|
||||
{
|
||||
"fault": 7008
|
||||
}
|
||||
```
|
||||
|
||||
#### Errors Codes
|
||||
|
||||
| Error Code | Meaning |
|
||||
|------------|--------------------------------------------------------------|
|
||||
| 7003 | Message failed due to an internal error. |
|
||||
| 7004 | Message failed due to invalid values in the request elements and/or failure to update one or more parameters during Add or Set requests. |
|
||||
| 7005 | Message failed due to memory or processing limitations. |
|
||||
| 7008 | Requested path was invalid or a reference was invalid. |
|
||||
| 7010 | Requested Path Name associated with this ParamError did not match any instantiated parameters. |
|
||||
| 7011 | Unable to convert string value to correct data type. |
|
||||
| 7012 | Out of range or invalid enumeration. |
|
||||
| 7022 | Command failed to operate. |
|
||||
| 7026 | Path is not present in the data model schema. |
|
||||
|
||||
|
||||
205
bbfd/docs/guide/ubus_example.md
Normal file
205
bbfd/docs/guide/ubus_example.md
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
# UBUS examples
|
||||
|
||||
```console
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.*.SSID"}'
|
||||
{
|
||||
"SSID": [
|
||||
{
|
||||
"SSID": "NORRLAND-34E380760120"
|
||||
},
|
||||
{
|
||||
"SSID": "NORRLAND-34E380760120"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.*.BSSID"}'
|
||||
{
|
||||
"SSID": [
|
||||
{
|
||||
"BSSID": "34:E3:80:76:01:22"
|
||||
},
|
||||
{
|
||||
"BSSID": "34:E3:80:76:01:23"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.[BSSID==\"34:E3:80:76:01:22\"].SSID"}'
|
||||
{
|
||||
"SSID": [
|
||||
{
|
||||
"SSID": "NORRLAND-34E380760120"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Status==\"Up\"].IPv4Address.[AddressingType==\"DHCP\"].IPAddress"}'
|
||||
{
|
||||
"Interface": [
|
||||
{
|
||||
"IPv4Address": [
|
||||
{
|
||||
"IPAddress": "192.168.0.96"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Status==\"Up\"].IPv4Address.[AddressingType==\"DHCP\"&&Status==\"Up\"]."}'
|
||||
{
|
||||
"Interface": [
|
||||
{
|
||||
"IPv4Address": [
|
||||
{
|
||||
"AddressingType": "DHCP",
|
||||
"Alias": "cpe-2",
|
||||
"Enable": true,
|
||||
"IPAddress": "192.168.0.96",
|
||||
"Status": "Up",
|
||||
"SubnetMask": "255.255.255.0",
|
||||
"X_IOPSYS_EU_FirewallEnabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Type==\"Normal\"&&Stats.PacketsSent<=500].IPv4Address.[AddressingType==\"Static\"].IPAddress"}'
|
||||
{
|
||||
"Interface": [
|
||||
{
|
||||
"IPv4Address": [
|
||||
{
|
||||
"IPAddress": "192.168.1.1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.AccessPoint.[SSIDReference+.SSID==\"NORRLAND-34E380760120\"].AssociatedDevice.[Noise>15].SignalStrength"}
|
||||
'
|
||||
{
|
||||
"AccessPoint": [
|
||||
{
|
||||
"AssociatedDevice": [
|
||||
{
|
||||
"SignalStrength": -31
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.*.LowerLayers#1+.Name"}'
|
||||
{
|
||||
{
|
||||
"Name": "wlan0",
|
||||
"Name": "wlan2"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.*.Username"}'
|
||||
{
|
||||
"User": [
|
||||
{
|
||||
"Username": "user"
|
||||
},
|
||||
{
|
||||
"Username": "support"
|
||||
},
|
||||
{
|
||||
"Username": "admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp.raw set '{"path":"Device.IP.Diagnostics.IPPing.DiagnosticsState", "value":"Requested", "proto":"cwmp"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.IP.Diagnostics.IPPing.DiagnosticsState",
|
||||
"status": true,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp.raw set '{"path":"Device.Users.User.2.Username", "value":"abc", "proto":"cwmp"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.Users.User.2.Username",
|
||||
"status": true,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp.raw set '{"path":"Device.Users.User.2.Username", "value":"abc", "proto":"usp"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.Users.User.2.Username",
|
||||
"status": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp.raw set '{"path":"Device.Users.User.2.Username", "value":"abc"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.Users.User.2.Username",
|
||||
"status": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp set '{"path":"Device.Users.User.[Username==\"xyz1\"].", "values":{"Username":"xyz1", "Enable":"dummy", "Password":"yzssssx"}, "proto":"usp"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.Users.User.2.Username",
|
||||
"status": true
|
||||
},
|
||||
{
|
||||
"path": "Device.Users.User.2.Enable",
|
||||
"status": false,
|
||||
"fault": 7012
|
||||
},
|
||||
{
|
||||
"path": "Device.Users.User.2.Password",
|
||||
"status": true
|
||||
}
|
||||
]
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp.raw setm_values '{"pv_tuple":[{"path":"Device.Users.User.2.Username", "value":"xzzz"}, {"path":"Device.Users.User.2.RemoteAccessCapable", "value":"1"}, {"path":"Device.Users.User.2.Password", "value":"zzzzzzz"}], "proto":"usp"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.Users.User.2.Username",
|
||||
"status": true
|
||||
},
|
||||
{
|
||||
"path": "Device.Users.User.2.RemoteAccessCapable",
|
||||
"status": false,
|
||||
"fault": 7012
|
||||
},
|
||||
{
|
||||
"path": "Device.Users.User.2.Password",
|
||||
"status": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- For more info on the usp ubus API see [link](../api/ubus/usp.md)
|
||||
- For more info on the usp.raw ubus API see [link](../api/ubus/usp.raw.md)
|
||||
|
||||
874
bbfd/docs/guide/ubus_methods.md
Normal file
874
bbfd/docs/guide/ubus_methods.md
Normal file
|
|
@ -0,0 +1,874 @@
|
|||
# UBUS Methods
|
||||
|
||||
`uspd` needs to be started on startup after `ubusd`, as it exposes the data-model
|
||||
objects over `ubus`. By default(when granularity is not set in `uci`), `uspd` registers
|
||||
below two namespaces with `ubus`.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus list |grep usp
|
||||
usp
|
||||
usp.raw
|
||||
```
|
||||
|
||||
`usp` namespace is to provide the output as required by `End User` or in pretty format,
|
||||
whereas `usp.raw` namespace is to provide output in raw JSON format for easy API integration,
|
||||
which can be used by other USP front-end applications(like: `obuspa`, `icwmp`).
|
||||
`usp` namespace has fewer methods defined to provide a simple interface to `end users`,
|
||||
whereas `usp.raw` has more features/methods to provide more customization options.
|
||||
|
||||
Default namespace with functionalities:
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus -v list usp
|
||||
'usp' @78f3eaca
|
||||
"list_operate":{}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus -v list usp.raw
|
||||
'usp.raw' @08a13407
|
||||
"dump_schema":{}
|
||||
"list_operate":{}
|
||||
"list_events":{}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"getm_values":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"getm_names":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"transaction_start":{"app":"String","max_timeout":"Integer"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"setm_values":{"pv_tuple":"Array","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"transaction_commit":{"transaction_id":"Integer"}
|
||||
"transaction_abort":{"transaction_id":"Integer"}
|
||||
"transaction_status":{"transaction_id":"Integer"}
|
||||
"notify_event":{"name":"String","input":"Table"}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
> Note1: `proto` in each method specify the data-model prototype('cwmp', 'usp') to use, if not provided default data-model will be used.
|
||||
|
||||
> Note2: `instance_mode` could be 0 or 1, for instance number, instance alias respectively.
|
||||
|
||||
> Note3: `next-level` true means only get next level objects and false means get all objects recursively
|
||||
|
||||
> Note4: `maxdepth` is measured on max number of .(Dot) present in object name
|
||||
|
||||
> Note5: `key` is used specifically for cwmp param_key
|
||||
|
||||
The objects registered with the above namespaces can be called with appropriate
|
||||
parameters to perform a USP `Get/Set/Operate/Add Object/Delete Object` operation as below.
|
||||
|
||||
## Granularity
|
||||
|
||||
Granularity feature is basically exposes the same USP functionality by registering
|
||||
additional ubus namespaces to reduce the `path` length in ubus parameter.
|
||||
It is the number of levels(Dots) up to which we want to shorten the length.
|
||||
|
||||
Ex:
|
||||
- When Granularity is set to 1, exposed ubus namespaces are
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus list|grep usp
|
||||
usp
|
||||
usp.Device.
|
||||
usp.raw
|
||||
```
|
||||
|
||||
- When Granularity is set to 2, exposed ubus namespaces are
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus list|grep usp
|
||||
usp
|
||||
usp.Device.
|
||||
usp.Device.Bridging.
|
||||
usp.Device.DHCPv4.
|
||||
usp.Device.DHCPv6.
|
||||
usp.Device.DNS.
|
||||
usp.Device.DeviceInfo.
|
||||
usp.Device.DynamicDNS.
|
||||
usp.Device.Ethernet.
|
||||
usp.Device.Firewall.
|
||||
usp.Device.Hosts.
|
||||
usp.Device.IP.
|
||||
usp.raw
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
These granular ubus objects provides the same functionality as of `usp` ubus namespace
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus -v list usp.Device.WiFi.
|
||||
'usp.Device.WiFi.' @6fd43aca
|
||||
"list_operate":{}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
Registered method can be called with appropriate parameters, like:
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.Device. get '{"path":"Users."}'
|
||||
{
|
||||
"Users": {
|
||||
"User": [
|
||||
{
|
||||
"Alias": "cpe-1",
|
||||
"Enable": true,
|
||||
"Language": "",
|
||||
"Password": "",
|
||||
"RemoteAccessCapable": true,
|
||||
"Username": "user"
|
||||
},
|
||||
{
|
||||
"Alias": "cpe-2",
|
||||
"Enable": true,
|
||||
"Language": "",
|
||||
"Password": "",
|
||||
"RemoteAccessCapable": true,
|
||||
"Username": "support"
|
||||
},
|
||||
{
|
||||
"Alias": "cpe-3",
|
||||
"Enable": true,
|
||||
"Language": "",
|
||||
"Password": "",
|
||||
"RemoteAccessCapable": true,
|
||||
"Username": "admin"
|
||||
}
|
||||
],
|
||||
"UserNumberOfEntries": 3
|
||||
}
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
## Overview
|
||||
|
||||
`uspd` provides below commands in pretty(usp) or raw(usp.raw) formats, some methods only available for API integration in usp.raw namespace:
|
||||
|
||||
- Get
|
||||
- Get multiple values
|
||||
- Get multiple names
|
||||
- Set
|
||||
- Operate
|
||||
- Add object
|
||||
- Delete object
|
||||
- Object names
|
||||
- Instances
|
||||
- Validate
|
||||
- List operate
|
||||
- Dump schema
|
||||
- Set multiple values
|
||||
- Transaction start
|
||||
- Transaction status
|
||||
- Transaction commit
|
||||
- Transaction abort
|
||||
- List supported usp events
|
||||
- Send notification for an event
|
||||
|
||||
It also provide a granularity layer which can be configured using uci parameter and provide additional ubus objects.
|
||||
|
||||
### Get
|
||||
API to query the value of a specific object.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Diagnostics.", "proto":"usp"}'
|
||||
{
|
||||
"Diagnostics": {
|
||||
"IPv4DownloadDiagnosticsSupported": true,
|
||||
"IPv4PingSupported": true,
|
||||
"IPv4ServerSelectionDiagnosticsSupported": true,
|
||||
"IPv4TraceRouteSupported": true,
|
||||
"IPv4UDPEchoDiagnosticsSupported": true,
|
||||
"IPv4UploadDiagnosticsSupported": true,
|
||||
"IPv6DownloadDiagnosticsSupported": true,
|
||||
"IPv6PingSupported": true,
|
||||
"IPv6ServerSelectionDiagnosticsSupported": true,
|
||||
"IPv6TraceRouteSupported": true,
|
||||
"IPv6UDPEchoDiagnosticsSupported": true,
|
||||
"IPv6UploadDiagnosticsSupported": true
|
||||
}
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Diagnostics.", "proto":"cwmp"}'
|
||||
{
|
||||
"Diagnostics": {
|
||||
"DownloadDiagnostics": {
|
||||
"BOMTime": "0",
|
||||
"DSCP": 0,
|
||||
"DiagnosticsState": "None",
|
||||
"DownloadDiagnosticMaxConnections": 1,
|
||||
"TotalBytesSent": 0,
|
||||
"TotalBytesSentUnderFullLoading": 0
|
||||
},
|
||||
"IPPing": {
|
||||
"AverageResponseTime": 0,
|
||||
"AverageResponseTimeDetailed": 0,
|
||||
"DSCP": 0,
|
||||
"DataBlockSize": 64,
|
||||
"ProtocolVersion": "Any",
|
||||
"SuccessCount": 0,
|
||||
"Timeout": 1000
|
||||
},
|
||||
"IPv4DownloadDiagnosticsSupported": true,
|
||||
"IPv4PingSupported": true,
|
||||
"IPv4ServerSelectionDiagnosticsSupported": true,
|
||||
"IPv6UDPEchoDiagnosticsSupported": true,
|
||||
"IPv6UploadDiagnosticsSupported": true,
|
||||
}
|
||||
}
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.Users."}'
|
||||
{
|
||||
"Users": {
|
||||
"User": [
|
||||
{
|
||||
"Alias": "cpe-1",
|
||||
"Enable": true,
|
||||
"Language": "",
|
||||
"Password": "",
|
||||
"RemoteAccessCapable": true,
|
||||
"Username": "user"
|
||||
},
|
||||
{
|
||||
"Alias": "cpe-2",
|
||||
"Enable": true,
|
||||
"Language": "",
|
||||
"Password": "",
|
||||
"RemoteAccessCapable": true,
|
||||
"Username": "support"
|
||||
},
|
||||
{
|
||||
"Alias": "cpe-3",
|
||||
"Enable": true,
|
||||
"Language": "",
|
||||
"Password": "",
|
||||
"RemoteAccessCapable": true,
|
||||
"Username": "admin"
|
||||
}
|
||||
],
|
||||
"UserNumberOfEntries": 3
|
||||
}
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp.raw get '{"path":"Device.Users."}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Alias",
|
||||
"value": "cpe-1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Enable",
|
||||
"value": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Language",
|
||||
"value": "",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Password",
|
||||
"value": "",
|
||||
"type": "xsd:string"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md#get)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md#get)
|
||||
|
||||
### Get multiple values
|
||||
API to get values of multiple objects at once, object name must be provided in `paths` parameter array as below.
|
||||
|
||||
> Note: This method is only available in `usp.raw` namespace.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw getm_values '{"paths":["Device.Users.User.1.Username","Device.DeviceInfo.SerialNumber"]}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Username",
|
||||
"value": "user",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.DeviceInfo.SerialNumber",
|
||||
"value": "E40A24H185027824",
|
||||
"type": "xsd:string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Get multiple objects
|
||||
API to get multiple objects from multiple paths at once.
|
||||
|
||||
> Note: This method only available in `usp.raw` namespace
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw getm_names '{"paths":["Device.Users.User.1.","Device.DeviceInfo.SerialNumber"]}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.1.",
|
||||
"value": "1",
|
||||
"type": "xsd:object"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Alias",
|
||||
"value": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Enable",
|
||||
"value": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Language",
|
||||
"value": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Password",
|
||||
"value": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.RemoteAccessCapable",
|
||||
"value": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Username",
|
||||
"value": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.DeviceInfo.SerialNumber",
|
||||
"value": "0",
|
||||
"type": "xsd:string"
|
||||
}
|
||||
]
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
### Set
|
||||
API to set value to specific object, object name must be provided in `path` parameter and value to be set in `value` option.
|
||||
|
||||
> Note 1: In usp namespace, set method creates a internal transaction before actually setting the value. After set operation it automatically commits the transaction.
|
||||
|
||||
> Note 2: In usp.raw namespace, set method requires a transaction to be created before calling the set method. Please refer to transaction APIs for more details.
|
||||
|
||||
```console
|
||||
root@iopsys:/tmp# ubus call usp set '{"path":"Device.WiFi.SSID.[BSSID==\"00:22:07:ae:ee:03\"].SSID", "value":"test-2g"}'
|
||||
{
|
||||
"status": true
|
||||
}
|
||||
root@iopsys:/tmp# ubus call usp.raw set '{"path":"Device.WiFi.SSID.[BSSID==\"00:22:07:ae:ee:03\"].SSID", "value":"test-2g", "transaction_id":12345}'
|
||||
{
|
||||
"status": true
|
||||
}
|
||||
root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.[BSSID==\"00:22:07:ae:ee:03\"].SSID"}'
|
||||
{
|
||||
"SSID": [
|
||||
{
|
||||
"SSID": "test-2g"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md#set)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md#set)
|
||||
|
||||
### Operate
|
||||
API to run operate/diagnostics commands as defined in TR-369
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp operate '{"path":"Device.IP.Diagnostics.", "action":"IPPing()","input":{"Host":"iopsys.eu"}}'
|
||||
{
|
||||
"Results": [
|
||||
{
|
||||
"path": "Device.IP.Diagnostics.IPPing",
|
||||
"result": [
|
||||
{
|
||||
"AverageResponseTime": 0,
|
||||
"AverageResponseTimeDetailed": 0,
|
||||
"FailureCount": 3,
|
||||
"MaximumResponseTime": 0,
|
||||
"MaximumResponseTimeDetailed": 0,
|
||||
"MinimumResponseTime": 9999,
|
||||
"MinimumResponseTimeDetailed": 999999999,
|
||||
"SuccessCount": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp.raw operate '{"path":"Device.IP.Diagnostics.", "action":"IPPing()","input":{"Host":"iopsys.eu"}}'
|
||||
{
|
||||
"Results": [
|
||||
{
|
||||
"path": "Device.IP.Diagnostics.IPPing",
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "AverageResponseTime",
|
||||
"value": "0",
|
||||
"type": "xsd:unsignedInt"
|
||||
},
|
||||
{
|
||||
"parameter": "AverageResponseTimeDetailed",
|
||||
"value": "0",
|
||||
"type": "xsd:unsignedInt"
|
||||
},
|
||||
{
|
||||
"parameter": "FailureCount",
|
||||
"value": "3",
|
||||
"type": "xsd:unsignedInt"
|
||||
},
|
||||
{
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp operate '{"path":"Device.IP.Interface.[Name==\"wan\"].", "action":"Reset()"}'
|
||||
{
|
||||
"Results": [
|
||||
{
|
||||
"path": "Device.IP.Interface.2.Reset",
|
||||
"result": [
|
||||
{
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
root@iopsys:~# ubus call usp.raw operate '{"path":"Device.IP.Interface.[Name==\"wan\"].", "action":"Reset()"}'
|
||||
{
|
||||
"Results": [
|
||||
{
|
||||
"path": "Device.IP.Interface.2.Reset",
|
||||
"parameters": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md#operate)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md#operate)
|
||||
|
||||
### Add object
|
||||
API to add new objects in multi-instance object
|
||||
|
||||
> Note 1: In usp namespace, `add_object` method creates a internal transaction before actually setting the value. After set operation it automatically commits the transaction.
|
||||
> Note 2: In usp.raw namespace, `add_object` method requires a transaction to be created before calling the set method. Please refer to transaction APIs for more details.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp add_object '{"path":"Device.Users.User."}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.",
|
||||
"status": true,
|
||||
"instance": "4"
|
||||
}
|
||||
]
|
||||
}
|
||||
root@iopsys:~# ubus call usp.raw add_object '{"path":"Device.Users.User.", "transaction_id":12345}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.",
|
||||
"status": true,
|
||||
"instance": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md#add_object)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md#add_object)
|
||||
|
||||
### Delete object
|
||||
API to delete an existing object from multi-instance object
|
||||
|
||||
> Note 1: In usp namespace, `del_object` method creates a internal transaction before actually setting the value. After set operation it automatically commits the transaction.
|
||||
> Note 2: In usp.raw namespace, `del_object` method requires a transaction to be created before calling the set method. Please refer to transaction APIs for more details.
|
||||
|
||||
```console
|
||||
root@iopsys:/tmp# ubus call usp del_object '{"path":"Device.Users.User.4"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.4.",
|
||||
"status": true
|
||||
}
|
||||
]
|
||||
}
|
||||
root@iopsys:/tmp# ubus call usp.raw del_object '{"path":"Device.Users.User.3", "transaction_id": 12345}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.3.",
|
||||
"status": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md#del_object)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md#del_object)
|
||||
|
||||
### Object names
|
||||
API to get the available list of object names.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp object_names '{"path":"Device.DeviceInfo.SerialNumber"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.DeviceInfo.SerialNumber",
|
||||
"writable": "0",
|
||||
"type": "xsd:string"
|
||||
}
|
||||
]
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp.raw object_names '{"path":"Device.Users.User.1."}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.Users.User.1.",
|
||||
"writable": "1",
|
||||
"type": "xsd:object"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Alias",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Enable",
|
||||
"writable": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Language",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Password",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.RemoteAccessCapable",
|
||||
"writable": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Users.User.1.Username",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
}
|
||||
]
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md)
|
||||
|
||||
### Instances
|
||||
API to get the available instances of an multi-instance object. USP Instances method returns the registered instances.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp instances '{"path":"Device.IP.Interface.", "proto":"usp"}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.IP.Interface.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.1.IPv4Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.2."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv4Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv6Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv6Prefix.1."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- For more info on the `usp` ubus API see [link](../api/ubus/usp.md#instances)
|
||||
- For more info on the `usp.raw` ubus API see [link](../api/ubus/usp.raw.md#instances)
|
||||
|
||||
### Validate
|
||||
API to validate a object in data-model. This api shall simply return the object name
|
||||
if present in data-model objects or generates a fault if object not available in
|
||||
data-model.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp validate '{"path":"Device.DeviceInfo."}'
|
||||
{
|
||||
"parameter": "Device.DeviceInfo"
|
||||
}
|
||||
root@iopsys:~# ubus call usp.raw validate '{"path":"invalid.object"}'
|
||||
{
|
||||
"fault": 9005
|
||||
}
|
||||
```
|
||||
|
||||
### List Operate
|
||||
API to list all available operate commands with supported input and output parameters
|
||||
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp list_operate
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.DHCPv4.Client.{i}.Renew()",
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.DNS.Diagnostics.NSLookupDiagnostics()",
|
||||
"type": "async",
|
||||
"in": [
|
||||
"HostName",
|
||||
"Interface",
|
||||
"DNSServer",
|
||||
"Timeout",
|
||||
"NumberOfRepetitions"
|
||||
],
|
||||
"out": [
|
||||
"Status",
|
||||
"AnswerType",
|
||||
"HostNameReturned",
|
||||
"IPAddresses",
|
||||
"DNSServerIP",
|
||||
"ResponseTime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameter": "Device.DeviceInfo.FirmwareImage.{i}.Activate()",
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Diagnostics.IPPing()",
|
||||
"type": "async",
|
||||
"in": [
|
||||
"Interface",
|
||||
"ProtocolVersion",
|
||||
"Host",
|
||||
"NumberOfRepetitions",
|
||||
"Timeout",
|
||||
"DataBlockSize",
|
||||
"DSCP"
|
||||
],
|
||||
"out": [
|
||||
"Status",
|
||||
"IPAddressUsed",
|
||||
"SuccessCount",
|
||||
"FailureCount",
|
||||
"AverageResponseTime",
|
||||
"MinimumResponseTime",
|
||||
"MaximumResponseTime",
|
||||
"AverageResponseTimeDetailed",
|
||||
"MinimumResponseTimeDetailed",
|
||||
"MaximumResponseTimeDetailed"
|
||||
]
|
||||
},
|
||||
{
|
||||
```
|
||||
|
||||
### Dump schema
|
||||
API to dump all registered schema paths,
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp dump_schema
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.",
|
||||
"writable": "1",
|
||||
"type": "xsd:object"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.Alias",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.DestinationAddress",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.Enable",
|
||||
"writable": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
```
|
||||
|
||||
### Set multiple values
|
||||
API to set value of multiple parameters at once.
|
||||
|
||||
> Note: This method only available in usp.raw namespace
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw setm_values '{"pv_tuple":[{"path":"Device.Users.User.2.Username", "value":"xzzz"}, {"path":"Device.Users.User.2.RemoteAccessCapable", "value":"true"}, {"path":"Device.Users.User.2.Password", "value":"zzzzzzz"}], "proto":"usp", "transaction_id":1249743667}'
|
||||
{
|
||||
"status": true
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp.raw setm_values '{"pv_tuple":[{"path":"Device.Users.User.2.Username", "value":"xzzz"}, {"path":"Device.Users.User.2.RemoteAccessCapable", "value":"dummy"}, {"path":"Device.Users.User.2.Password", "value":"zzzzzzz"}], "proto":"usp", "transaction_id":738335779}'
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"path": "Device.Users.User.2.RemoteAccessCapable",
|
||||
"status": false,
|
||||
"fault": 7012
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Transaction start
|
||||
To support the `allow_partial` and `required` parameters in Add/Del/Set operation as defined in TR-369, transaction_* APIs introduced.
|
||||
It basically works around data-model objects which has dependent uci config files for each CUD operation.
|
||||
API to start a transaction in usp.raw namespace for add/del/set operations in usp.raw namespace
|
||||
|
||||
> Note: This API only available in usp.raw namespace
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw transaction_start '{"app":"test"}'
|
||||
{
|
||||
"status": true,
|
||||
"transaction_id": 955001092
|
||||
}
|
||||
```
|
||||
|
||||
It's sometime required to have a per transaction timeout, which can be defined along with transaction_start
|
||||
```bash
|
||||
root@4949e4da3d27:~# ubus call usp.raw transaction_start '{"app":"test", "max_timeout":5000}'
|
||||
{
|
||||
"status": true,
|
||||
"transaction_id": 491944812
|
||||
}
|
||||
```
|
||||
> Note: max_timeout is time in milliseconds, its an optional input argument if not provided, uci default (uspd.usp.transaction_timeout) is used which is defined in seconds
|
||||
> If uci option uspd.usp.transaction_timeout not set than a default 10 second timeout is used for the transactions.
|
||||
|
||||
### Get status of a transaction
|
||||
API to get details and check status of a transaction id in usp.raw namespace
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw transaction_status '{"transaction_id":955001092}'
|
||||
{
|
||||
"app": "test",
|
||||
"status": "on-going",
|
||||
"remaining_time": 634
|
||||
}
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus call usp.raw transaction_status '{"transaction_id":869066287}'
|
||||
{
|
||||
"status": "not-exists"
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
### Transaction commit
|
||||
API to commit an on-going transaction, on calling this api, uci changes shall
|
||||
be committed and required services shall be restarted.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw transaction_commit '{"transaction_id":955001092}'
|
||||
{
|
||||
"status": true
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
### Transaction abort
|
||||
API to abort an on-going transaction, on calling this api, staged changes in
|
||||
uci shall be reverted to earlier values.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw transaction_abort '{"transaction_id":955001092}'
|
||||
{
|
||||
"status": true
|
||||
}
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
### List supported usp events
|
||||
API to list down the data-model events for usp notification supported by uspd.
|
||||
|
||||
```console
|
||||
root@iopsys:~# ubus call usp.raw list_events
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.LocalAgent.TransferComplete!",
|
||||
"in": [
|
||||
"Command",
|
||||
"CommandKey",
|
||||
"Requestor",
|
||||
"TransferType",
|
||||
"Affected",
|
||||
"TransferURL",
|
||||
"StartTime",
|
||||
"CompleteTime",
|
||||
"FaultCode",
|
||||
"FaultString"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
20
bbfd/docs/guide/ubus_parallel_call.md
Normal file
20
bbfd/docs/guide/ubus_parallel_call.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Parallel UBUS calls
|
||||
|
||||
All `operate` operation and `get` operation with a depth up to 'USP_SUBPROCESS_DEPTH(2)'
|
||||
runs in a parallel subprocess to avoid blocking the next call.
|
||||
|
||||
```console
|
||||
root@iopsys:~# time ubus call usp.raw get '{"path":"Device."}' >/dev/null &
|
||||
root@iopsys:~# time ubus call usp.raw get '{"path":"Device.Users."}' >/dev/null
|
||||
real 0m 0.07s
|
||||
user 0m 0.00s
|
||||
sys 0m 0.00s
|
||||
root@iopsys:~#
|
||||
real 0m 1.86s
|
||||
user 0m 0.05s
|
||||
sys 0m 0.00s
|
||||
|
||||
[1]+ Done time ubus call usp.raw get "{\"path\":\"Device.\"}" >/dev/null
|
||||
root@iopsys:~#
|
||||
```
|
||||
|
||||
90
bbfd/docs/mkdocs.yml
Executable file
90
bbfd/docs/mkdocs.yml
Executable file
|
|
@ -0,0 +1,90 @@
|
|||
site_name: Documentation Instructions
|
||||
site_url: https://docs.iopsys.se/portal2/uspd/
|
||||
edit_uri: "https://dev.iopsys.eu/docs/portal2/uspd"
|
||||
|
||||
site_description: IOWRT Technical Documentation
|
||||
site_author: IOPSYS
|
||||
|
||||
docs_dir: '.'
|
||||
site_dir: 'site'
|
||||
|
||||
|
||||
theme:
|
||||
name: material
|
||||
include_sidebar: true
|
||||
highlightjs: true
|
||||
hljs_languages:
|
||||
- yaml
|
||||
- python
|
||||
language: en
|
||||
font:
|
||||
text: Roboto
|
||||
code: Roboto Mono
|
||||
logo: iopsys-white.svg
|
||||
icon:
|
||||
logo: icon.png
|
||||
repo: fontawesome/brands/gitlab
|
||||
extra:
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/squidfunk
|
||||
features:
|
||||
- toc.autohide
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
- navigation.top
|
||||
- navigation.tracking
|
||||
- navigation.expand
|
||||
|
||||
palette:
|
||||
# Primary color used for header, sidebar and links, default: indigo
|
||||
primary: black
|
||||
# Accent color for highlighting user interaction, default: indigo
|
||||
accent: deep orange
|
||||
|
||||
extra_css:
|
||||
- css/extra.css
|
||||
- https://unpkg.com/mermaid@8.5.1/dist/mermaid.css
|
||||
- https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css
|
||||
|
||||
extra_javascript:
|
||||
- https://unpkg.com/mermaid/dist/mermaid.min.js
|
||||
- https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js
|
||||
- https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js
|
||||
|
||||
markdown_extensions:
|
||||
- meta
|
||||
- admonition
|
||||
- pymdownx.arithmatex
|
||||
- pymdownx.betterem:
|
||||
smart_enable: all
|
||||
- pymdownx.caret
|
||||
- pymdownx.critic
|
||||
- pymdownx.details
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.magiclink
|
||||
- pymdownx.mark
|
||||
- pymdownx.smartsymbols
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.tilde
|
||||
- pymdownx.superfences:
|
||||
# make exceptions to highlighting of code:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:mermaid2.fence_mermaid
|
||||
- fontawesome_markdown
|
||||
|
||||
plugins:
|
||||
- search:
|
||||
lang:
|
||||
- en
|
||||
separator: '[\s\-\.]+'
|
||||
- awesome-pages:
|
||||
collapse_single_pages: true
|
||||
- mermaid2
|
||||
- section-index
|
||||
10
bbfd/docs/preview.sh
Executable file
10
bbfd/docs/preview.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Copy README.md as index.md and change links
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Copy README.md as index.md and change links
|
||||
sed -r -e 's![\.\/]*docs[\/]*!./!g' ../README.md > index.md
|
||||
|
||||
# Start mkdocs local server
|
||||
mkdocs serve -f mkdocs.yml
|
||||
7
bbfd/docs/requirements.txt
Executable file
7
bbfd/docs/requirements.txt
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
mkdocs
|
||||
mkdocs-material
|
||||
mkdocs-awesome-pages-plugin
|
||||
mkdocs-section-index
|
||||
fontawesome_markdown
|
||||
mkdocs-print-site-plugin
|
||||
mkdocs-mermaid2-plugin
|
||||
4
bbfd/docs/spec/.pages
Normal file
4
bbfd/docs/spec/.pages
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
title: "USP Daemon Specification"
|
||||
|
||||
nav:
|
||||
- "..."
|
||||
336
bbfd/docs/spec/functionspec.md
Normal file
336
bbfd/docs/spec/functionspec.md
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
# Function Specification
|
||||
|
||||
The scope of uspd is to expose the datamodel provided by libbbfdm APIs over ubus, along with provididng the features deinfed by requirements R-ARC.7 to R-ARC.12 of USP protocol.
|
||||
|
||||
```
|
||||
root@iopsys:~# ubus -v list usp
|
||||
'usp' @232da280
|
||||
"list_operate":{}
|
||||
"get_supported_dm":{"path":"String","next-level":"Boolean","schema_type":"Integer"}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
|
||||
root@iopsys:~#
|
||||
root@iopsys:~# ubus -v list usp.raw
|
||||
'usp.raw' @4c9c3c6e
|
||||
"dump_schema":{}
|
||||
"list_operate":{}
|
||||
"list_events":{}
|
||||
"get_supported_dm":{"path":"String","next-level":"Boolean","schema_type":"Integer"}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"getm_values":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"getm_names":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"transaction_start":{"app":"String"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"setm_values":{"pv_tuple":"Array","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"transaction_commit":{"transaction_id":"Integer","restart_services":"Boolean"}
|
||||
"transaction_abort":{"transaction_id":"Integer"}
|
||||
"transaction_status":{"transaction_id":"Integer"}
|
||||
"notify_event":{"name":"String","input":"Table"}
|
||||
|
||||
```
|
||||
|
||||
# Contents
|
||||
* [usp](#usp)
|
||||
* [usp.raw](#uspraw)
|
||||
|
||||
## APIs
|
||||
|
||||
uspd publishes two different types UBUS objects, `usp`, `usp.raw`. USP object is meant for end users/CLI users
|
||||
usp.raw is meant for API integration
|
||||
usp.raw has more ganureality in the function to match the third party apllication requiremtns whereas usp obect take cares of cutomization internally to provide simple interface for the end users.
|
||||
|
||||
|
||||
### usp
|
||||
|
||||
An object that publishes device information.
|
||||
|
||||
````bash
|
||||
"list_operate":{}
|
||||
"get_supported_dm":{"path":"String","next-level":"Boolean","schema_type":"Integer"}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer"}
|
||||
````
|
||||
|
||||
| Method |Function ID |
|
||||
| :--- | :--- |
|
||||
| [list_operate](#list_operate) | 1 |
|
||||
| [get_supported_dm](#get_supported_dm) | 2 |
|
||||
| [get](#get) | 3 |
|
||||
| [object_names](#object_names) | 4 |
|
||||
| [instances](#instances) | 5 |
|
||||
| [validate](#validate) | 6 |
|
||||
| [set](#set) | 7 |
|
||||
| [operate](#operate) | 8 |
|
||||
| [add_object](#add_object) | 9 |
|
||||
| [del_object](#del_object) | 10 |
|
||||
|
||||
#### Methods
|
||||
|
||||
Below methods are supported in usp methods. Method description of the `usp` object in succeding paragraphs .
|
||||
|
||||
|
||||
##### list_operate
|
||||
|
||||
Exposes various sync and async operations supported by datamodel. e.g., IPPing(), NeighbourDiagnostics() etc.
|
||||
|
||||
* [list_operate documentation](../api/ubus/usp.md#list_operate)
|
||||
|
||||
##### get_supported_dm
|
||||
|
||||
This method exposes the all type of objects supported in the data model in one browse. it will expose name, type, cmd_type and writable properties of the object depending on the type of the parameters present in the data model.
|
||||
|
||||
* [get_supported_dm documentation](../api/ubus/usp.md#get_supported_dm)
|
||||
|
||||
|
||||
##### get
|
||||
|
||||
This method exposes information regarding various schema parameters registered in the data model.
|
||||
|
||||
* [get documentation](../api/ubus/usp.md#get)
|
||||
|
||||
##### object_names
|
||||
|
||||
This method exposes names of the object registered in the data model.
|
||||
|
||||
* [object_names documentation](../api/ubus/usp.md#object_names)
|
||||
|
||||
##### instances
|
||||
|
||||
This method exposes information of all instances of various objects registered in the data model for specified schema path.
|
||||
|
||||
* [disconnect documentation](../api/ubus/usp.md#instances)
|
||||
|
||||
##### validate
|
||||
|
||||
This method validates whether the path provided is valid as per registerd schema paths.
|
||||
|
||||
* [validate documentation](../api/ubus/usp.md#validate)
|
||||
|
||||
##### set
|
||||
|
||||
This method is used to set information of various registered schema parameters.
|
||||
|
||||
* [set documentation](../api/ubus/usp.md#set)
|
||||
|
||||
##### operate
|
||||
|
||||
This method is used to execute various sync/async operations e.g., IPPing(), NeighbourDiagnostics() etc.
|
||||
|
||||
* [operate documentation](../api/ubus/usp.md#operate)
|
||||
|
||||
##### add_object
|
||||
|
||||
This method is used to add an object to specified multi instance object in registered schema.
|
||||
|
||||
* [add_object neighbor documentation](../api/ubus/usp.md#add_object)
|
||||
|
||||
##### del_object
|
||||
|
||||
This method is used to delete an object from specified multi instance object in registered schema.
|
||||
|
||||
* [del_object documentation](../api/ubus/usp.md#del_object)
|
||||
|
||||
|
||||
|
||||
### usp.raw
|
||||
|
||||
Object for device functionality. One object per device will be published to
|
||||
ubus.
|
||||
|
||||
````bash
|
||||
"dump_schema":{}
|
||||
"list_operate":{}
|
||||
"list_events":{}
|
||||
"get_supported_dm":{"path":"String","next-level":"Boolean","schema_type":"Integer"}
|
||||
"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"getm_values":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"getm_names":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
|
||||
"transaction_start":{"app":"String"}
|
||||
"set":{"path":"String","value":"String","values":"Table","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
|
||||
"add_object":{"path":"String","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"del_object":{"path":"String","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"setm_values":{"pv_tuple":"Array","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
|
||||
"transaction_commit":{"transaction_id":"Integer","restart_services":"Boolean"}
|
||||
"transaction_abort":{"transaction_id":"Integer"}
|
||||
"transaction_status":{"transaction_id":"Integer"}
|
||||
"notify_event":{"name":"String","input":"Table"}
|
||||
|
||||
````
|
||||
|
||||
| Method |Function ID |
|
||||
| :--- | :--- |
|
||||
| [dump_schema](#dump_schema_raw) | 1 |
|
||||
| [list_operate](#list_operate_raw) | 2 |
|
||||
| [list_events](#list_events_raw) | 3 |
|
||||
| [get_supported_dm](#get_supported_dm_raw) | 4 |
|
||||
| [get](#get_raw) | 5 |
|
||||
| [getm_values](#getm_values_raw) | 6 |
|
||||
| [getm_names](#getm_names_raw) | 7 |
|
||||
| [object_names](#object_names_raw) | 8 |
|
||||
| [instances](#instances_raw) | 9 |
|
||||
| [validate](#validate_raw) | 10 |
|
||||
| [transaction_start](#transaction_start_raw) | 11 |
|
||||
| [set](#set_raw) | 12 |
|
||||
| [operate](#operate_raw) | 13 |
|
||||
| [add_object](#add_object_raw) | 14 |
|
||||
| [del_object](#del_object_raw) | 15 |
|
||||
| [setm_values](#setm_values_raw) | 16 |
|
||||
| [transaction_commit](#transaction_commit_raw) | 17 |
|
||||
| [transaction_abort](#transaction_abort_raw) | 18 |
|
||||
| [transaction_status](#transaction_status_raw) | 19 |
|
||||
| [notify_event](#notify_event_raw) | 20 |
|
||||
|
||||
|
||||
#### Methods
|
||||
|
||||
Below methods are supported in usp methods. Method description of the `usp` object in succeding paragraphs .
|
||||
|
||||
|
||||
##### dump_schema_raw
|
||||
|
||||
This method exposes schema registered in the data model .
|
||||
|
||||
* [dump_schema documentation](../api/ubus/usp.raw.md#dump_schema)
|
||||
|
||||
##### list_operate_raw
|
||||
|
||||
Exposes various sync and async operations supported by datamodel. e.g., IPPing(), NeighbourDiagnostics() etc.
|
||||
|
||||
* [list_operate documentation](../api/ubus/usp.raw.md#list_operate)
|
||||
|
||||
##### list_events_raw
|
||||
|
||||
Exposes various events registered in the datamodel.
|
||||
|
||||
* [list_events documentation](../api/ubus/usp.raw.md#list_events)
|
||||
|
||||
##### get_supported_dm_raw
|
||||
|
||||
This method exposes the all type of objects supported in the data model in one browse. it will expose name, type, cmd_type and writable properties of the object depending on the type of the parameters present in the data model.
|
||||
|
||||
* [get_supported_dm documentation](../api/ubus/usp.md#get_supported_dm)
|
||||
|
||||
|
||||
##### get_raw
|
||||
|
||||
This method exposes information of various schema parameters registered in the data model.
|
||||
|
||||
* [get documentation](../api/ubus/usp.raw.md#get)
|
||||
|
||||
##### getm_values_raw
|
||||
|
||||
This method is an extension to get method, this method can be use to get parameter values for multiple query paths at once.
|
||||
|
||||
* [getm_values documentation](../api/ubus/usp.raw.md#getm_values)
|
||||
|
||||
##### getm_names_raw
|
||||
|
||||
This method is an extension to get method, this method can be use to get parameter names for multiple query paths at once.
|
||||
|
||||
* [getm_names documentation](../api/ubus/usp.raw.md#getm_names)
|
||||
|
||||
|
||||
##### object_names_raw
|
||||
|
||||
This method exposes names of the objects in the spectified query path registered in the data model.
|
||||
|
||||
* [object_names documentation](../api/ubus/usp.raw.md#object_names)
|
||||
|
||||
##### instances_raw
|
||||
|
||||
Get all the instances for specified schema path.
|
||||
|
||||
* [disconnect documentation](../api/ubus/usp.raw.md#instances)
|
||||
|
||||
##### validate_raw
|
||||
|
||||
This method validates whether the path provided is valid as per registerd schema paths.
|
||||
|
||||
* [validate documentation](../api/ubus/usp.raw.md#validate)
|
||||
|
||||
|
||||
##### transaction_start
|
||||
|
||||
This method starts a transaction with the name provided.
|
||||
|
||||
* [transaction_start documentation](../api/ubus/usp.raw.md#transaction_start)
|
||||
|
||||
|
||||
##### set_raw
|
||||
|
||||
This method is used to set information of various registered schema parameters.
|
||||
|
||||
* [set documentation](../api/ubus/usp.raw.md#set)
|
||||
|
||||
##### operate_raw
|
||||
|
||||
This method is used to execute various sync/async operations e.g., IPPing(), NeighbourDiagnostics() etc.
|
||||
|
||||
* [operate documentation](../api/ubus/usp.raw.md#operate)
|
||||
|
||||
##### add_object_raw
|
||||
|
||||
This method is used to add an object to specified multi instance object in registered schema.
|
||||
|
||||
* [add_object neighbor documentation](../api/ubus/usp.raw.md#add_object)
|
||||
|
||||
##### del_object_raw
|
||||
|
||||
This method is used to delete an object from specified multi instance object in registered schema.
|
||||
|
||||
* [del_object documentation](../api/ubus/usp.raw.md#del_object)
|
||||
|
||||
##### setm_values_raw
|
||||
|
||||
This method is an extension to set method, this method can be use to set parameter values for multiple query paths at once.
|
||||
|
||||
* [setm_values documentation](../api/ubus/usp.raw.md#setm_values)
|
||||
|
||||
|
||||
##### transaction_commit
|
||||
|
||||
This method commits the changes made by an ongoing transaction.
|
||||
|
||||
* [transaction_commit documentation](../api/ubus/usp.raw.md#transaction_commit)
|
||||
|
||||
|
||||
##### transaction_abort
|
||||
|
||||
This method aborts an ongoing transaction.
|
||||
|
||||
* [transaction_abort documentation](../api/ubus/usp.raw.md#transaction_abort)
|
||||
|
||||
##### transaction_status
|
||||
|
||||
This method provides with the status of an ongoing transaction.
|
||||
|
||||
* [transaction_status documentation](../api/ubus/usp.raw.md#transaction_status)
|
||||
|
||||
##### notify_event
|
||||
|
||||
This method is used to get notified whenever the specified event occurs
|
||||
|
||||
* [notify_event documentation](../api/ubus/usp.raw.md#notify_event)
|
||||
464
bbfd/docs/spec/testspec.md
Normal file
464
bbfd/docs/spec/testspec.md
Normal file
|
|
@ -0,0 +1,464 @@
|
|||
# Test Specification
|
||||
|
||||
Most of the functionalities in uspd can be tested via its ubus API. Each
|
||||
API can be broken down into an individual test case to show full coverage is
|
||||
achieved.
|
||||
|
||||
# Sections
|
||||
* [Preqreuisites](#prerequisites)
|
||||
* [Test Suites](#test-suites)
|
||||
* [Functional API Tests](#functional-api-tests)
|
||||
* [Unit Tests](#unit-tests)
|
||||
* [Functional Tests](#functional-tests)
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The prerequisite for the uspd test suites is that libbbfdm and ubusd has to be
|
||||
built for the TEST platform, a version prepared to publish dummy data for get
|
||||
API, and record set API to a test logfile at `/tmp/test.log`.
|
||||
|
||||
| Dependency | Link | License |
|
||||
| :--- | :--- | :--- |
|
||||
| ---------- | ---------------------------------------- | -------- |
|
||||
| ubusd | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
|
||||
| libbbfdm | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 |
|
||||
|
||||
|
||||
## Test Suites
|
||||
|
||||
The uspd build pipe has three test suites, a functional-api suite, unit test suite
|
||||
and functional test suite.
|
||||
|
||||
### Functional API Tests
|
||||
|
||||
The functional API tests consists of two individual test suites, one per object
|
||||
Ubus under test. The functional API tests use the Ubus-API-validation
|
||||
command-line interface tool to invoke a method, programmatically through
|
||||
libubus, and validates it against the objects json-schema.
|
||||
|
||||
#### usp
|
||||
|
||||
| Execution ID | Method | Description | Function ID Coverage |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| 1 | list_operate | No argument | [1](./functionspec.md#list_operate) |
|
||||
| 2 | get_supported_dm \ with path argument | [2](./functionspec.md#get_supported_dm) |
|
||||
| 3 | get | With path argument | [3](./functionspec.md#get) |
|
||||
| 4 | object_names | With path argument | [4](./functionspec.md#object_names) |
|
||||
| 5 | instances | With path argument | [5](./functionspec.md#instances) |
|
||||
| 6 | validate | With path argument | [6](./functionspec.md#validate) |
|
||||
| 7 | set | With path and value arguments | [7](./functionspec.md#set) |
|
||||
| 8 | operate | With path, action and input arguments | [8](./functionspec.md#operate) |
|
||||
| 9 | add_object | With path argument | [9](./functionspec.md#add_object) |
|
||||
| 10 | del_object | With path argument | [10](./functionspec.md#del_object) |
|
||||
|
||||
|
||||
#### usp.raw
|
||||
|
||||
| Execution ID | Method | Description | Function ID Coverage |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| 1 | dump_schema | No argument | [15](./functionspec.md#dump_schema_raw) |
|
||||
| 2 | list_operate | No argument | [16](./functionspec.md#list_operate_raw) |
|
||||
| 3 | list_events | No argument | [16](./functionspec.md#list_events) |
|
||||
| 4 | get_supported_dm | with path argument | [2](./functionspec.md#get_supported_dm) |
|
||||
| 5 | get | With path argument | [17](./functionspec.md#get_raw) |
|
||||
| 6 | getm_values | With paths array argument | [25](./functionspec.md#getm_values_raw) |
|
||||
| 7 | getm_name | With paths array argument | [26](./functionspec.md#getm_names_raw) |
|
||||
| 8 | object_names | With path argument | [18](./functionspec.md#object_names_raw) |
|
||||
| 9 | instances | With path argument | [19](./functionspec.md#instances_raw) |
|
||||
| 10 | validate | With path argument | [20](./functionspec.md#validate_raw) |
|
||||
| 11 | transaction_start | With app argument | [17](./functionspec.md#transaction_start) |
|
||||
| 12 | set | With path and value arguments | [21](./functionspec.md#set_raw) |
|
||||
| 13 | operate | With path, action and input arguments | [22](./functionspec.md#operate_raw) |
|
||||
| 14 | add_object | With path argument | [23](./functionspec.md#add_object_raw) |
|
||||
| 15 | del_object | With path argument | [24](./functionspec.md#del_object_raw) |
|
||||
| 16 | setm_values | With pv_tuple and transaction_id argument | [17](./functionspec.md#setm_val) |
|
||||
| 17 | transaction_commit | With transaction_id argument | [17](./functionspec.md#transaction_commit) |
|
||||
| 18 | transaction_abort | With transaction_id argument | [17](./functionspec.md#transaction_abort) |
|
||||
| 19 | transaction_status | With transaction_id argument | [17](./functionspec.md#transaction_status) |
|
||||
| 20 | notify_event | With ***** argument | [17](./functionspec.md#notify_event) |
|
||||
|
||||
|
||||
### Unit Tests
|
||||
|
||||
The uspd unit tests are written in cmocka, invoking the ubus callbacks
|
||||
directly from the source code, which is compiled into a shared library.
|
||||
This means mocking the arguments of a cli or libubus invoke in a
|
||||
`struct blob_attr *`. The results of the call will be logged to the logfile at
|
||||
`/tmp/test.log`.
|
||||
|
||||
| Execution ID | Method | Test Case Name | Function ID Coverage |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| 1 | dump_schema | [test_api_usp_raw_dump_schema](#test_api_usp_raw_dump_schema) | [1](./functionspec.md#dump_schema_raw)
|
||||
| 2 | list_operate | [test_api_usp_list_operate](#test_api_usp_list_operate) | [2](./functionspec.md#list_operate) |
|
||||
| 3 | get | [test_api_usp_get](#test_api_usp_get) | [3](./functionspec.md#get) |
|
||||
| 4 | object_names | [test_api_usp_object_name](#test_api_usp_object_name) | [4](./functionspec.md#object_names) |
|
||||
| 5 | instances | [test_api_usp_instances](#test_api_usp_instances) | [5](./functionspec.md#instances) |
|
||||
| 6 | validate | [test_api_usp_resolve](#test_api_usp_resolve) | [6](./functionspec.md#validate) |
|
||||
| 7 | set | [test_api_usp_set](#test_api_usp_set) | [7](./functionspec.md#set) |
|
||||
| 8 | add_object | [test_api_usp_add_object](#test_api_usp_add_object) | [9](./functionspec.md#add_object) |
|
||||
| 9 | del_object | [test_api_usp_del](#test_api_usp_del_object) | [10](./functionspec.md#del_object) |
|
||||
| 10 | getm_values | [test_api_usp_get_safe_values](#test_api_usp_get_safe_values) | [11](./functionspec.md#getm_values) |
|
||||
| 11 | getm_name | [test_api_usp_get_safe_names](#test_api_usp_get_safe_names) | [12](./functionspec.md#getm_names) |
|
||||
|
||||
#### test_api_usp_dump_schema
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the uspd ubus API callback `dump_schema`, publishing the method
|
||||
[dump_schema](./functionspec.md#dump_schema).
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Issuing a dump_schema to a client from the uspd test platform.
|
||||
|
||||
Read the logfile and verify that the `schema` argument was
|
||||
accurately logged.
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
dump_schema function.
|
||||
|
||||
````bash
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.",
|
||||
"writable": "1",
|
||||
"type": "xsd:object"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.Alias",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.DestinationAddress",
|
||||
"writable": "1",
|
||||
"type": "xsd:string"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.ATM.Link.{i}.Enable",
|
||||
"writable": "1",
|
||||
"type": "xsd:boolean"
|
||||
},
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### test_api_usp_list_operate
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the uspd ubus API `list_operate`, publishing the method
|
||||
[list_operate](./functionspec.md#list_operate).
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Issuing a list_operate to a client from the uspd test platform.
|
||||
|
||||
Read the logfile and verify that the `list_operate` argument was
|
||||
accurately logged.
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
````bash
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.DHCPv4.Client.{i}.Renew()",
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.DNS.Diagnostics.NSLookupDiagnostics()",
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
{
|
||||
"parameter": "Device.IP.Diagnostics.IPPing()",
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Diagnostics.TraceRoute()",
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Diagnostics.UDPEchoDiagnostics()",
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.{i}.Reset()",
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"parameter": "Device.Reboot()",
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
|
||||
```
|
||||
|
||||
#### test_api_usp_get
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the uspd ubus API get, publishing the method
|
||||
[get](./functionspec.md#get).
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Prepare the arguments as:
|
||||
|
||||
````bash
|
||||
{"path":"Device.IP.Diagnostics.", "proto":"usp"}
|
||||
```
|
||||
|
||||
Requesting the libbfdm with the path `Device.IP.Diagnostics.`.
|
||||
|
||||
Read the logfile and verify that the interface and arguments were accurately
|
||||
logged.
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
`libbbfdm`, through ubus and with the argument `path` as `Device.IP.Diagnostics.`
|
||||
`proto` as `usp`.
|
||||
|
||||
````bash
|
||||
{
|
||||
"Diagnostics": {
|
||||
"IPv4DownloadDiagnosticsSupported": true,
|
||||
"IPv4PingSupported": true,
|
||||
"IPv4ServerSelectionDiagnosticsSupported": true,
|
||||
"IPv4TraceRouteSupported": true,
|
||||
"IPv6UploadDiagnosticsSupported": true,
|
||||
"UDPEchoConfig": {
|
||||
"BytesReceived": 0,
|
||||
"BytesResponded": 0,
|
||||
"TimeFirstPacketReceived": "0",
|
||||
"TimeLastPacketReceived": "0",
|
||||
"UDPPort": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### test_api_usp_instances
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the uspd ubus API instances, publishing the method
|
||||
[instances](./functionspec.md#instances).
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Prepare the arguments as:
|
||||
|
||||
````bash
|
||||
{"path":"Device.IP.Interface.", "proto":"usp"}
|
||||
```
|
||||
|
||||
Requesting the libbfdm with the path `Device.IP.Interface.`.
|
||||
|
||||
Read the logfile and verify that the interface and arguments were accurately
|
||||
logged.
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
`libbbfdm`, through ubus and with the argument `path` as `Device.IP.Interface.`
|
||||
`proto` as `usp`.
|
||||
|
||||
````bash
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.IP.Interface.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.1.IPv4Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.2."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv4Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv6Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv6Prefix.1."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### test_api_usp_instances
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the uspd ubus API instances, publishing the method
|
||||
[instances](./functionspec.md#instances).
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Prepare the arguments as:
|
||||
|
||||
````bash
|
||||
{"path":"Device.IP.Interface.", "proto":"usp"}
|
||||
````
|
||||
|
||||
Requesting the libbfdm with the path `Device.IP.Interface.`.
|
||||
|
||||
Read the logfile and verify that the interface and arguments were accurately
|
||||
logged.
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
`libbbfdm`, through ubus and with the argument `path` as `Device.IP.Interface.`
|
||||
`proto` as `usp`.
|
||||
|
||||
```bash
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"parameter": "Device.IP.Interface.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.1.IPv4Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.2."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv4Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv6Address.1."
|
||||
},
|
||||
{
|
||||
"parameter": "Device.IP.Interface.3.IPv6Prefix.1."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Functional Tests
|
||||
|
||||
|
||||
#### test_func_ref_follow
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the reference follow for search path. Reference follow is basically
|
||||
quering a search path, which is referenced by the path queried for.
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Prepare the arguments as:
|
||||
|
||||
````bash
|
||||
{"path":"Device.WiFi.SSID.1.LowerLayers+.Alias", "proto":"usp"}
|
||||
```
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
`libbbfdm`, through ubus and with the argument `path` as `Device.WiFi.SSID.1.LowerLayers+.Alias` and `proto` as `usp`.
|
||||
|
||||
````bash
|
||||
{
|
||||
"Device": {
|
||||
"WiFi": {
|
||||
"Radio": [
|
||||
{
|
||||
"Alias": "cpe-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### test_func_list_of_ref
|
||||
|
||||
##### Description
|
||||
|
||||
Tests the list of reference following for search path. Reference follow is basically
|
||||
quering a search path, which is referenced by the path queried for.
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Prepare the arguments as:
|
||||
|
||||
````bash
|
||||
{"path":"Device.WiFi.SSID.1.LowerLayers#1+.Name"}
|
||||
```
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
`libbbfdm`, through ubus and with the argument `path` as `Device.WiFi.SSID.1.LowerLayers#1+.Name` and `proto` as `usp`.
|
||||
|
||||
````bash
|
||||
{
|
||||
"Device": {
|
||||
"WiFi": {
|
||||
"Radio": [
|
||||
{
|
||||
"Name": "wl0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### test_func_search_expr
|
||||
|
||||
##### Description
|
||||
|
||||
Testing search path, this is a path Name that contains search criteria for addressing a
|
||||
set of Multi-Instance Objects and/or their parameters. A Search path may contain a
|
||||
Search Expression or Wildcard.
|
||||
|
||||
##### Test Steps
|
||||
|
||||
Prepare the arguments as:
|
||||
|
||||
````bash
|
||||
{"path":"Device.WiFi.SSID.[Status==\"Up\"].Alias"}
|
||||
```
|
||||
|
||||
##### Test Expected Results
|
||||
|
||||
In the above bash parameter path we can identify the square brackets as search path. So basically through this search path we are querying 'Alias' for any WiFi.SSID instance having
|
||||
`Up` Status.
|
||||
|
||||
The expected result is for the log file to have recorded a call to the
|
||||
`libbbfdm`, through ubus and with the argument `path` as `Device.WiFi.SSID.1.LowerLayers#1+.Name` and `proto` as `usp`.
|
||||
|
||||
````bash
|
||||
{
|
||||
"SSID": [
|
||||
{
|
||||
"Alias": "cpe-1"
|
||||
},
|
||||
{
|
||||
"Alias": "cpe-2"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
63
bbfd/gitlab-ci/functional-api-test.sh
Executable file
63
bbfd/gitlab-ci/functional-api-test.sh
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "$0 preparation script"
|
||||
pwd
|
||||
|
||||
source ./gitlab-ci/shared.sh
|
||||
|
||||
trap cleanup EXIT
|
||||
trap cleanup SIGINT
|
||||
|
||||
# clean and make
|
||||
make clean
|
||||
CFLAGS="-g -Os -fprofile-arcs -ftest-coverage -DUSPD_MAX_MSG_LEN=1048576" LDFLAGS="--coverage" make func-test -C ./
|
||||
check_ret $?
|
||||
|
||||
supervisorctl update
|
||||
supervisorctl restart all
|
||||
supervisorctl status all
|
||||
exec_cmd ubus wait_for usp.raw usp
|
||||
supervisorctl status all
|
||||
|
||||
# debug logging
|
||||
echo "Checking ubus status [$(date '+%d/%m/%Y %H:%M:%S')]"
|
||||
ubus list
|
||||
ubus -v list usp.raw
|
||||
ubus -v list usp
|
||||
|
||||
echo "Checking system resources"
|
||||
free -h
|
||||
df -h
|
||||
sleep 5
|
||||
# run functional on usp object validation
|
||||
if [ -f "/usr/share/rpcd/schemas/usp*.json" ]; then
|
||||
rm /usr/share/rpcd/schemas/usp*.json
|
||||
fi
|
||||
|
||||
cp -r ./schemas/ubus/usp.json /usr/share/rpcd/schemas
|
||||
ubus-api-validator -t 5 -f ./test/api/json/usp.validation.json > ./api-result.log
|
||||
generate_report usp_api api-result.log
|
||||
|
||||
# run functional on usp object validation
|
||||
if [ -f "/usr/share/rpcd/schemas/usp*.json" ]; then
|
||||
rm /usr/share/rpcd/schemas/usp*.json
|
||||
fi
|
||||
|
||||
cp -r ./schemas/ubus/usp.raw.json /usr/share/rpcd/schemas
|
||||
ubus-api-validator -t 5 -f ./test/api/json/usp.raw.validation.json >> ./api-result.log
|
||||
generate_report usp_raw_api api-result.log
|
||||
|
||||
supervisorctl status all
|
||||
supervisorctl stop all
|
||||
supervisorctl status
|
||||
|
||||
#report part
|
||||
date +%s > timestamp.log
|
||||
gcovr -r . --xml -o ./api-test-coverage.xml
|
||||
gcovr -r .
|
||||
|
||||
echo "Checking memory leaks..."
|
||||
grep -q "Leak" memory-report.xml
|
||||
error_on_zero $?
|
||||
|
||||
echo "Functional ubus API test :: PASS"
|
||||
111
bbfd/gitlab-ci/functional-test.sh
Executable file
111
bbfd/gitlab-ci/functional-test.sh
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "$0 preparation script"
|
||||
pwd
|
||||
|
||||
source ./gitlab-ci/shared.sh
|
||||
|
||||
trap cleanup EXIT
|
||||
trap cleanup SIGINT
|
||||
|
||||
make clean
|
||||
CFLAGS="-g -Os -fprofile-arcs -ftest-coverage -DUSPD_MAX_MSG_LEN=1048576" LDFLAGS="--coverage" make func-test -C ./
|
||||
check_ret $?
|
||||
ls
|
||||
|
||||
supervisorctl update
|
||||
supervisorctl restart all
|
||||
supervisorctl status all
|
||||
exec_cmd ubus wait_for usp.raw usp
|
||||
supervisorctl status all
|
||||
|
||||
# debug logging
|
||||
echo "Checking ubus status [$(date '+%d/%m/%Y %H:%M:%S')]"
|
||||
ubus list
|
||||
ubus -v list usp.raw
|
||||
ubus -v list usp
|
||||
|
||||
echo "Checking system resources"
|
||||
free -h
|
||||
df -h
|
||||
|
||||
echo "## Preparing shared library for uspd msglen test ##"
|
||||
exec_cmd make -C ./test
|
||||
|
||||
echo "## Running python based verification of functionalities ##"
|
||||
echo > ./funl-result.log
|
||||
num=0
|
||||
for test in `ls -1 ./test/python/*.py`
|
||||
do
|
||||
num=$(( num + 1 ))
|
||||
sleep 1
|
||||
$test
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ok ${num} - $test" >> ./funl-result.log
|
||||
|
||||
else
|
||||
echo "not ok ${num} - $test" >> ./funl-result.log
|
||||
fi
|
||||
done
|
||||
|
||||
echo "1..${num}" >> ./funl-result.log
|
||||
generate_report python_test ./funl-result.log
|
||||
|
||||
# run functional on usp object validation
|
||||
if [ -f "/usr/share/rpcd/schemas/usp*.json" ]; then
|
||||
rm /usr/share/rpcd/schemas/usp*.json
|
||||
fi
|
||||
|
||||
fault=0
|
||||
# run functional on usp object validation
|
||||
cp -r ./test/funl/schema/usp_test_positive.json /usr/share/rpcd/schemas/usp.json
|
||||
ubus-api-validator -t 5 -f ./test/funl/validation/usp.validation.positive.json > ./funl-result.log
|
||||
fault=$?
|
||||
generate_report usp_positive ./funl-result.log
|
||||
|
||||
cp -r ./test/funl/schema/usp_test_negative.json /usr/share/rpcd/schemas/usp.json
|
||||
ubus-api-validator -t 5 -f ./test/funl/validation/usp.validation.negative.json > ./funl-result.log
|
||||
fault=$(( $fault + $? ))
|
||||
generate_report usp_negative ./funl-result.log
|
||||
|
||||
# run functional on usp.raw object validation
|
||||
rm /usr/share/rpcd/schemas/usp*.json
|
||||
cp -r ./test/funl/schema/usp.raw_test_positive.json /usr/share/rpcd/schemas/usp.raw.json
|
||||
ubus-api-validator -t 5 -f ./test/funl/validation/usp.raw.validation.positive.json > ./funl-result.log
|
||||
fault=$(( $fault + $? ))
|
||||
generate_report usp_raw_positive ./funl-result.log
|
||||
|
||||
#test usp.raw for negative test cases
|
||||
cp -r ./test/funl/schema/usp.raw_test_negative.json /usr/share/rpcd/schemas/usp.raw.json
|
||||
ubus-api-validator -t 5 -f ./test/funl/validation/usp.raw.validation.negative.json > ./funl-result.log
|
||||
fault=$(( $fault + $? ))
|
||||
generate_report usp_raw_negative ./funl-result.log
|
||||
|
||||
# TODO: add for granularity ubus objects
|
||||
#uci set uspd.usp.granularitylevel='1'
|
||||
#uci commit
|
||||
|
||||
#ubus-api-validator -f ./test/funl/json/gran/gran.validation.json >> ./funl-result.log
|
||||
#fault=$?
|
||||
|
||||
#uci set uspd.usp.granularitylevel='0'
|
||||
#uci commit
|
||||
|
||||
supervisorctl stop all
|
||||
supervisorctl status
|
||||
|
||||
#report part
|
||||
gcovr -r . --xml -o ./funl-test-coverage.xml
|
||||
gcovr -r .
|
||||
date +%s > timestamp.log
|
||||
|
||||
echo "Checking memory leaks..."
|
||||
grep -q "Leak" memory-report.xml
|
||||
error_on_zero $?
|
||||
|
||||
if [ "${fault}" -ne 0 ]; then
|
||||
echo "Failed running ubus-api-validator fault[$fault]"
|
||||
exit $fault
|
||||
fi
|
||||
|
||||
echo "Functional Test :: PASS"
|
||||
56
bbfd/gitlab-ci/install-dependencies.sh
Executable file
56
bbfd/gitlab-ci/install-dependencies.sh
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "install dependencies of uspd"
|
||||
pwd
|
||||
|
||||
source ./gitlab-ci/shared.sh
|
||||
|
||||
# install required packages
|
||||
exec_cmd apt update
|
||||
exec_cmd apt install -y python3-pip
|
||||
exec_cmd pip3 install pexpect ubus
|
||||
git config --global --add safe.directory ${PWD}
|
||||
branch="$(git branch --show-current)"
|
||||
|
||||
# install libbbf
|
||||
cd /opt/dev
|
||||
rm -rf bbf
|
||||
|
||||
if [ -z "${BBF_TAR_URL}" ]; then
|
||||
if ! git clone -b ${branch} https://dev.iopsys.eu/iopsys/bbf.git; then
|
||||
exec_cmd git clone https://dev.iopsys.eu/iopsys/bbf.git
|
||||
fi
|
||||
|
||||
cd bbf
|
||||
echo "BBF Upstream Hash ${UPSTREAM_BBF_SHA}, uspd branch ${branch}"
|
||||
if [ -n "${UPSTREAM_BBF_SHA}" ]; then
|
||||
exec_cmd git checkout ${UPSTREAM_BBF_SHA}
|
||||
fi
|
||||
|
||||
git log -1
|
||||
source ./gitlab-ci/shared.sh
|
||||
install_libbbf
|
||||
./gitlab-ci/setup.sh
|
||||
else
|
||||
echo "## Installing upstream libbbf release from [${BBF_TAR_URL}] ##"
|
||||
mkdir -p bbf
|
||||
cd bbf
|
||||
exec_cmd wget -q ${BBF_TAR_URL} -O bbf.sh
|
||||
chmod +x bbf.sh
|
||||
./bbf.sh --prefix=/ --exclude-subdir --skip-license
|
||||
ldconfig
|
||||
cd ..
|
||||
fi
|
||||
|
||||
cd -
|
||||
# install usermngr plugin
|
||||
rm -rf /opt/dev/usermngr
|
||||
exec_cmd git clone https://dev.iopsys.eu/iopsys/usermngr.git /opt/dev/usermngr
|
||||
|
||||
echo "Compiling libusermngr"
|
||||
make clean -C /opt/dev/usermngr/src
|
||||
make -C /opt/dev/usermngr/src
|
||||
|
||||
echo "Installing libusermngr"
|
||||
cp -f /opt/dev/usermngr/src/libusermngr.so /usr/lib/bbfdm
|
||||
|
||||
15
bbfd/gitlab-ci/iopsys-supervisord.conf
Normal file
15
bbfd/gitlab-ci/iopsys-supervisord.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[program:ubusd]
|
||||
autorestart=false
|
||||
priority=1
|
||||
command=/bin/bash -c "/usr/sbin/ubusd"
|
||||
|
||||
[program:rpcd]
|
||||
autorestart=false
|
||||
priority=2
|
||||
command=/bin/bash -c "/usr/sbin/rpcd"
|
||||
|
||||
[program:uspd]
|
||||
autorestart=false
|
||||
priority=3
|
||||
command=/bin/bash -c "/usr/bin/valgrind --xml=yes --xml-file=/builds/iopsys/uspd/memory-report.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes --leak-resolution=high --show-error-list=yes --child-silent-after-fork=yes /builds/iopsys/uspd/uspd"
|
||||
|
||||
14
bbfd/gitlab-ci/setup.sh
Executable file
14
bbfd/gitlab-ci/setup.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "preparation script"
|
||||
pwd
|
||||
|
||||
cp -r ./test/files/* /
|
||||
cp ./gitlab-ci/iopsys-supervisord.conf /etc/supervisor/conf.d/
|
||||
|
||||
ls /etc/config/
|
||||
ls /usr/share/rpcd/schemas/
|
||||
ls /etc/supervisor/conf.d/
|
||||
|
||||
supervisorctl shutdown
|
||||
supervisord -c /etc/supervisor/supervisord.conf
|
||||
44
bbfd/gitlab-ci/shared.sh
Normal file
44
bbfd/gitlab-ci/shared.sh
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
echo ""
|
||||
}
|
||||
|
||||
function check_ret()
|
||||
{
|
||||
ret=$1
|
||||
if [ "$ret" -ne 0 ]; then
|
||||
echo "Validation of last command failed, ret(${ret})"
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function error_on_zero()
|
||||
{
|
||||
ret=$1
|
||||
if [ "$ret" -eq 0 ]; then
|
||||
echo "Validation of last command failed, ret(${ret})"
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function exec_cmd()
|
||||
{
|
||||
echo "executing $@"
|
||||
$@ >/dev/null 2>&1
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to execute $@"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function generate_report()
|
||||
{
|
||||
exec_cmd tap-junit --name "${1}" --input "${2}" --output report
|
||||
sync
|
||||
}
|
||||
|
||||
22
bbfd/gitlab-ci/unit-test.sh
Executable file
22
bbfd/gitlab-ci/unit-test.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "preparation script"
|
||||
pwd
|
||||
source ./gitlab-ci/shared.sh
|
||||
|
||||
trap cleanup EXIT
|
||||
trap cleanup SIGINT
|
||||
|
||||
echo "Running the unit test cases"
|
||||
make clean
|
||||
make unit-test -C ./src/
|
||||
check_ret $?
|
||||
|
||||
#report part
|
||||
#GitLab-CI output
|
||||
gcovr -r .
|
||||
# Artefact
|
||||
gcovr -r . --xml -o ./unit-test-coverage.xml
|
||||
date +%s > timestamp.log
|
||||
|
||||
echo "Unit test PASS"
|
||||
43
bbfd/openwrt/uspd/Makefile
Normal file
43
bbfd/openwrt/uspd/Makefile
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=uspd
|
||||
PKG_VERSION:=1.0.5
|
||||
PKG_RELEASE:=$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/uspd.git
|
||||
PKG_SOURCE_VERSION=x
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
PKG_MAINTAINER:=IOPSYS Dev <dev@iopsys.eu>
|
||||
|
||||
CONFIG_SRC_TREE_OVERRIDE:=y
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/uspd
|
||||
SECTION:=iopsys
|
||||
CATEGORY:=IOPSYS
|
||||
TITLE:=USP ubus backend
|
||||
DEPENDS:=+libubox +ubus +libbbfdm
|
||||
endef
|
||||
|
||||
define Package/uspd/description
|
||||
Ubus based backend for TR-369/USP which can be used by other USP agents
|
||||
running on top of it.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
define Package/uspd/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_BIN) ./files/uspd.init $(1)/etc/init.d/uspd
|
||||
$(INSTALL_CONF) ./files/uspd.config $(1)/etc/config/uspd
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/uspd $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,uspd))
|
||||
2
bbfd/openwrt/uspd/files/uspd.config
Normal file
2
bbfd/openwrt/uspd/files/uspd.config
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
config uspd 'usp'
|
||||
option granularitylevel '0'
|
||||
25
bbfd/openwrt/uspd/files/uspd.init
Normal file
25
bbfd/openwrt/uspd/files/uspd.init
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=94
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/uspd
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command ${PROG}
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "cwmp"
|
||||
procd_add_config_trigger "config.change" "uspd" /etc/init.d/uspd restart
|
||||
}
|
||||
1
bbfd/openwrt/uspd/git-src
Symbolic link
1
bbfd/openwrt/uspd/git-src
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../.git/
|
||||
791
bbfd/schemas/ubus/usp.json
Normal file
791
bbfd/schemas/ubus/usp.json
Normal file
|
|
@ -0,0 +1,791 @@
|
|||
{
|
||||
"definitions": {
|
||||
"path_t": {
|
||||
"description": "Complete object element path as per TR181",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.1.",
|
||||
"Device.WiFi."
|
||||
]
|
||||
},
|
||||
"schema_path_t": {
|
||||
"description": "Datamodel object schema path",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.Bridging.Bridge.{i}.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.{i}.SSID"
|
||||
]
|
||||
},
|
||||
"boolean_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"0",
|
||||
"1"
|
||||
]
|
||||
},
|
||||
"operate_path_t": {
|
||||
"description": "Datamodel object schema path",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.DHCPv4.Client.{i}.Renew()",
|
||||
"Device.FactoryReset()"
|
||||
]
|
||||
},
|
||||
"operate_type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"query_path_t": {
|
||||
"description": "DM object path with search queries",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.[SSID==\"test_ssid\"].BSSID",
|
||||
"Device.WiFi.SSID.*.BSSID",
|
||||
"Device.WiFi.SSID.[SSID!=\"test_ssid\"&&Enable==1].BSSID",
|
||||
"Device.WiFi."
|
||||
]
|
||||
},
|
||||
"instance_t": {
|
||||
"description": "Multi object instances",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 256
|
||||
},
|
||||
"proto_t": {
|
||||
"type": "string",
|
||||
"default": "both",
|
||||
"enum": [
|
||||
"usp",
|
||||
"cwmp",
|
||||
"both"
|
||||
]
|
||||
},
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"xsd:string",
|
||||
"xsd:unsignedInt",
|
||||
"xsd:int",
|
||||
"xsd:unsignedLong",
|
||||
"xsd:long",
|
||||
"xsd:boolean",
|
||||
"xsd:dateTime",
|
||||
"xsd:hexBinary",
|
||||
"xsd:object"
|
||||
]
|
||||
},
|
||||
"fault_t": {
|
||||
"type": "integer",
|
||||
"minimum": 7000,
|
||||
"maximum": 9050
|
||||
}
|
||||
},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://dev.iopsys.eu/iopsys/uspd/-/blob/devel/docs/api/usp.md",
|
||||
"type": "object",
|
||||
"title": "usp",
|
||||
"object": "usp",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"get_supported_dm": {
|
||||
"title": "Get list of supported datamodel parameters",
|
||||
"description": "Schema will have all the nodes/objects supported by libbbf",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"schema_type": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 3,
|
||||
"description": "0-All, 1-Parameter only 2- Event only 3- operate only"
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"oneof": [
|
||||
{
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t",
|
||||
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"type",
|
||||
"writable"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/schema_path_t"
|
||||
},
|
||||
"writable": {
|
||||
"$ref": "#/definitions/boolean_t"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/type_t"
|
||||
},
|
||||
"cmd_type": {
|
||||
"$ref": "#/definitions/operate_type_t"
|
||||
},
|
||||
"in": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"out": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"list_operate": {
|
||||
"title": "List down supported usp operate commands",
|
||||
"description": "Commands will be shown in schema format",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/operate_path_t"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/operate_type_t"
|
||||
},
|
||||
"in": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"out": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"title": "Get handler",
|
||||
"description": "Query the datamodel object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"maxdepth": {
|
||||
"type": "integer",
|
||||
"description": "Integer to decide the depth of data model to be parsed"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"oneof": [
|
||||
{
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t",
|
||||
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code in fault_t"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"examples": [
|
||||
"root@iopsys:/tmp# ubus call usp get '{\"path\":\"Device.Users.User.2.\"}'\n{\n\t\"User\": [\n\t\t{\n\t\t\t\"Alias\": \"\",\n\t\t\t\"Enable\": true,\n\t\t\t\"Language\": \"\",\n\t\t\t\"Password\": \"\",\n\t\t\t\"RemoteAccessCapable\": false,\n\t\t\t\"Username\": \"user_2\"\n\t\t}\n\t]\n}",
|
||||
"root@iopsys:/tmp# ubus call usp get '{\"path\":\"Device.Users.\"}'\n{\n\t\"Users\": {\n\t\t\"User\": [\n\t\t\t{\n\t\t\t\t\"Alias\": \"\",\n\t\t\t\t\"Enable\": true,\n\t\t\t\t\"Language\": \"\",\n\t\t\t\t\"Password\": \"\",\n\t\t\t\t\"RemoteAccessCapable\": true,\n\t\t\t\t\"Username\": \"user\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"Alias\": \"\",\n\t\t\t\t\"Enable\": true,\n\t\t\t\t\"Language\": \"\",\n\t\t\t\t\"Password\": \"\",\n\t\t\t\t\"RemoteAccessCapable\": false,\n\t\t\t\t\"Username\": \"user_2\"\n\t\t\t}\n\t\t],\n\t\t\"UserNumberOfEntries\": 2\n\t}\n}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
"title": "Set handler",
|
||||
"description": "Set values of datamodel object element",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"value": {
|
||||
"description": "value of the object element provided in path, path should contains valid writable object element",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"{\"path\":\"Device.WiFi.SSID.1.SSID\", \"value\":\"test_ssid\"}",
|
||||
"{\"path\":\"Device.WiFi.SSID.2.Enable\", \"value\":\"true\"}",
|
||||
"{\"path\":\"Device.WiFi.SSID.1.Enable\", \"value\":\"0\"}"
|
||||
]
|
||||
},
|
||||
"values": {
|
||||
"description": "To set multiple values at once, path should be relative to object elements",
|
||||
"examples": [
|
||||
"{\"path\":\"Device.WiFi.SSID.1\", \"values\":{\".SSID\":\"test_ssid\",\".Name\":\"test_name\"}}",
|
||||
"{\"path\":\"Device.WiFi.SSID.2\", \"values\":{\".SSID\":\"test_ssid\"}}"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"oneof": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"const": "0"
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"add_object": {
|
||||
"title": "Add a new object instance",
|
||||
"description": "Add a new object in multi instance object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"instance": {
|
||||
"type": "string"
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"del_object": {
|
||||
"title": "Delete object instance",
|
||||
"description": "Delete a object instance from multi instance object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"title": "Validate a datamodel object",
|
||||
"description": "API to check if a datamodel object is available",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"maxdepth": {
|
||||
"type": "integer",
|
||||
"description": "Integer to decide the depth of data model to be parsed"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"type": "string"
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"instances": {
|
||||
"title": "Instance query handler",
|
||||
"description": "Get the instances of multi object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"maxdepth": {
|
||||
"type": "integer",
|
||||
"description": "Integer to decide the depth of data model to be parsed"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"oneof": [
|
||||
{
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t",
|
||||
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code in fault_t"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/instance_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"object_names": {
|
||||
"title": "Get objects names",
|
||||
"description": "Get names of all the objects below input object path",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"maxdepth": {
|
||||
"type": "integer",
|
||||
"description": "Integer to decide the depth of data model to be parsed"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"oneof": [
|
||||
{
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t",
|
||||
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code in fault_t"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": {
|
||||
"$ref": "#/definitions/type_t"
|
||||
},
|
||||
"required": [
|
||||
"parameter",
|
||||
"type",
|
||||
"writable"
|
||||
],
|
||||
"writable": {
|
||||
"$ref": "#/definitions/boolean_t"
|
||||
},
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"operate": {
|
||||
"title": "Operate handler",
|
||||
"description": "Operate on object element provided in path",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path",
|
||||
"action"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
},
|
||||
"action": {
|
||||
"description": "Opreate command as defined in TR-369, TR-181-2.13",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"{\"path\":\"Device.WiFi.\", \"action\":\"Reset\\(\\)\"}"
|
||||
],
|
||||
"pattern": "[a-zA-Z]+\\(\\)"
|
||||
},
|
||||
"input": {
|
||||
"description": "Input arguments for the operate command as defined in TR-181-2.13",
|
||||
"examples": [
|
||||
"{\"path\":\"Device.IP.Diagnostics\", \"action\":\"IPPing\\(\\)\", \"input\":{\"Host\":\"iopsys.eu\"}}"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"oneof": [
|
||||
{
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t",
|
||||
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code in fault_t"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Output will have status for sync commands and for async commands parameters as defined in TR-181-2.13",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"Results"
|
||||
],
|
||||
"properties": {
|
||||
"Results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"result": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string",
|
||||
"Description": "Success or Failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
"{\n\t\"status\": true}",
|
||||
"{\n\t\"AverageResponseTime\": \"0\",\n\t\"AverageResponseTimeDetailed\": \"130\",\n\t\"FailureCount\": \"0\",\n\t\"MaximumResponseTime\": \"0\",\n\t\"MaximumResponseTimeDetailed\": \"140\",\n\t\"MinimumResponseTime\": \"0\",\n\t\"MinimumResponseTimeDetailed\": \"120\",\n\t\"SuccessCount\": \"3\"}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1420
bbfd/schemas/ubus/usp.raw.json
Normal file
1420
bbfd/schemas/ubus/usp.raw.json
Normal file
File diff suppressed because it is too large
Load diff
74
bbfd/schemas/uci/uspd.json
Normal file
74
bbfd/schemas/uci/uspd.json
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"uspd": [
|
||||
{
|
||||
"section": "uspd",
|
||||
"description": "USP daemon Settings",
|
||||
"multi": false,
|
||||
"options": [
|
||||
{
|
||||
"name": "granularitylevel",
|
||||
"type": "integer",
|
||||
"required": "no",
|
||||
"default": "0",
|
||||
"description": "Creates ubus objects along with object names, depth of object name depends on granularitylevel"
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"type": "boolean",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"description": "Enabled debug logging"
|
||||
},
|
||||
{
|
||||
"name": "sock",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"description": "Path for ubus socket to register uspd services"
|
||||
},
|
||||
{
|
||||
"name": "transaction_timeout",
|
||||
"type": "integer",
|
||||
"required": "no",
|
||||
"default": "10",
|
||||
"description": "Transaction timeout value in seconds"
|
||||
},
|
||||
{
|
||||
"name": "loglevel",
|
||||
"type": "integer",
|
||||
"required": "no",
|
||||
"default": "1",
|
||||
"description": "Internal loglevel for debugging {0: No Logs; 1: Errors only; 2: Errors and warnings; 3: Error, warning and info; 4: Everything}"
|
||||
},
|
||||
{
|
||||
"name": "subprocess_level",
|
||||
"type": "integer",
|
||||
"required": "no",
|
||||
"default": "2",
|
||||
"description": "This parameter configures when subprocess can be used for get operation. Level here denotes the Datamodel object depth up-to which subprocess will be used to collect the get data. For example, if this is configured to 1, then only get for 'Device.' shall be called within the subprocess. If configured as level 2, then all the get with up-to depth 2 like 'Device.WiFi.', 'Device.IP.' shall be called in subprocess."
|
||||
},
|
||||
{
|
||||
"name": "bbf_caching_time",
|
||||
"type": "integer",
|
||||
"required": "no",
|
||||
"default": "0",
|
||||
"description": "Max caching time in seconds for ubus output used in datamodel parameters. If not configured, output shall be cleared end the end of call."
|
||||
},
|
||||
{
|
||||
"name": "dm_version",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"description": "Configures the datamodel version to use for datamodel parameters, if not configured show all defined datamodel"
|
||||
},
|
||||
{
|
||||
"name": "refresh_time",
|
||||
"type": "integer",
|
||||
"required": "no",
|
||||
"default": "5",
|
||||
"description": "The time period in seconds after which uspd will refresh the datamodel instances in a periodic manner. If configured to '0' then instance updater will be disabled. If not configured at all then after every 5 seconds datamodel instances will be refreshed."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
58
bbfd/src/Makefile
Normal file
58
bbfd/src/Makefile
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
PROG = uspd
|
||||
OBJS =common.o get.o get_helper.o set.o operate.o add_delete.o pretty_print.o usp.o events.o
|
||||
CP=cp -f
|
||||
|
||||
PROG_CFLAGS = $(CFLAGS) \
|
||||
-fstrict-aliasing \
|
||||
-Wall -Wextra -Werror \
|
||||
-Wformat \
|
||||
-Wformat-signedness -fPIC
|
||||
|
||||
PROG_LDFLAGS = $(LDFLAGS)
|
||||
PROG_LDFLAGS += -luci -lubus -lubox -ljson-c -lblobmsg_json -lbbfdm
|
||||
|
||||
ifeq ($(USE_MBEDTLS),yes)
|
||||
PROG_LDFLAGS += -lmbedcrypto -lmbedtls
|
||||
endif
|
||||
|
||||
ifeq ($(USE_OPENSSL),yes)
|
||||
PROG_LDFLAGS += -lssl -lcrypto
|
||||
endif
|
||||
|
||||
ifeq ($(USE_WOLFSSL),yes)
|
||||
PROG_LDFLAGS += -lwolfssl
|
||||
endif
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(PROG_CFLAGS) -c -o $@ $<
|
||||
|
||||
all: ${PROG}
|
||||
|
||||
${PROG}: $(OBJS)
|
||||
$(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS)
|
||||
$(CP) ${PROG} ../${PROG}
|
||||
|
||||
test: PROG_CFLAGS += -fPIC
|
||||
test: ${OBJS}
|
||||
${CC} $(PROG_CFLAGS) -shared -o libuspd.so ${OBJS} $(PROG_LDFLAGS)
|
||||
$(CP) libuspd.so ../libuspd.so
|
||||
|
||||
unit-test: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage
|
||||
unit-test: LDFLAGS += --coverage
|
||||
unit-test: clean_objs
|
||||
unit-test: test
|
||||
make -C ../test/cmocka unit-test USPD_LIB_DIR=$(PWD)
|
||||
|
||||
func-test: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage
|
||||
func-test: LDFLAGS += --coverage
|
||||
func-test: clean_objs
|
||||
func-test: ${PROG}
|
||||
|
||||
clean_objs:
|
||||
rm -f *.o
|
||||
clean:
|
||||
rm -f *.o libuspd.so $(PROG)
|
||||
rm -f *.xml *.html
|
||||
find -name '*.gcda' -exec rm {} -fv \;
|
||||
find -name '*.gcno' -exec rm {} -fv \;
|
||||
find -name '*.gcov' -exec rm {} -fv \;
|
||||
77
bbfd/src/add_delete.c
Normal file
77
bbfd/src/add_delete.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* add_delete.c: Add/Delete handler for uspd
|
||||
*
|
||||
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "add_delete.h"
|
||||
#include "get_helper.h"
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
|
||||
typedef int (*ADD_DEL_CB_T)(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey);
|
||||
|
||||
static int handle_add_del_req(usp_data_t *data, struct blob_buf *bb, ADD_DEL_CB_T req_cb)
|
||||
{
|
||||
int fault = 0;
|
||||
struct dmctx bbf_ctx;
|
||||
LIST_HEAD(resolved_paths);
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
fault = get_resolved_paths(&bbf_ctx, data->qpath, &resolved_paths);
|
||||
if (fault) {
|
||||
fill_resolve_err(bb, data->qpath, fault);
|
||||
} else {
|
||||
struct pathNode *p;
|
||||
void *array;
|
||||
|
||||
array = blobmsg_open_array(bb, "parameters");
|
||||
list_for_each_entry(p, &resolved_paths, list) {
|
||||
void *table = blobmsg_open_table(bb, NULL);
|
||||
int op_fault;
|
||||
|
||||
op_fault = req_cb(&bbf_ctx, bb, p->path, data->set_key);
|
||||
blobmsg_close_table(bb, table);
|
||||
// Preserve the first error
|
||||
if (fault == USP_ERR_OK && op_fault != USP_ERR_OK)
|
||||
fault = op_fault;
|
||||
}
|
||||
blobmsg_close_array(bb, array);
|
||||
}
|
||||
|
||||
// Free
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
free_path_list(&resolved_paths);
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
||||
int create_add_response(usp_data_t *data, struct blob_buf *bb)
|
||||
{
|
||||
return handle_add_del_req(data, bb, &usp_add_object);
|
||||
}
|
||||
|
||||
int create_del_response(usp_data_t *data, struct blob_buf *bb)
|
||||
{
|
||||
return handle_add_del_req(data, bb, &usp_del_object);
|
||||
}
|
||||
23
bbfd/src/add_delete.h
Normal file
23
bbfd/src/add_delete.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef ADD_DEL_H
|
||||
#define ADD_DEL_H
|
||||
|
||||
#include "usp.h"
|
||||
|
||||
enum {
|
||||
DM_ADD_PATH,
|
||||
DM_ADD_PROTO,
|
||||
DM_ADD_INSTANCE,
|
||||
__DM_ADD_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_RAW_ADD_PATH,
|
||||
DM_RAW_ADD_PROTO,
|
||||
DM_RAW_ADD_INSTANCE,
|
||||
DM_RAW_ADD_TRANS_ID,
|
||||
__DM_RAW_ADD_MAX
|
||||
};
|
||||
|
||||
int create_add_response(usp_data_t *data, struct blob_buf *bb);
|
||||
int create_del_response(usp_data_t *data, struct blob_buf *bb);
|
||||
#endif /* ADD_DEL_H */
|
||||
210
bbfd/src/common.c
Normal file
210
bbfd/src/common.c
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* common.c: Common utils of Get/Set/Operate handlers
|
||||
*
|
||||
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
#include "ipc.h"
|
||||
#include "get_helper.h"
|
||||
|
||||
#define DEFAULT_LOG_LEVEL (2)
|
||||
|
||||
static unsigned char gLogLevel = DEFAULT_LOG_LEVEL;
|
||||
|
||||
// Logging utilities
|
||||
void set_debug_level(unsigned char level)
|
||||
{
|
||||
gLogLevel = level;
|
||||
}
|
||||
|
||||
void print_error(const char *format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
if (gLogLevel < 1)
|
||||
return;
|
||||
|
||||
va_start(arglist, format);
|
||||
vsyslog(LOG_ERR, format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
void print_warning(const char *format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
if (gLogLevel < 2)
|
||||
return;
|
||||
|
||||
va_start(arglist, format);
|
||||
vsyslog(LOG_WARNING, format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
void print_info(const char *format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
if (gLogLevel < 3)
|
||||
return;
|
||||
|
||||
va_start(arglist, format);
|
||||
vsyslog(LOG_INFO, format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
void print_debug(const char *format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
if (gLogLevel < 4)
|
||||
return;
|
||||
|
||||
va_start(arglist, format);
|
||||
vsyslog(LOG_DEBUG, format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
|
||||
bool is_str_eq(const char *s1, const char *s2)
|
||||
{
|
||||
if (strcmp(s1, s2) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_boolean_string(char *value)
|
||||
{
|
||||
if (!value)
|
||||
return false;
|
||||
|
||||
if (strncasecmp(value, "true", 4) == 0 ||
|
||||
value[0] == '1' ||
|
||||
strncasecmp(value, "on", 2) == 0 ||
|
||||
strncasecmp(value, "yes", 3) == 0 ||
|
||||
strncasecmp(value, "enabled", 7) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_node_instance(char *path)
|
||||
{
|
||||
bool ret = false;
|
||||
char *rb = NULL;
|
||||
|
||||
DEBUG("entry |%s|", path);
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
if (path[0] == '[') {
|
||||
char temp_char[MAX_DM_KEY_LEN] = {'\0'};
|
||||
size_t shift;
|
||||
|
||||
rb = strchr(path, ']');
|
||||
shift = (size_t) labs(rb - path);
|
||||
strncpyt(temp_char, path, shift + 1);
|
||||
if (!match(temp_char, GLOB_EXPR))
|
||||
ret = true;
|
||||
} else {
|
||||
if (strtol(path, NULL, 10))
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool get_uci_option_string(char *package, char *section,
|
||||
char *option, char **value)
|
||||
{
|
||||
struct uci_context *uci_ctx;
|
||||
struct uci_ptr ptr = {0};
|
||||
bool ret = true;
|
||||
|
||||
*value = NULL;
|
||||
uci_ctx = uci_alloc_context();
|
||||
|
||||
if (!uci_ctx)
|
||||
return false;
|
||||
|
||||
if (bbfdmuci_lookup_ptr(uci_ctx, &ptr, package, section, option, NULL)) {
|
||||
*value = NULL;
|
||||
ret = false;
|
||||
} else if (ptr.o && ptr.o->v.string) {
|
||||
*value = strdup(ptr.o->v.string);
|
||||
} else {
|
||||
*value = NULL;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
uci_free_context(uci_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// RE utilities
|
||||
bool match(const char *string, const char *pattern)
|
||||
{
|
||||
int status;
|
||||
regex_t re;
|
||||
|
||||
if (regcomp(&re, pattern, REG_EXTENDED) != 0)
|
||||
return 0;
|
||||
|
||||
status = regexec(&re, string, 0, NULL, 0);
|
||||
regfree(&re);
|
||||
if (status != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int count_delim(const char *path)
|
||||
{
|
||||
int count = 0;
|
||||
char *token, *save;
|
||||
char *pp = strdup(path);
|
||||
|
||||
token = strtok_r(pp, ".", &save);
|
||||
while (token) {
|
||||
token = strtok_r(NULL, ".", &save);
|
||||
count++;
|
||||
}
|
||||
free(pp);
|
||||
|
||||
// count is the count of tokens
|
||||
return (count - 1);
|
||||
}
|
||||
|
||||
bool validate_msglen(struct blob_buf *bb)
|
||||
{
|
||||
size_t data_len = blob_pad_len(bb->head);
|
||||
|
||||
if (data_len >= DEF_IPC_DATA_LEN) {
|
||||
ERR("Blob exceed max len(%zd), data len(%zd)", DEF_IPC_DATA_LEN, data_len);
|
||||
blob_buf_free(bb);
|
||||
blob_buf_init(bb, 0);
|
||||
fill_err_code(bb, FAULT_9002);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
73
bbfd/src/common.h
Normal file
73
bbfd/src/common.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <syslog.h>
|
||||
#include <regex.h>
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libubox/blobmsg.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
#include <libubox/utils.h>
|
||||
#include <libubox/list.h>
|
||||
|
||||
#define ROOT_NODE "Device."
|
||||
#define USP "usp"
|
||||
#define USPRAW "usp.raw"
|
||||
#define USPEXT "usp.Device."
|
||||
#define USP_ADD_EVENT "usp.AddObj"
|
||||
#define USP_DEL_EVENT "usp.DelObj"
|
||||
|
||||
#define MAX_DM_KEY_LEN 256
|
||||
#define MAX_DM_PATH 1024
|
||||
#define MAX_DM_VALUE 4096
|
||||
#define DM_VALUE_SEP ","
|
||||
#define DELIM '.'
|
||||
|
||||
#define GLOB_CHAR "[[+*]+"
|
||||
#define GLOB_EXPR "[=><]+"
|
||||
#define GLOB_USP_PATH "[+#=><]+"
|
||||
|
||||
#define USP_ERR_OK 0
|
||||
|
||||
bool match(const char *string, const char *pattern);
|
||||
bool is_str_eq(const char *s1, const char *s2);
|
||||
bool is_node_instance(char *path);
|
||||
int count_delim(const char *path);
|
||||
bool get_uci_option_string(char *package, char *section,
|
||||
char *option, char **value);
|
||||
|
||||
void set_debug_level(unsigned char level);
|
||||
void print_error(const char *format, ...);
|
||||
void print_warning(const char *format, ...);
|
||||
void print_info(const char *format, ...);
|
||||
void print_debug(const char *format, ...);
|
||||
bool get_boolean_string(char *value);
|
||||
bool validate_msglen(struct blob_buf *bb);
|
||||
|
||||
|
||||
#define DEBUG(fmt, args...) \
|
||||
print_debug("[%s:%d]"fmt, __func__, __LINE__, ##args)
|
||||
|
||||
#define INFO(fmt, args...) \
|
||||
print_info(fmt, ##args)
|
||||
|
||||
#define ERR(fmt, args...) \
|
||||
print_error("[%s:%d] " fmt, __func__, __LINE__, ##args)
|
||||
|
||||
#define WARNING(fmt, args...) \
|
||||
print_warning("[%s:%d] " fmt, __func__, __LINE__, ##args)
|
||||
|
||||
// glibc doesn't guarantee a 0 termianted string on strncpy
|
||||
// strncpy with always 0 terminated string
|
||||
static inline void strncpyt(char *dst, const char *src, size_t n)
|
||||
{
|
||||
if (n > 1) {
|
||||
strncpy(dst, src, n - 1);
|
||||
dst[n - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* COMMON_H */
|
||||
267
bbfd/src/events.c
Normal file
267
bbfd/src/events.c
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* events.c: Handler to generate usp events on ubus
|
||||
*
|
||||
* Copyright (C) 2021 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "events.h"
|
||||
#include "get_helper.h"
|
||||
#include <libbbfdm/dmentry.h>
|
||||
#include <libubus.h>
|
||||
|
||||
static struct event_map_list ev_map_list[] = {
|
||||
/* { event name, DM Path, .arguments[] = { event_args, dm_args } } */
|
||||
{ "wifi.dataelements.Associated", "Device.WiFi.DataElements.AssociationEvent.Associated!",
|
||||
.args = {
|
||||
{ "eventTime", "TimeStamp" },
|
||||
{ "wfa-dataelements:AssociationEvent.AssocData.BSSID", "BSSID" },
|
||||
{ "wfa-dataelements:AssociationEvent.AssocData.MACAddress", "MACAddress" },
|
||||
{ "wfa-dataelements:AssociationEvent.AssocData.StatusCode", "StatusCode" },
|
||||
{ "wfa-dataelements:AssociationEvent.AssocData.HTCapabilities", "HTCapabilities" },
|
||||
{ "wfa-dataelements:AssociationEvent.AssocData.VHTCapabilities", "VHTCapabilities" },
|
||||
{ "wfa-dataelements:AssociationEvent.AssocData.HECapabilities", "HECapabilities" },
|
||||
{0}
|
||||
}
|
||||
},
|
||||
{ "wifi.dataelements.Disassociated", "Device.WiFi.DataElements.DisassociationEvent.Disassociated!",
|
||||
.args = {
|
||||
{ "eventTime", "TimeStamp" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.BSSID", "BSSID" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.MACAddress", "MACAddress" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.ReasonCode", "ReasonCode" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.BytesSent", "BytesSent" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.BytesReceived", "BytesReceived" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.PacketsSent", "PacketsSent" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.PacketsReceived", "PacketsReceived" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.ErrorsSent", "ErrorsSent" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.ErrorsReceived", "ErrorsReceived" },
|
||||
{ "wfa-dataelements:DisassociationEvent.DisassocData.RetransCount", "RetransCount" },
|
||||
{0}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static char* get_events_dm_path(const char *event)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!event) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(ev_map_list)/sizeof(ev_map_list[0]); i++) {
|
||||
if (strcmp(event, ev_map_list[i].event) == 0)
|
||||
return ev_map_list[i].dm_path;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct event_args_list* get_events_args(const char *event)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!event) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(ev_map_list)/sizeof(ev_map_list[0]); i++) {
|
||||
if (strcmp(event, ev_map_list[i].event) == 0)
|
||||
return ev_map_list[i].args;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void serialize_blob_msg(struct blob_attr *msg, char *node, struct list_head *pv_list)
|
||||
{
|
||||
struct blob_attr *attr;
|
||||
size_t rem;
|
||||
|
||||
blobmsg_for_each_attr(attr, msg, rem) {
|
||||
char path[MAX_DM_PATH], value[MAX_DM_VALUE];
|
||||
|
||||
snprintf(path, sizeof(path), "%s%s%s",
|
||||
DM_STRLEN(node) ? node : "",
|
||||
blobmsg_name(attr),
|
||||
(blobmsg_type(attr) == BLOBMSG_TYPE_TABLE && DM_STRLEN(blobmsg_name(attr))) ? "." : "");
|
||||
|
||||
switch (blobmsg_type(attr)) {
|
||||
case BLOBMSG_TYPE_STRING:
|
||||
snprintf(value, MAX_DM_VALUE, "%s", blobmsg_get_string(attr));
|
||||
add_pv_node(path, value, NULL, pv_list);
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT8:
|
||||
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u8(attr));
|
||||
add_pv_node(path, value, NULL, pv_list);
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT16:
|
||||
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u16(attr));
|
||||
add_pv_node(path, value, NULL, pv_list);
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT32:
|
||||
snprintf(value, MAX_DM_VALUE, "%u", blobmsg_get_u32(attr));
|
||||
add_pv_node(path, value, NULL, pv_list);
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT64:
|
||||
snprintf(value, MAX_DM_VALUE, "%"PRIu64"", blobmsg_get_u64(attr));
|
||||
add_pv_node(path, value, NULL, pv_list);
|
||||
break;
|
||||
case BLOBMSG_TYPE_TABLE:
|
||||
serialize_blob_msg(attr, path, pv_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *get_dm_arg_value(const char *event_arg, struct list_head *pv_list)
|
||||
{
|
||||
struct pvNode *pv = NULL;
|
||||
|
||||
list_for_each_entry(pv, pv_list, list) {
|
||||
if (strcmp(pv->param, event_arg) == 0)
|
||||
return pv->val;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void generate_blob_input(struct blob_buf *b, const char *type, struct list_head *pv_list)
|
||||
{
|
||||
struct event_args_list *args = get_events_args(type);
|
||||
if (args == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 0; args[i].event_arg; i++) {
|
||||
char *dm_arg = get_dm_arg_value(args[i].event_arg, pv_list);
|
||||
blobmsg_add_string(b, args[i].dm_arg, dm_arg ? dm_arg : "");
|
||||
}
|
||||
}
|
||||
|
||||
static void uspd_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev,
|
||||
const char *type, struct blob_attr *msg)
|
||||
{
|
||||
(void)ev;
|
||||
|
||||
if (!msg || !type)
|
||||
return;
|
||||
|
||||
char *dm_path = get_events_dm_path(type);
|
||||
if (dm_path == NULL)
|
||||
return;
|
||||
|
||||
LIST_HEAD(pv_list);
|
||||
|
||||
serialize_blob_msg(msg, "", &pv_list);
|
||||
|
||||
struct blob_buf b, bb;
|
||||
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
blobmsg_add_string(&b, "name", dm_path);
|
||||
generate_blob_input(&bb, type, &pv_list);
|
||||
blobmsg_add_field(&b, BLOBMSG_TYPE_TABLE, "input", blob_data(bb.head), blob_len(bb.head));
|
||||
ubus_send_event(ctx, "usp.event", b.head);
|
||||
|
||||
blob_buf_free(&bb);
|
||||
blob_buf_free(&b);
|
||||
free_pv_list(&pv_list);
|
||||
}
|
||||
|
||||
static void add_ubus_event_handler(struct ubus_event_handler *ev, struct list_head *ev_list)
|
||||
{
|
||||
if (ev == NULL || ev_list == NULL)
|
||||
return;
|
||||
|
||||
struct ev_handler_node *node = NULL;
|
||||
node = (struct ev_handler_node *) malloc(sizeof(struct ev_handler_node));
|
||||
|
||||
if (!node) {
|
||||
ERR("Out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
node->ev_handler = ev;
|
||||
INIT_LIST_HEAD(&node->list);
|
||||
list_add_tail(&node->list, ev_list);
|
||||
}
|
||||
|
||||
void list_event_schema(struct blob_buf *bb)
|
||||
{
|
||||
bbf_dm_get_supported_dm(bb, ROOT_NODE, false, EVENT_ONLY);
|
||||
}
|
||||
|
||||
bool is_registered_event(char *name)
|
||||
{
|
||||
return bbf_dm_event_registered(name);
|
||||
}
|
||||
|
||||
void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list)
|
||||
{
|
||||
struct ev_handler_node *iter = NULL, *node = NULL;
|
||||
|
||||
if (ctx == NULL || ev_list == NULL)
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(iter, node, ev_list, list) {
|
||||
if (iter->ev_handler != NULL) {
|
||||
ubus_unregister_event_handler(ctx, iter->ev_handler);
|
||||
free(iter->ev_handler);
|
||||
}
|
||||
|
||||
list_del(&iter->list);
|
||||
free(iter);
|
||||
}
|
||||
}
|
||||
|
||||
int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (ctx == NULL || ev_list == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < sizeof(ev_map_list)/sizeof(ev_map_list[0]); i++) {
|
||||
if (ev_map_list[i].event == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct ubus_event_handler *ev = (struct ubus_event_handler *)malloc(sizeof(struct ubus_event_handler));
|
||||
if (!ev) {
|
||||
ERR("Out of memory!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(ev, 0, sizeof(struct ubus_event_handler));
|
||||
ev->cb = uspd_event_handler;
|
||||
|
||||
if (0 != ubus_register_event_handler(ctx, ev, ev_map_list[i].event)) {
|
||||
ERR("Failed to register: %s", ev_map_list[i].event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
add_ubus_event_handler(ev, ev_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
23
bbfd/src/events.h
Normal file
23
bbfd/src/events.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
|
||||
#include "usp.h"
|
||||
#include "common.h"
|
||||
|
||||
struct event_args_list {
|
||||
char *event_arg;
|
||||
char *dm_arg;
|
||||
};
|
||||
|
||||
struct event_map_list {
|
||||
char *event;
|
||||
char *dm_path;
|
||||
struct event_args_list args[16];
|
||||
};
|
||||
|
||||
void list_event_schema(struct blob_buf *bb);
|
||||
bool is_registered_event(char *name);
|
||||
void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list);
|
||||
int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list);
|
||||
|
||||
#endif /* EVENT_H */
|
||||
306
bbfd/src/get.c
Normal file
306
bbfd/src/get.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* get.c: Get handler for uspd
|
||||
*
|
||||
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "get.h"
|
||||
#include "get_helper.h"
|
||||
#include "pretty_print.h"
|
||||
#include "ipc.h"
|
||||
#include <libubus.h>
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
|
||||
void init_dmmap(void)
|
||||
{
|
||||
struct dmctx bbf_ctx;
|
||||
LIST_HEAD(resolved_list);
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER);
|
||||
|
||||
get_resolved_paths(&bbf_ctx, ROOT_NODE, &resolved_list);
|
||||
|
||||
// Commit dmmap
|
||||
bbf_uci_commit_bbfdm();
|
||||
|
||||
free_path_list(&resolved_list);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void usp_get_value_async(usp_data_t *data, void *output)
|
||||
{
|
||||
struct blob_buf bb;
|
||||
int fault = USP_ERR_OK;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
LIST_HEAD(resolved_list);
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
// Fill the blob_buf for sharing the result
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
INFO("Preparing result for(%s)", data->qpath);
|
||||
|
||||
fault = get_resolved_paths(&bbf_ctx, data->qpath, &resolved_list);
|
||||
if (fault) {
|
||||
fill_err_code(&bb, fault);
|
||||
} else {
|
||||
if (data->is_raw)
|
||||
prepare_result_raw(&bb, &bbf_ctx, &resolved_list);
|
||||
else
|
||||
prepare_pretty_result(data->depth, data->qpath, &bb, &bbf_ctx, &resolved_list);
|
||||
}
|
||||
|
||||
if (!validate_msglen(&bb)) {
|
||||
ERR("IPC failed for path(%s)", data->qpath);
|
||||
}
|
||||
|
||||
memcpy(output, bb.head, blob_pad_len(bb.head));
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
free_path_list(&resolved_list);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void usp_get_value(usp_data_t *data)
|
||||
{
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
struct blob_buf bb;
|
||||
int fault = USP_ERR_OK;
|
||||
char *qpath;
|
||||
bool raw;
|
||||
uint8_t depth;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
ctx = data->ctx;
|
||||
req = data->req;
|
||||
qpath = data->qpath;
|
||||
raw = data->is_raw;
|
||||
depth = data->depth;
|
||||
|
||||
LIST_HEAD(resolved_list);
|
||||
|
||||
// Fill the blob_buf for sharing the result
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
fault = get_resolved_paths(&bbf_ctx, qpath, &resolved_list);
|
||||
|
||||
INFO("Preparing result for(%s), fault(%d)", qpath, fault);
|
||||
if (fault) {
|
||||
fill_err_code(&bb, fault);
|
||||
} else {
|
||||
if (raw)
|
||||
prepare_result_raw(&bb, &bbf_ctx, &resolved_list);
|
||||
else
|
||||
prepare_pretty_result(depth, qpath, &bb, &bbf_ctx, &resolved_list);
|
||||
}
|
||||
|
||||
if (!validate_msglen(&bb)) {
|
||||
ERR("IPC failed for path(%s)", data->qpath);
|
||||
}
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
|
||||
// Apply all bbfdm changes
|
||||
if (is_transaction_running() == false)
|
||||
bbf_uci_commit_bbfdm();
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
free_path_list(&resolved_list);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void usp_validate_path(usp_data_t *data)
|
||||
{
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
struct blob_buf bb;
|
||||
int fault = USP_ERR_OK;
|
||||
char *qpath;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
ctx = data->ctx;
|
||||
req = data->req;
|
||||
qpath = data->qpath;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
fault = bbf_dm_get_names(&bbf_ctx, qpath, data->next_level);
|
||||
if (!list_empty(&bbf_ctx.list_parameter)) {
|
||||
size_t len = DM_STRLEN(qpath);
|
||||
|
||||
if (len > 0) {
|
||||
if (qpath[len - 1] == '.')
|
||||
qpath[len - 1] = '\0';
|
||||
blobmsg_add_string(&bb, "parameter", qpath);
|
||||
}
|
||||
}
|
||||
|
||||
if (fault)
|
||||
fill_err_code(&bb, fault);
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
|
||||
// Apply all bbfdm changes
|
||||
if (is_transaction_running() == false)
|
||||
bbf_uci_commit_bbfdm();
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void usp_get_instance(usp_data_t *data)
|
||||
{
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
struct blob_buf bb;
|
||||
int fault = USP_ERR_OK;
|
||||
char *qpath;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
ctx = data->ctx;
|
||||
req = data->req;
|
||||
qpath = data->qpath;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
fault = bbf_dm_get_instances(&bbf_ctx, qpath, data->next_level);
|
||||
|
||||
if (fault) {
|
||||
fill_err_code(&bb, fault);
|
||||
} else {
|
||||
struct dm_parameter *n;
|
||||
void *array;
|
||||
|
||||
array = blobmsg_open_array(&bb, "parameters");
|
||||
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
|
||||
void *table = blobmsg_open_table(&bb, NULL);
|
||||
|
||||
blobmsg_add_string(&bb, "parameter", n->name);
|
||||
blobmsg_close_table(&bb, table);
|
||||
}
|
||||
blobmsg_close_array(&bb, array);
|
||||
}
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
|
||||
// Apply all bbfdm changes
|
||||
if (is_transaction_running() == false)
|
||||
bbf_uci_commit_bbfdm();
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void usp_get_name(usp_data_t *data)
|
||||
{
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
struct blob_buf bb;
|
||||
int fault;
|
||||
char *qpath;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
ctx = data->ctx;
|
||||
req = data->req;
|
||||
qpath = data->qpath;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
fault = bbf_dm_get_names(&bbf_ctx, qpath, data->next_level);
|
||||
if (fault) {
|
||||
fill_err_code(&bb, fault);
|
||||
} else {
|
||||
void *array;
|
||||
struct dm_parameter *n;
|
||||
|
||||
array = blobmsg_open_array(&bb, "parameters");
|
||||
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
|
||||
void *table = blobmsg_open_table(&bb, NULL);
|
||||
|
||||
blobmsg_add_string(&bb, "parameter", n->name);
|
||||
blobmsg_add_string(&bb, "writable", n->data);
|
||||
blobmsg_add_string(&bb, "type", n->type);
|
||||
blobmsg_close_table(&bb, table);
|
||||
}
|
||||
blobmsg_close_array(&bb, array);
|
||||
}
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
|
||||
// Commit all bbfdm changes if transaction is not in progress
|
||||
if (is_transaction_running() == false)
|
||||
bbf_uci_commit_bbfdm();
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void get_mpath(usp_data_t *data)
|
||||
{
|
||||
struct blob_buf bb;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
if (data->is_raw) {
|
||||
void *array = blobmsg_open_array(&bb, "parameters");
|
||||
bbf_get_raw(data, &bb);
|
||||
blobmsg_close_array(&bb, array);
|
||||
} else {
|
||||
bbf_get_blob(data, &bb);
|
||||
}
|
||||
|
||||
ubus_send_reply(data->ctx, data->req, bb.head);
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
|
||||
31
bbfd/src/get.h
Normal file
31
bbfd/src/get.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef GET_H
|
||||
#define GET_H
|
||||
#include "usp.h"
|
||||
#include "common.h"
|
||||
|
||||
enum {
|
||||
DM_GET_PATH,
|
||||
DM_GET_PROTO,
|
||||
DM_GET_MAXDEPTH,
|
||||
DM_GET_NXT_LVL,
|
||||
DM_GET_INSTANCE,
|
||||
__DM_GET_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_GET_SAFE_PATHS,
|
||||
DM_GET_SAFE_PROTO,
|
||||
DM_GET_SAFE_NXT_LVL,
|
||||
DM_GET_SAFE_INSTANCE,
|
||||
__DM_GET_SAFE_MAX
|
||||
};
|
||||
|
||||
void init_dmmap(void);
|
||||
void usp_validate_path(usp_data_t *data);
|
||||
void usp_get_value(usp_data_t *data);
|
||||
void usp_get_instance(usp_data_t *data);
|
||||
void usp_get_name(usp_data_t *data);
|
||||
void get_mpath(usp_data_t *data);
|
||||
void usp_get_value_async(usp_data_t *data, void *output);
|
||||
|
||||
#endif /* GET_H */
|
||||
2039
bbfd/src/get_helper.c
Normal file
2039
bbfd/src/get_helper.c
Normal file
File diff suppressed because it is too large
Load diff
89
bbfd/src/get_helper.h
Normal file
89
bbfd/src/get_helper.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef GET_HELPER_H
|
||||
#define GET_HELPER_H
|
||||
|
||||
#include "usp.h"
|
||||
#include "common.h"
|
||||
#include <libbbf_api/dmbbf.h>
|
||||
|
||||
#include <libubus.h>
|
||||
|
||||
enum operation {
|
||||
OPER_EQUAL_EQUAL,
|
||||
OPER_NOT_EQUAL,
|
||||
OPER_LESS_THAN_EQUAL,
|
||||
OPER_GREATER_THAN_EQUAL,
|
||||
OPER_LESS_THAN,
|
||||
OPER_GREATER_THAN,
|
||||
};
|
||||
|
||||
struct pvNode {
|
||||
char *param;
|
||||
char *val;
|
||||
char *type;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct pathNode {
|
||||
struct list_head list;
|
||||
char path[MAX_DM_PATH];
|
||||
};
|
||||
|
||||
int resolve_path(struct dmctx *bbf_ctx, char *qPath, size_t pos,
|
||||
struct list_head *resolved_plist);
|
||||
|
||||
void add_path_node(char *para, struct list_head *plist);
|
||||
void fill_err_code(struct blob_buf *bb, int fault);
|
||||
void fill_resolve_err(struct blob_buf *bb, char *spath, int fault);
|
||||
void add_pv_node(char *para, char *val, char *type,
|
||||
struct list_head *pv_list);
|
||||
|
||||
bool path_present_in_pvlist(struct list_head *pvlist, char *entry);
|
||||
void free_pv_list(struct list_head *head);
|
||||
void free_pv_node(struct pvNode *pv);
|
||||
void free_path_list(struct list_head *head);
|
||||
|
||||
bool get_granural_object_paths(struct list_head *path_list,
|
||||
uint8_t maxdepth);
|
||||
|
||||
int bbf_dm_get_supported_dm(struct blob_buf *bb, char *path, bool first_level, int schema_type);
|
||||
int bbf_dm_get_values(struct dmctx *bbf_ctx, char *path);
|
||||
int bbf_dm_get_schema(struct blob_buf *bb);
|
||||
int bbf_dm_get_names(struct dmctx *bbf_ctx, char *path, char *next);
|
||||
|
||||
int bbf_dm_list_operate(struct dmctx *bbf_ctx);
|
||||
int usp_dm_set(struct dmctx *dm_ctx, char *path, char *value);
|
||||
|
||||
int get_resolved_paths(struct dmctx *bbf_ctx, char *qpath,
|
||||
struct list_head *resolved_paths);
|
||||
|
||||
int usp_dm_operate(struct blob_buf *bb, char *path, char *input_params, bool raw, int instance);
|
||||
int usp_del_object(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey);
|
||||
|
||||
int usp_add_object(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey);
|
||||
|
||||
int bbf_get_blob(usp_data_t *data, struct blob_buf *bb);
|
||||
int bbf_get_raw(usp_data_t *data, struct blob_buf *bb);
|
||||
bool get_next_param(char *qPath, size_t *pos, char *param);
|
||||
int bbf_dm_get_instances(struct dmctx *bbf_ctx, char *path, char *next);
|
||||
void bbf_init(struct dmctx *dm_ctx, int instance);
|
||||
void bbf_configure_ubus(struct ubus_context *ctx);
|
||||
void bbf_cleanup(struct dmctx *dm_ctx);
|
||||
void bb_add_string(struct blob_buf *bb, const char *name, const char *value);
|
||||
bool bbf_dm_event_registered(char *ename);
|
||||
void set_datamodel_version(char * version);
|
||||
|
||||
bool present_in_path_list(struct list_head *plist, char *entry);
|
||||
|
||||
// Transaction related
|
||||
bool is_transaction_running(void);
|
||||
bool is_transaction_valid(int trans_id);
|
||||
int transaction_start(const char *app, uint32_t max_timeout);
|
||||
int fill_transaction_status(struct blob_buf *bb, int trans_id);
|
||||
int transaction_commit(int trans_id, struct blob_buf *bp_service_list, bool is_service_restart);
|
||||
int transaction_abort(int trans_id);
|
||||
int configure_transaction_timeout(int timeout);
|
||||
void handle_pending_signal(int);
|
||||
void print_last_dm_object(void);
|
||||
int usp_dm_exec_apply(struct dmctx *bbf_ctx, int cmd);
|
||||
|
||||
#endif /* GET_HELPER_H */
|
||||
34
bbfd/src/ipc.h
Normal file
34
bbfd/src/ipc.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* ipc.h: File to handle ipc related functionality
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef IPC_H
|
||||
#define IPC_H
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef USPD_MAX_MSG_LEN
|
||||
#define DEF_IPC_DATA_LEN (USPD_MAX_MSG_LEN - 128) // Configured Len - 128 bytes
|
||||
#else
|
||||
#define DEF_IPC_DATA_LEN (10 * 1024 * 1024 - 128) // 10M - 128 bytes
|
||||
#endif
|
||||
|
||||
#endif // end IPC_H
|
||||
156
bbfd/src/operate.c
Normal file
156
bbfd/src/operate.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* operate.c: Operate handler for uspd
|
||||
*
|
||||
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "operate.h"
|
||||
#include "get_helper.h"
|
||||
#include "pretty_print.h"
|
||||
#include "ipc.h"
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
#include <libubus.h>
|
||||
|
||||
static void usp_operate_cmd(usp_data_t *data, struct blob_buf *bb)
|
||||
{
|
||||
struct dmctx bbf_ctx;
|
||||
int fault;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
LIST_HEAD(resolved_paths);
|
||||
|
||||
fault = get_resolved_paths(&bbf_ctx, data->qpath, &resolved_paths);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
if (fault) {
|
||||
fill_err_code(bb, fault);
|
||||
} else {
|
||||
void *array;
|
||||
struct pathNode *rv;
|
||||
|
||||
array = blobmsg_open_array(bb, "Results");
|
||||
list_for_each_entry(rv, &resolved_paths, list) {
|
||||
char path[MAX_DM_PATH] = {0};
|
||||
snprintf(path, MAX_DM_PATH, "%s%s", rv->path, data->op_action);
|
||||
|
||||
void *table = blobmsg_open_table(bb, NULL);
|
||||
blobmsg_add_string(bb, "path", path);
|
||||
usp_dm_operate(bb, path, data->op_input, data->is_raw, data->instance);
|
||||
blobmsg_close_table(bb, table);
|
||||
}
|
||||
blobmsg_close_array(bb, array);
|
||||
}
|
||||
|
||||
free_path_list(&resolved_paths);
|
||||
}
|
||||
|
||||
void list_operate_schema(struct blob_buf *bb)
|
||||
{
|
||||
struct dm_parameter *n;
|
||||
void *array;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(BBFDM_USP);
|
||||
bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER);
|
||||
|
||||
bbf_dm_list_operate(&bbf_ctx);
|
||||
|
||||
array = blobmsg_open_array(bb, "parameters");
|
||||
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
|
||||
void *table = blobmsg_open_table(bb, NULL);
|
||||
|
||||
bb_add_string(bb, "parameter", n->name);
|
||||
bb_add_string(bb, "type", n->additional_data);
|
||||
|
||||
DEBUG("Operate node|%s|, type(%s)", n->name, n->type);
|
||||
|
||||
// filling in and out parameter
|
||||
if (n->data) {
|
||||
int i;
|
||||
void *array_arg;
|
||||
operation_args *args = (operation_args *) n->data;
|
||||
const char **ap = args->in;
|
||||
|
||||
if (ap) {
|
||||
array_arg = blobmsg_open_array(bb, "in");
|
||||
for (i = 0; ap[i] != NULL; i++)
|
||||
blobmsg_add_string(bb, NULL, ap[i]);
|
||||
|
||||
blobmsg_close_array(bb, array_arg);
|
||||
}
|
||||
|
||||
ap = args->out;
|
||||
if (ap) {
|
||||
array_arg = blobmsg_open_array(bb, "out");
|
||||
for (i = 0; ap[i] != NULL; i++)
|
||||
blobmsg_add_string(bb, NULL, ap[i]);
|
||||
|
||||
blobmsg_close_array(bb, array_arg);
|
||||
}
|
||||
}
|
||||
blobmsg_close_table(bb, table);
|
||||
}
|
||||
|
||||
blobmsg_close_array(bb, array);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
}
|
||||
|
||||
void usp_operate_cmd_async(usp_data_t *data, void *output)
|
||||
{
|
||||
struct blob_buf bb;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
usp_operate_cmd(data, &bb);
|
||||
|
||||
if (!validate_msglen(&bb)) {
|
||||
ERR("IPC failed for path(%s)", data->qpath);
|
||||
}
|
||||
|
||||
memcpy(output, bb.head, blob_pad_len(bb.head));
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
|
||||
void usp_operate_cmd_sync(usp_data_t *data)
|
||||
{
|
||||
struct blob_buf bb;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
usp_operate_cmd(data, &bb);
|
||||
|
||||
if (!validate_msglen(&bb)) {
|
||||
ERR("IPC failed for path(%s)", data->qpath);
|
||||
}
|
||||
|
||||
ubus_send_reply(data->ctx, data->req, bb.head);
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
19
bbfd/src/operate.h
Normal file
19
bbfd/src/operate.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef OPERATE_H
|
||||
#define OPERATE_H
|
||||
|
||||
#include "usp.h"
|
||||
#include "common.h"
|
||||
|
||||
enum {
|
||||
DM_OPERATE_PATH,
|
||||
DM_OPERATE_ACTION,
|
||||
DM_OPERATE_INPUT,
|
||||
DM_OPERATE_PROTO,
|
||||
DM_OPERATE_INSTANCE,
|
||||
__DM_OPERATE_MAX,
|
||||
};
|
||||
|
||||
void list_operate_schema(struct blob_buf *bb);
|
||||
void usp_operate_cmd_async(usp_data_t *data, void *output);
|
||||
void usp_operate_cmd_sync(usp_data_t *data);
|
||||
#endif /* OPERATE_H */
|
||||
490
bbfd/src/pretty_print.c
Normal file
490
bbfd/src/pretty_print.c
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
/*
|
||||
* pretty_print.c: utils for pretty printing of results
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "get_helper.h"
|
||||
#include "pretty_print.h"
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
|
||||
|
||||
// private function and structures
|
||||
struct resultstack {
|
||||
void *cookie;
|
||||
char *key;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static bool is_search_by_reference(char *path)
|
||||
{
|
||||
DEBUG("Entry |%s|", path);
|
||||
if (match(path, "[+]+")) {
|
||||
size_t pindex = 0, bindex = 0;
|
||||
char *last_plus, *last_bracket;
|
||||
|
||||
last_bracket = strrchr(path, ']');
|
||||
if (!last_bracket)
|
||||
return true;
|
||||
|
||||
last_plus = strrchr(path, '+');
|
||||
|
||||
pindex = (size_t)labs(last_plus - path);
|
||||
bindex = (size_t)labs(last_bracket - path);
|
||||
|
||||
if (pindex > bindex)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//if matched start will have first match index, end will have end index
|
||||
static bool is_res_required(char *str, size_t *start, size_t *len)
|
||||
{
|
||||
|
||||
DEBUG("Entry |%s|", str);
|
||||
if (match(str, GLOB_CHAR)) {
|
||||
size_t s_len, b_len, p_len;
|
||||
char *star, *b_start, *b_end, *plus;
|
||||
char temp_char[MAX_DM_KEY_LEN] = {'\0'};
|
||||
|
||||
s_len = DM_STRLEN(str);
|
||||
b_len = s_len;
|
||||
p_len = s_len;
|
||||
|
||||
star = strchr(str, '*');
|
||||
b_start = strchr(str, '[');
|
||||
b_end = strchr(str, ']');
|
||||
plus = strchr(str, '+');
|
||||
|
||||
if (star)
|
||||
s_len = (size_t)labs(star - str);
|
||||
|
||||
if (b_start)
|
||||
b_len = (size_t)labs(b_start - str);
|
||||
|
||||
if (plus)
|
||||
p_len = (size_t)labs(plus - str);
|
||||
|
||||
*start = MIN(MIN(s_len, p_len), b_len);
|
||||
if (*start == s_len) {
|
||||
*len = 1;
|
||||
} else if (*start == p_len) {
|
||||
size_t i = 0, index = 0;
|
||||
|
||||
while ((str+i) != plus) {
|
||||
if (str[i] == DELIM)
|
||||
index = i;
|
||||
++i;
|
||||
}
|
||||
*start = index+1;
|
||||
*len = p_len - index;
|
||||
} else {
|
||||
*len = (size_t)labs(b_end - b_start);
|
||||
}
|
||||
|
||||
// Check if naming with aliases used
|
||||
snprintf(temp_char, *len+1, "%s", str + *start);
|
||||
if (match(temp_char, GLOB_EXPR))
|
||||
return true;
|
||||
|
||||
if (match(temp_char, "[*+]+"))
|
||||
return true;
|
||||
}
|
||||
*start = DM_STRLEN(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
static size_t get_glob_len(char *path)
|
||||
{
|
||||
size_t m_index = 0, m_len = 0, ret = 0;
|
||||
size_t plen = DM_STRLEN(path);
|
||||
char temp_name[MAX_DM_KEY_LEN] = {'\0'};
|
||||
char *end = NULL;
|
||||
|
||||
DEBUG("Entry");
|
||||
if (is_res_required(path, &m_index, &m_len)) {
|
||||
if (m_index <= MAX_DM_KEY_LEN)
|
||||
snprintf(temp_name, m_index, "%s", path);
|
||||
end = strrchr(temp_name, DELIM);
|
||||
if (end != NULL)
|
||||
ret = m_index - DM_STRLEN(end);
|
||||
} else {
|
||||
char name[MAX_DM_KEY_LEN] = {'\0'};
|
||||
|
||||
if (plen == 0)
|
||||
return ret;
|
||||
|
||||
if (path[plen - 1] == DELIM) {
|
||||
if (plen <= MAX_DM_KEY_LEN)
|
||||
snprintf(name, plen, "%s", path);
|
||||
} else {
|
||||
ret = 1;
|
||||
if (plen < MAX_DM_KEY_LEN)
|
||||
snprintf(name, plen + 1, "%s", path);
|
||||
}
|
||||
end = strrchr(name, DELIM);
|
||||
if (end == NULL)
|
||||
return ret;
|
||||
|
||||
ret = ret + DM_STRLEN(path) - DM_STRLEN(end);
|
||||
if (is_node_instance(end+1)) {
|
||||
int copy_len = plen - DM_STRLEN(end);
|
||||
if (copy_len <= MAX_DM_KEY_LEN)
|
||||
snprintf(temp_name, copy_len, "%s", path);
|
||||
|
||||
end = strrchr(temp_name, DELIM);
|
||||
if (end != NULL)
|
||||
ret = ret - DM_STRLEN(end);
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void resulting(uint8_t maxdepth, char *path, char *qPath, struct dmctx *bbf_ctx, struct list_head *pv_local)
|
||||
{
|
||||
struct dm_parameter *n;
|
||||
uint8_t count;
|
||||
|
||||
size_t plen = get_glob_len(qPath);
|
||||
//size_t plen = 0;
|
||||
size_t path_len = DM_STRLEN(path);
|
||||
|
||||
list_for_each_entry(n, &bbf_ctx->list_parameter, list) {
|
||||
if (path_len == 0)
|
||||
continue;
|
||||
|
||||
if (path[path_len - 1] == DELIM) {
|
||||
if (!strncmp(n->name, path, path_len)) {
|
||||
if (is_search_by_reference(qPath))
|
||||
plen = 0;
|
||||
|
||||
if (maxdepth > 4 || maxdepth == 0) {
|
||||
add_pv_node(n->name + plen, n->data, n->type, pv_local);
|
||||
} else {
|
||||
count = count_delim(n->name + path_len);
|
||||
if (count < maxdepth)
|
||||
add_pv_node(n->name + plen, n->data, n->type, pv_local);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!strcmp(n->name, path)) {
|
||||
if (is_search_by_reference(qPath))
|
||||
plen = 0;
|
||||
|
||||
if (maxdepth > 4 || maxdepth == 0) {
|
||||
add_pv_node(n->name + plen, n->data, n->type, pv_local);
|
||||
} else {
|
||||
count = count_delim(n->name + path_len);
|
||||
if (count < maxdepth)
|
||||
add_pv_node(n->name + plen, n->data, n->type, pv_local);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void add_data_blob(struct blob_buf *bb, char *param, char *value, char *type)
|
||||
{
|
||||
if (param == NULL || value == NULL || type == NULL)
|
||||
return;
|
||||
|
||||
DEBUG("# Adding BLOB (%s)::(%s)", param, value);
|
||||
switch (get_dm_type(type)) {
|
||||
case DMT_UNINT:
|
||||
blobmsg_add_u64(bb, param, (uint32_t)strtoul(value, NULL, 10));
|
||||
break;
|
||||
case DMT_INT:
|
||||
blobmsg_add_u32(bb, param, (int)strtol(value, NULL, 10));
|
||||
break;
|
||||
case DMT_LONG:
|
||||
blobmsg_add_u64(bb, param, strtoll(value, NULL, 10));
|
||||
break;
|
||||
case DMT_UNLONG:
|
||||
blobmsg_add_u64(bb, param, (uint64_t)strtoull(value, NULL, 10));
|
||||
break;
|
||||
case DMT_BOOL:
|
||||
if (get_boolean_string(value))
|
||||
blobmsg_add_u8(bb, param, true);
|
||||
else
|
||||
blobmsg_add_u8(bb, param, false);
|
||||
break;
|
||||
default: //"xsd:hexbin" "xsd:dateTime" "xsd:string"
|
||||
bb_add_string(bb, param, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void free_result_list(struct list_head *head)
|
||||
{
|
||||
struct resultstack *iter = NULL, *node = NULL;
|
||||
|
||||
list_for_each_entry_safe(iter, node, head, list) {
|
||||
free(iter->key);
|
||||
list_del(&iter->list);
|
||||
free(iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_result_node(struct resultstack *rnode)
|
||||
{
|
||||
if (rnode) {
|
||||
DEBUG("## ResStack DEL(%s)", rnode->key);
|
||||
free(rnode->key);
|
||||
list_del(&rnode->list);
|
||||
free(rnode);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_result_node(struct list_head *rlist, char *key, char *cookie)
|
||||
{
|
||||
struct resultstack *rnode = NULL;
|
||||
|
||||
rnode = (struct resultstack *) malloc(sizeof(*rnode));
|
||||
if (!rnode) {
|
||||
ERR("Out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
rnode->key = (key) ? strdup(key) : strdup("");
|
||||
rnode->cookie = cookie;
|
||||
DEBUG("## ResSTACK ADD (%s) ##", rnode->key);
|
||||
|
||||
INIT_LIST_HEAD(&rnode->list);
|
||||
list_add(&rnode->list, rlist);
|
||||
}
|
||||
|
||||
static bool is_leaf_element(char *path)
|
||||
{
|
||||
char *ptr = NULL;
|
||||
|
||||
if (!path)
|
||||
return true;
|
||||
|
||||
ptr = strchr(path, DELIM);
|
||||
|
||||
return (ptr == NULL);
|
||||
}
|
||||
|
||||
static bool get_next_element(char *path, char *param)
|
||||
{
|
||||
char *ptr;
|
||||
size_t len;
|
||||
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
len = DM_STRLEN(path);
|
||||
ptr = strchr(path, DELIM);
|
||||
if (ptr)
|
||||
strncpyt(param, path, (size_t)labs(ptr - path) + 1);
|
||||
else
|
||||
strncpyt(param, path, len + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_same_group(char *path, char *group)
|
||||
{
|
||||
return (strncmp(path, group, DM_STRLEN(group)) == 0);
|
||||
}
|
||||
|
||||
static bool add_paths_to_stack(struct blob_buf *bb, char *path, size_t begin,
|
||||
struct pvNode *pv, struct list_head *result_stack)
|
||||
{
|
||||
char key[MAX_DM_KEY_LEN], param[MAX_DM_PATH], *ptr;
|
||||
size_t parsed_len = 0;
|
||||
void *c;
|
||||
char *k;
|
||||
|
||||
|
||||
ptr = path + begin;
|
||||
if (is_leaf_element(ptr)) {
|
||||
add_data_blob(bb, ptr, pv->val, pv->type);
|
||||
return true;
|
||||
}
|
||||
|
||||
while (get_next_element(ptr, key)) {
|
||||
parsed_len += DM_STRLEN(key) + 1;
|
||||
ptr += DM_STRLEN(key) + 1;
|
||||
if (is_leaf_element(ptr)) {
|
||||
strncpyt(param, path, begin + parsed_len + 1);
|
||||
if (is_node_instance(key))
|
||||
c = blobmsg_open_table(bb, NULL);
|
||||
else
|
||||
c = blobmsg_open_table(bb, key);
|
||||
|
||||
k = param;
|
||||
add_result_node(result_stack, k, c);
|
||||
add_data_blob(bb, ptr, pv->val, pv->type);
|
||||
break;
|
||||
}
|
||||
strncpyt(param, pv->param, begin + parsed_len + 1);
|
||||
if (is_node_instance(ptr))
|
||||
c = blobmsg_open_array(bb, key);
|
||||
else
|
||||
c = blobmsg_open_table(bb, key);
|
||||
|
||||
k = param;
|
||||
add_result_node(result_stack, k, c);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// public functions
|
||||
void prepare_result_blob(struct blob_buf *bb, struct list_head *pv_list)
|
||||
{
|
||||
char *ptr;
|
||||
size_t len;
|
||||
struct pvNode *pv;
|
||||
struct resultstack *rnode;
|
||||
|
||||
LIST_HEAD(result_stack);
|
||||
|
||||
if (!bb || !pv_list)
|
||||
return;
|
||||
|
||||
if (list_empty(pv_list))
|
||||
return;
|
||||
|
||||
list_for_each_entry(pv, pv_list, list) {
|
||||
ptr = pv->param;
|
||||
if (list_empty(&result_stack)) {
|
||||
DEBUG("stack empty Processing (%s)", ptr);
|
||||
add_paths_to_stack(bb, pv->param, 0, pv, &result_stack);
|
||||
} else {
|
||||
bool is_done = false;
|
||||
|
||||
while (is_done == false) {
|
||||
rnode = list_entry(result_stack.next, struct resultstack, list);
|
||||
if (is_same_group(ptr, rnode->key)) {
|
||||
len = DM_STRLEN(rnode->key);
|
||||
ptr = ptr + len;
|
||||
|
||||
DEBUG("GROUP (%s), ptr(%s), len(%d)", pv->param, ptr, len);
|
||||
add_paths_to_stack(bb, pv->param, len, pv, &result_stack);
|
||||
is_done = true;
|
||||
} else {
|
||||
// Get the latest entry before deleting it
|
||||
DEBUG("DIFF GROUP pv(%s), param(%s)", pv->param, ptr);
|
||||
blobmsg_close_table(bb, rnode->cookie);
|
||||
free_result_node(rnode);
|
||||
if (list_empty(&result_stack)) {
|
||||
add_paths_to_stack(bb, pv->param, 0, pv, &result_stack);
|
||||
is_done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close the stack entry if left
|
||||
list_for_each_entry(rnode, &result_stack, list) {
|
||||
blobmsg_close_table(bb, rnode->cookie);
|
||||
}
|
||||
free_result_list(&result_stack);
|
||||
}
|
||||
|
||||
void prepare_pretty_result(uint8_t maxdepth, char *qPath, struct blob_buf *bb,
|
||||
struct dmctx *bbf_ctx, struct list_head *rslvd)
|
||||
{
|
||||
struct pathNode *iter = NULL;
|
||||
|
||||
LIST_HEAD(pv_local);
|
||||
|
||||
list_for_each_entry(iter, rslvd, list) {
|
||||
resulting(maxdepth, iter->path, qPath, bbf_ctx, &pv_local);
|
||||
}
|
||||
|
||||
struct pvNode *pv;
|
||||
|
||||
DEBUG("################### DATA to PROCESS ##################");
|
||||
list_for_each_entry(pv, &pv_local, list) {
|
||||
DEBUG("## %s ##", pv->param);
|
||||
}
|
||||
DEBUG("######################################################");
|
||||
|
||||
prepare_result_blob(bb, &pv_local);
|
||||
|
||||
free_pv_list(&pv_local);
|
||||
}
|
||||
|
||||
/* This function is not used anywhere but kept for debugging purpose hence suppressed */
|
||||
// cppcheck-suppress unusedFunction
|
||||
void dump_pv_list(struct list_head *pv_list)
|
||||
{
|
||||
struct pvNode *pv = NULL;
|
||||
|
||||
INFO("############### PV list Dump #########");
|
||||
list_for_each_entry(pv, pv_list, list) {
|
||||
INFO("## (%s)::(%s)::(%s) ##", pv->param, pv->val, pv->type);
|
||||
}
|
||||
INFO("############# dump done ###############");
|
||||
}
|
||||
|
||||
/* This function is not used anywhere but kept for debugging purpose hence suppressed */
|
||||
// cppcheck-suppress unusedFunction
|
||||
void dump_resolved_list(struct list_head *resolved_list)
|
||||
{
|
||||
struct pathNode *iter;
|
||||
|
||||
INFO("********************Resolved List Dump***********************");
|
||||
list_for_each_entry(iter, resolved_list, list) {
|
||||
INFO("## %s ##", iter->path);
|
||||
}
|
||||
INFO("**************************DONE*******************************");
|
||||
}
|
||||
|
||||
void prepare_result_raw(struct blob_buf *bb, struct dmctx *bbf_ctx, struct list_head *rslvd)
|
||||
{
|
||||
struct pathNode *iter = NULL;
|
||||
struct dm_parameter *n;
|
||||
void *array, *table;
|
||||
|
||||
array = blobmsg_open_array(bb, "parameters");
|
||||
list_for_each_entry(iter, rslvd, list) {
|
||||
size_t ilen = DM_STRLEN(iter->path);
|
||||
if (ilen == 0)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(n, &bbf_ctx->list_parameter, list) {
|
||||
if (iter->path[ilen - 1] == DELIM) {
|
||||
if (!strncmp(n->name, iter->path, ilen)) {
|
||||
table = blobmsg_open_table(bb, NULL);
|
||||
bb_add_string(bb, "parameter", n->name);
|
||||
bb_add_string(bb, "value", n->data);
|
||||
bb_add_string(bb, "type", n->type);
|
||||
blobmsg_close_table(bb, table);
|
||||
}
|
||||
} else {
|
||||
if (!strcmp(n->name, iter->path)) {
|
||||
table = blobmsg_open_table(bb, NULL);
|
||||
bb_add_string(bb, "parameter", n->name);
|
||||
bb_add_string(bb, "value", n->data);
|
||||
bb_add_string(bb, "type", n->type);
|
||||
blobmsg_close_table(bb, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
blobmsg_close_array(bb, array);
|
||||
}
|
||||
33
bbfd/src/pretty_print.h
Normal file
33
bbfd/src/pretty_print.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* pretty_print.h: utils for pretty printing of results
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef PRETTY_PRINT_H
|
||||
#define PRETTY_PRINT_H
|
||||
|
||||
void prepare_result_blob(struct blob_buf *bb, struct list_head *pv_list);
|
||||
void prepare_pretty_result(uint8_t maxdepth, char *qPath, struct blob_buf *bb,
|
||||
struct dmctx *bbf_ctx, struct list_head *rslvd);
|
||||
void prepare_result_raw(struct blob_buf *bb, struct dmctx *bbf_ctx, struct list_head *rslvd);
|
||||
void dump_pv_list(struct list_head *pv_list);
|
||||
void dump_resolved_list(struct list_head *resolved_list);
|
||||
|
||||
#endif
|
||||
225
bbfd/src/set.c
Normal file
225
bbfd/src/set.c
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* set.c: Set handler for uspd
|
||||
*
|
||||
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "set.h"
|
||||
#include "get_helper.h"
|
||||
#include <libubus.h>
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
|
||||
|
||||
static const struct blobmsg_policy dm_setm_value_policy[] = {
|
||||
[DM_SET_V_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
|
||||
[DM_SET_V_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING },
|
||||
};
|
||||
|
||||
int usp_set_value(usp_data_t *data)
|
||||
{
|
||||
struct blob_buf bb;
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
void *array = NULL;
|
||||
struct pvNode *pv = NULL;
|
||||
struct dmctx bbf_ctx;
|
||||
int fault = USP_ERR_OK;
|
||||
struct param_fault *p = NULL;
|
||||
void *table;
|
||||
bool fault_occured = false;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
|
||||
set_bbfdatamodel_type(data->proto);
|
||||
bbf_init(&bbf_ctx, data->instance);
|
||||
|
||||
ctx = data->ctx;
|
||||
req = data->req;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
list_for_each_entry(pv, data->pv_list, list) {
|
||||
fault = usp_dm_set(&bbf_ctx, pv->param, pv->val);
|
||||
if (fault == 0)
|
||||
fault = usp_dm_exec_apply(&bbf_ctx, CMD_SET_VALUE);
|
||||
|
||||
if (fault) {
|
||||
if (fault_occured == false) {
|
||||
fault_occured = true;
|
||||
if (!array)
|
||||
array = blobmsg_open_array(&bb, "parameters");
|
||||
}
|
||||
|
||||
while (bbf_ctx.list_fault_param.next != &bbf_ctx.list_fault_param) {
|
||||
p = list_entry(bbf_ctx.list_fault_param.next, struct param_fault, list);
|
||||
table = blobmsg_open_table(&bb, NULL);
|
||||
bb_add_string(&bb, "path", p->name);
|
||||
blobmsg_add_u8(&bb, "status", false);
|
||||
blobmsg_add_u32(&bb, "fault", (uint32_t)p->fault);
|
||||
blobmsg_close_table(&bb, table);
|
||||
del_list_fault_param(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fault_occured == false)
|
||||
blobmsg_add_u8(&bb, "status", true);
|
||||
|
||||
if (array)
|
||||
blobmsg_close_array(&bb, array);
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
|
||||
// free
|
||||
blob_buf_free(&bb);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
||||
int fill_pvlist_from_table(char *bpath, struct blob_attr *blob_value, struct list_head *pv_list, int instance)
|
||||
{
|
||||
struct blob_attr *attr;
|
||||
char path[MAX_DM_PATH], value[MAX_DM_VALUE];
|
||||
struct dmctx bbf_ctx;
|
||||
int fault = USP_ERR_OK;
|
||||
struct pathNode *p;
|
||||
size_t tlen;
|
||||
LIST_HEAD(resolved_paths);
|
||||
|
||||
if (!blob_value)
|
||||
return 0;
|
||||
|
||||
tlen = (size_t)blobmsg_data_len(blob_value);
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
bbf_init(&bbf_ctx, instance);
|
||||
|
||||
fault = get_resolved_paths(&bbf_ctx, bpath, &resolved_paths);
|
||||
if (fault) {
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
free_path_list(&resolved_paths);
|
||||
return fault;
|
||||
}
|
||||
|
||||
__blob_for_each_attr(attr, blobmsg_data(blob_value), tlen) {
|
||||
struct blobmsg_hdr *hdr = blob_data(attr);
|
||||
|
||||
switch (blob_id(attr)) {
|
||||
case BLOBMSG_TYPE_STRING:
|
||||
snprintf(value, MAX_DM_VALUE, "%s", blobmsg_get_string(attr));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT8:
|
||||
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u8(attr));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT16:
|
||||
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u16(attr));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT32:
|
||||
snprintf(value, MAX_DM_VALUE, "%u", blobmsg_get_u32(attr));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT64:
|
||||
snprintf(value, MAX_DM_VALUE, "%"PRIu64"", blobmsg_get_u64(attr));
|
||||
break;
|
||||
default:
|
||||
INFO("Unhandled set request type|%x|", blob_id(attr));
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
free_path_list(&resolved_paths);
|
||||
return USP_FAULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
list_for_each_entry(p, &resolved_paths, list) {
|
||||
snprintf(path, MAX_DM_PATH, "%s%s", p->path, (char *)hdr->name);
|
||||
add_pv_node(path, value, NULL, pv_list);
|
||||
}
|
||||
}
|
||||
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
free_path_list(&resolved_paths);
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
||||
int fill_pvlist_from_tuple(struct blob_attr *blob, struct list_head *pv_list)
|
||||
{
|
||||
size_t rem;
|
||||
struct blob_attr *cur;
|
||||
|
||||
blobmsg_for_each_attr(cur, blob, rem) {
|
||||
struct blob_attr *tb[__DM_SET_V_MAX];
|
||||
char *path, *value, *key;
|
||||
|
||||
key = NULL;
|
||||
blobmsg_parse(dm_setm_value_policy, __DM_SET_V_MAX, tb,
|
||||
blobmsg_data(cur), blobmsg_len(cur));
|
||||
|
||||
// ignore the tuples which does not have path and values
|
||||
if (!tb[DM_SET_V_PATH] || !tb[DM_SET_V_VALUE])
|
||||
continue;
|
||||
|
||||
path = blobmsg_get_string(tb[DM_SET_V_PATH]);
|
||||
value = blobmsg_get_string(tb[DM_SET_V_VALUE]);
|
||||
|
||||
add_pv_node(path, value, key, pv_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fill_pvlist_from_path(char *path, struct blob_attr *val_blob, struct list_head *pv_list, int instance)
|
||||
{
|
||||
int fault = USP_ERR_OK;
|
||||
size_t plen;
|
||||
char *val = NULL;
|
||||
struct dmctx bbf_ctx;
|
||||
|
||||
LIST_HEAD(resolved_paths);
|
||||
|
||||
if (!val_blob)
|
||||
return 0;
|
||||
|
||||
memset(&bbf_ctx, 0, sizeof(struct dmctx));
|
||||
bbf_init(&bbf_ctx, instance);
|
||||
|
||||
plen = DM_STRLEN(path);
|
||||
if (plen == 0)
|
||||
fault = USP_FAULT_INVALID_PATH;
|
||||
|
||||
if (fault == USP_ERR_OK) {
|
||||
if (path[plen - 1] == '.')
|
||||
fault = USP_FAULT_INVALID_PATH;
|
||||
}
|
||||
|
||||
if (fault == USP_ERR_OK)
|
||||
fault = get_resolved_paths(&bbf_ctx, path, &resolved_paths);
|
||||
|
||||
if (fault == USP_ERR_OK) {
|
||||
struct pathNode *p;
|
||||
|
||||
list_for_each_entry(p, &resolved_paths, list) {
|
||||
val = blobmsg_get_string(val_blob);
|
||||
add_pv_node(p->path, val, NULL, pv_list);
|
||||
}
|
||||
}
|
||||
|
||||
free_path_list(&resolved_paths);
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
|
||||
return fault;
|
||||
}
|
||||
60
bbfd/src/set.h
Normal file
60
bbfd/src/set.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef SET_H
|
||||
#define SET_H
|
||||
#include "usp.h"
|
||||
#include "common.h"
|
||||
|
||||
enum {
|
||||
DM_SETS_PATHS,
|
||||
DM_SETS_PROTO,
|
||||
DM_SETS_INSTANCE,
|
||||
DM_SETS_TRANS_ID,
|
||||
__DM_SETS_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_SETS_A_NOTIF_PATH,
|
||||
DM_SETS_A_NOTIF_VALUE,
|
||||
DM_SETS_A_NOTIF_CHANGE,
|
||||
__DM_SETS_A_NOTIF_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_SET_PATH,
|
||||
DM_SET_VALUE,
|
||||
DM_SET_VALUE_TABLE,
|
||||
DM_SET_PROTO,
|
||||
DM_SET_INSTANCE,
|
||||
__DM_SET_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_RAW_SET_PATH,
|
||||
DM_RAW_SET_VALUE,
|
||||
DM_RAW_SET_VALUE_TABLE,
|
||||
DM_RAW_SET_PROTO,
|
||||
DM_RAW_SET_INSTANCE,
|
||||
DM_RAW_SET_TRANS_ID,
|
||||
__DM_RAW_SET_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_SET_V_PATH,
|
||||
DM_SET_V_VALUE,
|
||||
__DM_SET_V_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_SET_MULTI_TUPLE,
|
||||
DM_SET_MULTI_PROTO,
|
||||
DM_SET_MULTI_INSTANCE,
|
||||
DM_SET_MULTI_TRANS_ID,
|
||||
__DM_SET_MULTI_MAX
|
||||
};
|
||||
|
||||
int fill_pvlist_from_table(char *bpath, struct blob_attr *blob_value, struct list_head *pv_list, int instance);
|
||||
int fill_pvlist_from_tuple(struct blob_attr *blob, struct list_head *pv_list);
|
||||
int fill_pvlist_from_path(char *path, struct blob_attr *val_blob, struct list_head *pv_list, int instance);
|
||||
int usp_set_value(usp_data_t *data);
|
||||
|
||||
#endif /* SET_H */
|
||||
|
||||
1686
bbfd/src/usp.c
Normal file
1686
bbfd/src/usp.c
Normal file
File diff suppressed because it is too large
Load diff
137
bbfd/src/usp.h
Normal file
137
bbfd/src/usp.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
#ifndef USP_H
|
||||
#define USP_H
|
||||
|
||||
#include <libubus.h>
|
||||
#include <libubox/blobmsg.h>
|
||||
#include <libubox/list.h>
|
||||
|
||||
#define USP_ATTR_UNUSED __attribute__((unused))
|
||||
#define USP_EXT_LEN (4) // length of usp.
|
||||
#define MAX_GRANURALITY_DEPTH (3)
|
||||
#define USP_SUBPROCESS_DEPTH (2)
|
||||
#define SCHEMA_UPDATE_TIMEOUT (30 * 1000)
|
||||
|
||||
struct uspd_async_req {
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data req;
|
||||
struct uloop_process process;
|
||||
void *result;
|
||||
};
|
||||
|
||||
struct usp_context {
|
||||
struct ubus_context ubus_ctx;
|
||||
size_t dm_schema_len;
|
||||
struct uloop_timeout schema_timer;
|
||||
struct uloop_timeout instance_timer;
|
||||
struct ubus_object *notify_object;
|
||||
struct list_head obj_list;
|
||||
struct list_head event_handlers;
|
||||
struct list_head instances;
|
||||
struct list_head old_instances;
|
||||
};
|
||||
|
||||
struct ev_handler_node {
|
||||
struct ubus_event_handler *ev_handler;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
typedef struct usp_data {
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
bool is_raw;
|
||||
int proto;
|
||||
char *qpath;
|
||||
uint8_t depth;
|
||||
char *next_level;
|
||||
int dm_cmd;
|
||||
struct list_head *plist;
|
||||
struct list_head *pv_list;
|
||||
char *set_key;
|
||||
char *op_action;
|
||||
char *op_input;
|
||||
int instance;
|
||||
int trans_id;
|
||||
} usp_data_t;
|
||||
|
||||
enum {
|
||||
DM_LIST_NOTIFY_INSTANCE,
|
||||
__DM_LIST_NOTIFY_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_SUPPORTED_PATH,
|
||||
DM_SUPPORTED_NXT_LEVEL,
|
||||
DM_SUPPORTED_SCHEMA_TYPE,
|
||||
__DM_SUPPORTED_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
DM_NOTIFY_NAME,
|
||||
DM_NOTIFY_PRAMS,
|
||||
__DM_NOTIFY_MAX,
|
||||
};
|
||||
|
||||
struct obNode {
|
||||
struct ubus_object *obj;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
int get_multi(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, struct blob_attr *msg,
|
||||
int bbf_cmd);
|
||||
|
||||
int usp_getm_values(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req,
|
||||
USP_ATTR_UNUSED const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_getm_names(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req,
|
||||
USP_ATTR_UNUSED const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_raw_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_get_handler(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method USP_ATTR_UNUSED,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_set(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_raw_set(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_operate(struct ubus_context *ctx, struct ubus_object *obj USP_ATTR_UNUSED,
|
||||
struct ubus_request_data *req, const char *method USP_ATTR_UNUSED,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_list_schema(struct ubus_context *actx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg USP_ATTR_UNUSED);
|
||||
|
||||
int usp_list_operate(struct ubus_context *actx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg USP_ATTR_UNUSED);
|
||||
|
||||
int handle_set_multi_value(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method USP_ATTR_UNUSED,
|
||||
struct blob_attr *msg);
|
||||
|
||||
int usp_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg);
|
||||
|
||||
bool usp_pre_init(struct usp_context *u);
|
||||
bool usp_post_init(struct usp_context *u);
|
||||
bool usp_cleanup(struct usp_context *u);
|
||||
|
||||
#endif /* COMMON_H */
|
||||
16
bbfd/test/Makefile
Normal file
16
bbfd/test/Makefile
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
LIB = libuspd_test.so
|
||||
|
||||
LIB_OBJS = libuspd_test.o
|
||||
LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC
|
||||
LIB_LDFLAGS = $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(LIB_CFLAGS) -I/usr/local/include/libbbf_api/ -c -o $@ $<
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(LIB_OBJS)
|
||||
$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -fv *.o $(LIB)
|
||||
39
bbfd/test/Readme.md
Normal file
39
bbfd/test/Readme.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# USPD Tests
|
||||
USPD module test is based on `iopsys/code-analysis-dev` docker image. It consists
|
||||
of below test phases, in each phase different kind of test perform:
|
||||
|
||||
1. Static code analysis
|
||||
2. Unit Test
|
||||
3. API Test
|
||||
4. Functional Test
|
||||
|
||||
## 1. Static code Analysis
|
||||
In this stage code is being tested for flaws by running static code analysers,
|
||||
it also runs CPD tests which determine the optimal reusable codes.
|
||||
Tests running in this phase are:
|
||||
|
||||
- Flaw finder
|
||||
- CPP Check
|
||||
- CPD Test
|
||||
|
||||
## 2. Unit Test
|
||||
In this stage various wrapper functions being tested for memory leaks using
|
||||
`valgrind`.
|
||||
Tests running in this phase are:
|
||||
- Cmocka Test cases
|
||||
- Coverage report
|
||||
- memory check using valgrind
|
||||
|
||||
## 3. API Test
|
||||
In this stage ubus exposed APIs getting tested using `ubus-api-validator`
|
||||
|
||||
## 4. Functional Test
|
||||
In this stage functionality provided by uspd is getting tested.
|
||||
|
||||
Below tests and verifications done in this stage:
|
||||
- Compilation check
|
||||
- Python based bug verification
|
||||
- Functionality testing based on schema validation
|
||||
|
||||
|
||||
|
||||
157
bbfd/test/api/json/usp.raw.validation.json
Normal file
157
bbfd/test/api/json/usp.raw.validation.json
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
{
|
||||
"object": "usp.raw",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "hello",
|
||||
"rc": 3
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_start",
|
||||
"args": {
|
||||
"app": "test"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.SSID",
|
||||
"value": "test-2g",
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_abort",
|
||||
"args": {
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"127.0.0.1",
|
||||
"Timeout":".5"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.USB.",
|
||||
"next-level":false,
|
||||
"schema_type":1
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.WiFi."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.WiFi.",
|
||||
"next-level":false,
|
||||
"schema_type":2
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.USB.",
|
||||
"next-level":false,
|
||||
"schema_type":3
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.WiFi.",
|
||||
"schema_type":1
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "dump_schema",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "list_operate",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_start",
|
||||
"args": {
|
||||
"app": "test"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "setm_values",
|
||||
"args": {
|
||||
"pv_tuple": [{"path":"Device.Users.User.1.Alias", "value":"cpe-1"}, {"path":"Device.Users.User.2.Alias", "value":"cpe-2"}],
|
||||
"proto": "usp",
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_commit",
|
||||
"args": {
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "getm_names",
|
||||
"args": {
|
||||
"paths": ["Device.WiFi.SSID.1.SSID","Device.WiFi.SSID.2.SSID"],
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
117
bbfd/test/api/json/usp.validation.json
Normal file
117
bbfd/test/api/json/usp.validation.json
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
{
|
||||
"object": "usp",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "validate",
|
||||
"args": {
|
||||
"path": "Device.Users.User.1.Alias",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.SSID",
|
||||
"value": "test-2g"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"127.0.0.1"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "add_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "list_operate",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.USB.",
|
||||
"next-level":false,
|
||||
"schema_type":1
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.WiFi."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.WiFi.",
|
||||
"next-level":false,
|
||||
"schema_type":2
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path":"Device.USB.",
|
||||
"next-level":false,
|
||||
"schema_type":3
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"Path":"Device.WiFi.",
|
||||
"schema_type":1
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
23
bbfd/test/cmocka/Makefile
Normal file
23
bbfd/test/cmocka/Makefile
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
CC = gcc
|
||||
USPD_LIB_DIR ?= $(shell dirname $(PWD))
|
||||
USPD_LIB = -luspd -L$(USPD_LIB_DIR)
|
||||
CMOCKA_LIB = -l cmocka
|
||||
LIBS = $(USPD_LIB) $(CMOCKA_LIB) -luci -pthread -lubus -lubox -ljson-c -lblobmsg_json -lbbfdm -lpthread
|
||||
CFLAGS = -g -Wall -I../../src
|
||||
LDFLAGS = $(LIBS) -Wl,-rpath=$(USPD_LIB_DIR) -I$(USPD_LIB_DIR)
|
||||
UNIT_TESTS = unit_test_uspd
|
||||
|
||||
VALGRIND = valgrind --leak-check=full --show-reachable=no \
|
||||
--show-leak-kinds=all --errors-for-leak-kinds=all \
|
||||
--error-exitcode=1 --track-origins=yes
|
||||
|
||||
unit_test_uspd: unit_test_uspd.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
unit-test: $(UNIT_TESTS)
|
||||
$(foreach testprog, $(UNIT_TESTS), sudo $(VALGRIND) ./$(testprog);)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm $(UNIT_TESTS) *.o -fv
|
||||
|
||||
9
bbfd/test/cmocka/test_utils.h
Normal file
9
bbfd/test/cmocka/test_utils.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef TEST_UTILS_H
|
||||
#define TEST_UTILS_H
|
||||
|
||||
#define GET_PATH "Device.DeviceInfo.Manufacturer"
|
||||
#define GET_PROTO "usp"
|
||||
#define GET_RAW_PROTO "usp.raw"
|
||||
#define GET_CWMP_PROTO "cwmp"
|
||||
|
||||
#endif
|
||||
980
bbfd/test/cmocka/unit_test_uspd.c
Normal file
980
bbfd/test/cmocka/unit_test_uspd.c
Normal file
|
|
@ -0,0 +1,980 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
#include <libubus.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
#include <libubox/blobmsg.h>
|
||||
#include <libubox/list.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <json-c/json.h>
|
||||
|
||||
#include "usp.h"
|
||||
#include "get_helper.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
struct test_ctx {
|
||||
struct usp_context uspctx;
|
||||
struct blob_buf bb;
|
||||
struct ubus_object usp;
|
||||
struct ubus_object usp_raw;
|
||||
FILE *fp;
|
||||
struct ubus_request_data *req;
|
||||
unsigned long instance;
|
||||
};
|
||||
|
||||
// Stub functions to override existing functionalities
|
||||
void ubus_complete_deferred_request(struct ubus_context *ctx,
|
||||
struct ubus_request_data *req, int ret)
|
||||
{
|
||||
}
|
||||
|
||||
static int group_setup(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = calloc(1, sizeof(struct test_ctx));
|
||||
|
||||
if (!ctx)
|
||||
return -1;
|
||||
|
||||
openlog("unit_test", LOG_CONS| LOG_NDELAY, LOG_LOCAL1);
|
||||
|
||||
memset(&ctx->uspctx, 0, sizeof(struct usp_context));
|
||||
|
||||
ubus_connect_ctx(&ctx->uspctx.ubus_ctx, NULL);
|
||||
|
||||
INIT_LIST_HEAD(&ctx->uspctx.obj_list);
|
||||
INIT_LIST_HEAD(&ctx->uspctx.instances);
|
||||
INIT_LIST_HEAD(&ctx->uspctx.old_instances);
|
||||
|
||||
usp_pre_init(&ctx->uspctx);
|
||||
|
||||
remove("/tmp/test.log");
|
||||
ctx->usp.name = "usp";
|
||||
ctx->usp_raw.name = "usp.raw";
|
||||
memset(&ctx->bb, 0, sizeof(struct blob_buf));
|
||||
ctx->req = (struct ubus_request_data *) calloc(1, sizeof(struct ubus_request_data));
|
||||
*state = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
|
||||
remove("/tmp/test.log");
|
||||
blob_buf_init(&ctx->bb, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int group_teardown(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
|
||||
usp_cleanup(&ctx->uspctx);
|
||||
blob_buf_free(&ctx->bb);
|
||||
ubus_shutdown(&ctx->uspctx.ubus_ctx);
|
||||
free(ctx->req);
|
||||
free(ctx);
|
||||
remove("/tmp/test.log");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_DeviceInfo_Manufacturer(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "DeviceInfo.Manufacturer");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
//printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "fault", &tmp);
|
||||
assert_string_equal(json_object_to_json_string(tmp), "7026");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_getm_values_Device_WiFi_SSID_Alias(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct json_object *local;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
void *paths;
|
||||
paths = blobmsg_open_array(bb, "paths");
|
||||
blobmsg_add_string(bb, NULL, "Device.WiFi.SSID.1.Alias");
|
||||
blobmsg_close_array(bb, paths);
|
||||
blobmsg_add_string(bb, "proto", GET_RAW_PROTO);
|
||||
|
||||
usp_getm_values(uctx, obj, req, "getm_values", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "parameters", &tmp);
|
||||
|
||||
if (json_object_get_type(tmp) == json_type_array) {
|
||||
for (int i = 0; i<json_object_array_length(tmp);++i) {
|
||||
struct json_object *val = json_object_array_get_idx(tmp, i);
|
||||
json_object_object_get_ex(val, "value", &local);
|
||||
assert_string_equal(json_object_get_string(local), "cpe-1");
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_resolve_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct json_object *local;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.1.Username");
|
||||
blobmsg_add_string(bb, "proto", GET_RAW_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "validate", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "parameters", &tmp);
|
||||
if (json_object_get_type(tmp) == json_type_array) {
|
||||
for (int i = 0; i<json_object_array_length(tmp); ++i) {
|
||||
struct json_object *val = json_object_array_get_idx(tmp, i);
|
||||
json_object_object_get_ex(val, "parameter", &local);
|
||||
assert_string_equal(json_object_get_string(local), "Device.Users.User.1.Usernam");
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
static void test_api_usp_resolve_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct json_object *local;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.1.Username");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "validate", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "parameters", &tmp);
|
||||
if (json_object_get_type(tmp) == json_type_array) {
|
||||
for (int i = 0; i<json_object_array_length(tmp); ++i) {
|
||||
struct json_object *val = json_object_array_get_idx(tmp, i);
|
||||
json_object_object_get_ex(val, "parameter", &local);
|
||||
assert_string_equal(json_object_get_string(local), "Device.Users.User.1.Usernam");
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_getm_names_Device_WiFi_SSID_Alias(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct json_object *local;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
void *paths;
|
||||
paths = blobmsg_open_array(bb, "paths");
|
||||
blobmsg_add_string(bb, NULL, "Device.WiFi.SSID.1.Alias");
|
||||
blobmsg_close_array(bb, paths);
|
||||
blobmsg_add_string(bb, "proto", GET_RAW_PROTO);
|
||||
|
||||
usp_getm_names(uctx, obj, req, "getm_names", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "parameters", &tmp);
|
||||
|
||||
if (json_object_get_type(tmp) == json_type_array) {
|
||||
for (int i = 0; i<json_object_array_length(tmp); ++i) {
|
||||
struct json_object *val = json_object_array_get_idx(tmp, i);
|
||||
|
||||
json_object_object_get_ex(val, "parameter", &local);
|
||||
assert_string_equal(json_object_get_string(local), "Device.WiFi.SSID.1.Alias");
|
||||
json_object_object_get_ex(val, "value", &local);
|
||||
assert_string_equal(json_object_get_string(local), "1");
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void test_api_usp_raw_dump_schema(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct ubus_context *ubus_ctx = &ctx->uspctx.ubus_ctx;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj;
|
||||
|
||||
usp_list_schema(ubus_ctx, obj, req, "dump_schema", NULL);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
//printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_list_operate(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct ubus_context *ubus_ctx = &ctx->uspctx.ubus_ctx;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj;
|
||||
|
||||
usp_list_operate(ubus_ctx, obj, req, "list_operate", NULL);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
//printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_wrong_name_Device_IP_Interface(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path","Device.IP._Interface.1.Status");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "fault", &tmp);
|
||||
assert_string_equal(json_object_to_json_string(tmp), "7026");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_wrong_braces_Device_IP_Interface(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path","Device.IP.Interface.{Type==\"Normal\"}.Status");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "fault", &tmp);
|
||||
assert_string_equal(json_object_to_json_string(tmp), "7026");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_wrong_exp_Device_IP_Interface(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path","Device.IP.Interface.[Type==\"Normal\"&&IPv4Address.*.AddressingType==\"Static\"].Status");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "fault", &tmp);
|
||||
assert_string_equal(json_object_to_json_string(tmp), "7011");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_Device_IP_Interface(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.IP.Interface.[].");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "fault", &tmp);
|
||||
assert_string_equal(json_object_to_json_string(tmp), "7026");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_search_exp_Device_WiFi_SSID(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp, *array_obj;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.WiFi.SSID.[Status==\"Up\"].Alias");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "SSID");
|
||||
if (json_object_get_type(array_obj) == json_type_array) {
|
||||
for (int i = 0; i<json_object_array_length(array_obj);++i) {
|
||||
char temp[512];
|
||||
struct json_object *array_index_obj = json_object_array_get_idx(array_obj, i);
|
||||
|
||||
json_object_object_get_ex(array_index_obj, "Alias", &tmp);
|
||||
snprintf(temp, 512, "cpe-%d", i+1);
|
||||
assert_string_equal(json_object_get_string(tmp), temp);
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_Device_WiFi_SSID(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp, *array_obj;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.WiFi.SSID.*.Alias");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "SSID");
|
||||
|
||||
if (json_object_get_type(array_obj) == json_type_array) {
|
||||
for (int i = 0; i < json_object_array_length(array_obj); ++i) {
|
||||
char temp[512];
|
||||
struct json_object *array_index_obj = json_object_array_get_idx(array_obj, i);
|
||||
|
||||
json_object_object_get_ex(array_index_obj, "Alias", &tmp);
|
||||
snprintf(temp, 512, "cpe-%d", i+1);
|
||||
assert_string_equal(json_object_get_string(tmp), temp);
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_wrong_oper_Device_WiFi_SSID(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.WiFi.SSID.[Status>Up].Alias");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "fault", &tmp);
|
||||
assert_string_equal(json_object_to_json_string(tmp), "7008");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void test_api_usp_get_Device_DeviceInfo_Manufacturer(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", GET_PATH);
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "Manufacturer", &tmp);
|
||||
assert_string_equal(json_object_get_string(tmp), "iopsys");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_add_object_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp, *array_index_obj, *array_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_add_del_handler(uctx, obj, req, "add_object", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
assert_string_equal(json_object_get_string(tmp), "Device.Users.User.");
|
||||
json_object_object_get_ex(array_index_obj, "status", &tmp);
|
||||
assert_string_equal(json_object_get_string(tmp), "true");
|
||||
|
||||
tmp = NULL;
|
||||
json_object_object_get_ex(array_index_obj, "instance", &tmp);
|
||||
assert_non_null(tmp);
|
||||
ctx->instance = strtoul(json_object_get_string(tmp), NULL, 10);
|
||||
|
||||
assert_int_not_equal((int)ctx->instance, 0);
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_del_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
assert_int_not_equal((int)ctx->instance, 0);
|
||||
|
||||
char path[1024] = {0};
|
||||
snprintf(path, sizeof(path), "Device.Users.User.%lu.", ctx->instance);
|
||||
blobmsg_add_string(bb, "path", path);
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_add_del_handler(uctx, obj, req, "del_object", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
assert_string_equal(json_object_get_string(tmp), path);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "status");
|
||||
assert_string_equal(json_object_get_string(tmp), "true");
|
||||
|
||||
ctx->instance = 0;
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_instances_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "instances", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
|
||||
assert_non_null(jobj);
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
|
||||
assert_string_equal(json_object_get_string(tmp), "Device.Users.User.1");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_instances_Device(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "instances", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
|
||||
assert_non_null(jobj);
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
assert_non_null(array_index_obj);
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_set_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
assert_int_not_equal((int)ctx->instance, 0);
|
||||
|
||||
char path[1024] = {0};
|
||||
snprintf(path, sizeof(path), "Device.Users.User.%lu.Username", ctx->instance);
|
||||
blobmsg_add_string(bb, "path", path);
|
||||
blobmsg_add_string(bb, "value", "user2");
|
||||
|
||||
usp_set(uctx, obj, req, "set", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
tmp = json_object_object_get(jobj, "status");
|
||||
assert_string_equal(json_object_get_string(tmp), "true");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_object_name_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
blobmsg_add_u8(bb, "next-level", true);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "object_names", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
assert_string_equal(json_object_get_string(tmp), "Device.Users.User.1.");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_get_Device_DeviceInfo_Manufacturer(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", GET_PATH);
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
|
||||
assert_string_equal(json_object_get_string(tmp), "Device.DeviceInfo.Manufacturer");
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "value");
|
||||
assert_string_equal(json_object_get_string(tmp), "iopsys");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void test_api_usp_raw_add_object_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
int trans_id;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
trans_id = transaction_start("ut", 0);
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
blobmsg_add_u32(bb, "transaction_id", trans_id);
|
||||
usp_raw_add_del_handler(uctx, obj, req, "add_object", bb->head);
|
||||
transaction_commit(trans_id, NULL, true);
|
||||
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
json_object_object_get_ex(array_index_obj, "status", &tmp);
|
||||
assert_string_equal(json_object_get_string(tmp), "true");
|
||||
|
||||
tmp = NULL;
|
||||
json_object_object_get_ex(array_index_obj, "instance", &tmp);
|
||||
assert_non_null(tmp);
|
||||
ctx->instance = strtoul(json_object_get_string(tmp), NULL, 10);
|
||||
|
||||
assert_int_not_equal((int)ctx->instance, 0);
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void test_api_usp_raw_del_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
int trans_id;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
assert_int_not_equal((int)ctx->instance, 0);
|
||||
|
||||
char path[1024] = {0};
|
||||
snprintf(path, sizeof(path), "Device.Users.User.%lu.", ctx->instance);
|
||||
|
||||
trans_id = transaction_start("ut", 0);
|
||||
blobmsg_add_string(bb, "path", path);
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
blobmsg_add_u32(bb, "transaction_id", trans_id);
|
||||
usp_raw_add_del_handler(uctx, obj, req, "del_object", bb->head);
|
||||
transaction_commit(trans_id, NULL, true);
|
||||
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
assert_string_equal(json_object_get_string(tmp), path);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "status");
|
||||
assert_string_equal(json_object_get_string(tmp), "true");
|
||||
|
||||
ctx->instance = 0;
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_instances_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "instances", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
|
||||
assert_string_equal(json_object_get_string(tmp), "Device.Users.User.1");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_set_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
int trans_id;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
assert_int_not_equal((int)ctx->instance, 0);
|
||||
|
||||
char path[1024] = {0};
|
||||
snprintf(path, sizeof(path), "Device.Users.User.%lu.Username", ctx->instance);
|
||||
|
||||
trans_id = transaction_start("ut", 0);
|
||||
blobmsg_add_string(bb, "path", path);
|
||||
blobmsg_add_string(bb, "value", "user3");
|
||||
blobmsg_add_u32(bb, "transaction_id", trans_id);
|
||||
usp_raw_set(uctx, obj, req, "set", bb->head);
|
||||
transaction_commit(trans_id, NULL, true);
|
||||
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
tmp = json_object_object_get(jobj, "status");
|
||||
if (tmp == NULL) {
|
||||
json_object_put(jobj);
|
||||
}
|
||||
assert_non_null(tmp);
|
||||
assert_string_equal(json_object_get_string(tmp), "true");
|
||||
json_object_put(jobj);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_raw_object_name_Device_Users_User(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp_raw;
|
||||
struct json_object *jobj, *tmp, *array_obj, *array_index_obj;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", "Device.Users.User.");
|
||||
blobmsg_add_string(bb, "proto", GET_PROTO);
|
||||
blobmsg_add_u8(bb, "next-level", true);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "object_names", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
array_obj = json_object_object_get(jobj, "parameters");
|
||||
array_index_obj = json_object_array_get_idx(array_obj, 0);
|
||||
|
||||
tmp = json_object_object_get(array_index_obj, "parameter");
|
||||
assert_string_equal(json_object_get_string(tmp), "Device.Users.User.1.");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
static void test_api_usp_get_cwmp_Device_DeviceInfo_Manufacturer(void **state)
|
||||
{
|
||||
struct test_ctx *ctx = (struct test_ctx *) *state;
|
||||
struct blob_buf *bb = &ctx->bb;
|
||||
struct ubus_object *obj = &ctx->usp;
|
||||
struct json_object *jobj, *tmp;
|
||||
struct ubus_request_data *req = ctx->req;
|
||||
struct ubus_context *uctx = &ctx->uspctx.ubus_ctx;
|
||||
|
||||
blobmsg_add_string(bb, "path", GET_PATH);
|
||||
blobmsg_add_string(bb, "proto", GET_CWMP_PROTO);
|
||||
|
||||
usp_get_handler(uctx, obj, req, "get", bb->head);
|
||||
jobj = json_object_from_file("/tmp/test.log");
|
||||
assert_non_null(jobj);
|
||||
printf("json(%s)\n", json_object_to_json_string(jobj));
|
||||
|
||||
json_object_object_get_ex(jobj, "Manufacturer", &tmp);
|
||||
assert_string_equal(json_object_get_string(tmp), "iopsys");
|
||||
|
||||
json_object_put(jobj);
|
||||
return;
|
||||
}
|
||||
|
||||
// overriding this function
|
||||
int ubus_send_event(struct ubus_context *ctx, const char *id,
|
||||
struct blob_attr *data)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = blobmsg_format_json(data, true);
|
||||
printf("{\"%s\": %s }", id, str);
|
||||
|
||||
free(str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
|
||||
struct blob_attr *msg)
|
||||
{
|
||||
char *str;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen("/tmp/test.log", "w");
|
||||
if (!fp) {
|
||||
printf("failed to open file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
str = blobmsg_format_json_indent(msg, true, -1);
|
||||
fprintf(fp, "%s", str);
|
||||
|
||||
fclose(fp);
|
||||
free(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
// usp object test cases
|
||||
cmocka_unit_test_setup(test_api_usp_list_operate, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_Device_DeviceInfo_Manufacturer, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_Device_WiFi_SSID, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_search_exp_Device_WiFi_SSID, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_instances_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_instances_Device, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_resolve_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_add_object_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_set_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_del_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_object_name_Device_Users_User, setup),
|
||||
// usp.raw object test cases
|
||||
cmocka_unit_test_setup(test_api_usp_raw_dump_schema, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_get_Device_DeviceInfo_Manufacturer, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_getm_values_Device_WiFi_SSID_Alias, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_getm_names_Device_WiFi_SSID_Alias, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_instances_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_resolve_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_add_object_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_set_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_del_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_raw_object_name_Device_Users_User, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_cwmp_Device_DeviceInfo_Manufacturer, setup),
|
||||
|
||||
// -ve scenerios
|
||||
cmocka_unit_test_setup(test_api_usp_get_DeviceInfo_Manufacturer, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_wrong_oper_Device_WiFi_SSID, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_Device_IP_Interface, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_wrong_exp_Device_IP_Interface, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_wrong_braces_Device_IP_Interface, setup),
|
||||
cmocka_unit_test_setup(test_api_usp_get_wrong_name_Device_IP_Interface, setup)
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, group_setup, group_teardown);
|
||||
}
|
||||
|
||||
132
bbfd/test/files/etc/bbfdm/json/transferComplete.json
Normal file
132
bbfd/test/files/etc/bbfdm/json/transferComplete.json
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"Device.LocalAgent.": {
|
||||
"type": "object",
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"access": false,
|
||||
"array": false,
|
||||
"TransferComplete!": {
|
||||
"type": "event",
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"Command": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "string"
|
||||
},
|
||||
"CommandKey": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "string"
|
||||
},
|
||||
"Requestor": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "string"
|
||||
},
|
||||
"TransferType": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "string",
|
||||
"enumerations": [
|
||||
"Download",
|
||||
"Upload"
|
||||
]
|
||||
},
|
||||
"Affected": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "string"
|
||||
},
|
||||
"TransferURL": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "URL",
|
||||
"range": [
|
||||
{
|
||||
"max": 2048
|
||||
}
|
||||
]
|
||||
},
|
||||
"StartTime": {
|
||||
"type": "dateTime",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "dateTime"
|
||||
},
|
||||
"CompleteTime": {
|
||||
"type": "dateTime",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "dateTime"
|
||||
},
|
||||
"FaultCode": {
|
||||
"type": "unsignedInt",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "unsignedInt"
|
||||
},
|
||||
"FaultString": {
|
||||
"type": "string",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"version": "2.12",
|
||||
"protocols": [
|
||||
"usp"
|
||||
],
|
||||
"datatype": "string",
|
||||
"range": [
|
||||
{
|
||||
"max": 256
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
bbfd/test/files/etc/board-db/config/device
Normal file
11
bbfd/test/files/etc/board-db/config/device
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
config deviceinfo 'deviceinfo'
|
||||
option Manufacturer 'iopsys'
|
||||
option ProductClass 'FirstClass'
|
||||
option SerialNumber '000000001'
|
||||
option SoftwareVersion 'IOPSYS-CODE-ANALYSIS'
|
||||
option HardwareVersion '1.0'
|
||||
option DeviceCategory 'Gateway'
|
||||
option ModelName 'ModelName'
|
||||
option Description 'Iopsys code analysis test simulator'
|
||||
option ManufacturerOUI 'XXX'
|
||||
option BaseMACAddress 'feeddeadbeef'
|
||||
185
bbfd/test/files/etc/config/firewall
Normal file
185
bbfd/test/files/etc/config/firewall
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
|
||||
config globals 'globals'
|
||||
option enabled '1'
|
||||
|
||||
config defaults
|
||||
option syn_flood '1'
|
||||
option input 'ACCEPT'
|
||||
option output 'ACCEPT'
|
||||
option forward 'REJECT'
|
||||
|
||||
config zone
|
||||
option name 'lan'
|
||||
list network 'lan'
|
||||
option input 'ACCEPT'
|
||||
option output 'ACCEPT'
|
||||
option forward 'ACCEPT'
|
||||
|
||||
config zone
|
||||
option name 'wan'
|
||||
list network 'wan'
|
||||
list network 'wan6'
|
||||
option input 'REJECT'
|
||||
option output 'ACCEPT'
|
||||
option forward 'REJECT'
|
||||
option masq '1'
|
||||
option mtu_fix '1'
|
||||
|
||||
config forwarding
|
||||
option src 'lan'
|
||||
option dest 'wan'
|
||||
|
||||
config rule
|
||||
option name 'Allow-DHCP-Renew'
|
||||
option src 'wan'
|
||||
option proto 'udp'
|
||||
option dest_port '68'
|
||||
option target 'ACCEPT'
|
||||
option family 'ipv4'
|
||||
|
||||
config rule
|
||||
option name 'Allow-Ping'
|
||||
option src 'wan'
|
||||
option proto 'icmp'
|
||||
option icmp_type 'echo-request'
|
||||
option family 'ipv4'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-IGMP'
|
||||
option src 'wan'
|
||||
option proto 'igmp'
|
||||
option family 'ipv4'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-DHCPv6'
|
||||
option src 'wan'
|
||||
option proto 'udp'
|
||||
option src_ip 'fc00::/6'
|
||||
option dest_ip 'fc00::/6'
|
||||
option dest_port '546'
|
||||
option family 'ipv6'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-MLD'
|
||||
option src 'wan'
|
||||
option proto 'icmp'
|
||||
option src_ip 'fe80::/10'
|
||||
list icmp_type '130/0'
|
||||
list icmp_type '131/0'
|
||||
list icmp_type '132/0'
|
||||
list icmp_type '143/0'
|
||||
option family 'ipv6'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-ICMPv6-Input'
|
||||
option src 'wan'
|
||||
option proto 'icmp'
|
||||
list icmp_type 'echo-request'
|
||||
list icmp_type 'echo-reply'
|
||||
list icmp_type 'destination-unreachable'
|
||||
list icmp_type 'packet-too-big'
|
||||
list icmp_type 'time-exceeded'
|
||||
list icmp_type 'bad-header'
|
||||
list icmp_type 'unknown-header-type'
|
||||
list icmp_type 'router-solicitation'
|
||||
list icmp_type 'neighbour-solicitation'
|
||||
list icmp_type 'router-advertisement'
|
||||
list icmp_type 'neighbour-advertisement'
|
||||
option limit '1000/sec'
|
||||
option family 'ipv6'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-ICMPv6-Forward'
|
||||
option src 'wan'
|
||||
option dest '*'
|
||||
option proto 'icmp'
|
||||
list icmp_type 'echo-request'
|
||||
list icmp_type 'echo-reply'
|
||||
list icmp_type 'destination-unreachable'
|
||||
list icmp_type 'packet-too-big'
|
||||
list icmp_type 'time-exceeded'
|
||||
list icmp_type 'bad-header'
|
||||
list icmp_type 'unknown-header-type'
|
||||
option limit '1000/sec'
|
||||
option family 'ipv6'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-IPSec-ESP'
|
||||
option src 'wan'
|
||||
option dest 'lan'
|
||||
option proto 'esp'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-ISAKMP'
|
||||
option src 'wan'
|
||||
option dest 'lan'
|
||||
option dest_port '500'
|
||||
option proto 'udp'
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Support-UDP-Traceroute'
|
||||
option src 'wan'
|
||||
option dest_port '33434:33689'
|
||||
option proto 'udp'
|
||||
option family 'ipv4'
|
||||
option target 'REJECT'
|
||||
option enabled 'false'
|
||||
|
||||
config dmz 'dmz'
|
||||
option enabled '0'
|
||||
option exclude_ports '5060 7547'
|
||||
|
||||
config include
|
||||
option path '/etc/firewall.user'
|
||||
option reload '1'
|
||||
|
||||
config include 'ddos'
|
||||
option path '/etc/firewall.ddos'
|
||||
option reload '1'
|
||||
|
||||
config include 'parental'
|
||||
option path '/etc/firewall.parental'
|
||||
option reload '1'
|
||||
|
||||
config include 'qos'
|
||||
option path '/etc/firewall.qos'
|
||||
option reload '1'
|
||||
|
||||
config include 'cwmp'
|
||||
option path '/etc/firewall.cwmp'
|
||||
option reload '1'
|
||||
|
||||
config include 'miniupnpd'
|
||||
option type 'script'
|
||||
option path '/usr/share/miniupnpd/firewall.include'
|
||||
option family 'any'
|
||||
option reload '1'
|
||||
|
||||
config include 'sip'
|
||||
option path '/etc/firewall.sip'
|
||||
option reload '1'
|
||||
|
||||
config include 'dmzhost'
|
||||
option path '/etc/firewall.dmz'
|
||||
option reload '1'
|
||||
|
||||
config redirect 'port_mapping_1'
|
||||
option enabled '1'
|
||||
option src 'wan'
|
||||
option dest 'lan'
|
||||
option target 'DNAT'
|
||||
option reflection '1'
|
||||
option name 'test'
|
||||
option proto 'tcp'
|
||||
option dest_ip 'wan'
|
||||
option src_dport '192.168.3.45'
|
||||
option src_dport '50:60'
|
||||
option dest_port '44'
|
||||
123
bbfd/test/files/etc/config/network
Normal file
123
bbfd/test/files/etc/config/network
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
config interface 'loopback'
|
||||
option device 'lo'
|
||||
option proto 'static'
|
||||
option ipaddr '127.0.0.1'
|
||||
option netmask '255.0.0.0'
|
||||
|
||||
config globals 'globals'
|
||||
option ula_prefix 'fddb:7949:7caa::/48'
|
||||
|
||||
config device
|
||||
option name 'br-lan'
|
||||
option type 'bridge'
|
||||
list ports 'eth1'
|
||||
list ports 'eth2'
|
||||
list ports 'eth3'
|
||||
list ports 'eth4'
|
||||
option macaddr '44:D4:37:71:B8:11'
|
||||
|
||||
config interface 'lan'
|
||||
option device 'br-lan'
|
||||
option proto 'static'
|
||||
option ipaddr '192.168.1.1'
|
||||
option netmask '255.255.255.0'
|
||||
option ip6assign '60'
|
||||
option is_lan '1'
|
||||
option macaddr '44:D4:37:71:B8:11'
|
||||
|
||||
config interface 'wan'
|
||||
option proto 'dhcp'
|
||||
option hostname 'iopsysWrt-44D43771B810'
|
||||
option vendorid 'eg400'
|
||||
option device 'eth0.1'
|
||||
option reqopts '12 43'
|
||||
option sendopts '60:iopsystest 61:iopsys'
|
||||
option macaddr '44:D4:37:71:B8:12'
|
||||
|
||||
config interface 'wan6'
|
||||
option proto 'dhcpv6'
|
||||
option device '@wan'
|
||||
|
||||
config device 'ethwan'
|
||||
option type 'untagged'
|
||||
option ifname 'eth0'
|
||||
option name 'eth0.1'
|
||||
option macaddr '44:D4:37:71:B8:12'
|
||||
|
||||
config device 'br_test_1'
|
||||
option name 'br-test'
|
||||
option type 'bridge'
|
||||
list ports 'eth1.100'
|
||||
list ports 'eth2.100'
|
||||
list ports 'eth3.100'
|
||||
list ports 'eth4.100'
|
||||
option macaddr '44:D4:37:71:B8:13'
|
||||
|
||||
config interface 'lan100'
|
||||
option device 'br-test'
|
||||
option proto 'static'
|
||||
option ipaddr '172.32.1.1'
|
||||
option macaddr '44:D4:37:71:B8:13'
|
||||
|
||||
config device 'eth1_100'
|
||||
option type 'untagged'
|
||||
option ifname 'eth1'
|
||||
option name 'eth1.100'
|
||||
option vid '100'
|
||||
|
||||
config device 'eth2_100'
|
||||
option type 'untagged'
|
||||
option ifname 'eth2'
|
||||
option name 'eth2.100'
|
||||
option vid '100'
|
||||
|
||||
config device 'eth3_100'
|
||||
option type '8021q'
|
||||
option ifname 'eth3'
|
||||
option name 'eth3.100'
|
||||
option vid '100'
|
||||
|
||||
config device 'eth4_100'
|
||||
option type '8021q'
|
||||
option ifname 'eth4'
|
||||
option name 'eth4.100'
|
||||
option vid '100'
|
||||
|
||||
config interface 'ppp_wan'
|
||||
option type 'anywan'
|
||||
option proto 'pppoe'
|
||||
option username 'iopsyshome@iopsys.eu'
|
||||
option password 'iopsys'
|
||||
option device 'eth0.1'
|
||||
option ipv6 '1'
|
||||
option macaddr '44:D4:37:71:B8:14'
|
||||
|
||||
config route 'route4'
|
||||
option interface 'wan'
|
||||
option target '0.0.0.0/0'
|
||||
option gateway '10.72.197.110'
|
||||
|
||||
config route6 'route6'
|
||||
option interface 'wan6'
|
||||
option target '::/0'
|
||||
|
||||
config interface 'stabridge'
|
||||
option proto 'relay'
|
||||
option network 'lan wan'
|
||||
|
||||
config interface 'mygre'
|
||||
option ipaddr '10.1.1.1'
|
||||
option peeraddr '10.2.2.1'
|
||||
option proto 'gre'
|
||||
|
||||
config interface 'mygre_static'
|
||||
option proto 'static'
|
||||
option device '@mygre'
|
||||
option ipaddr '172.16.12.1'
|
||||
option netmask '255.255.255.252'
|
||||
|
||||
config route 'tunnel'
|
||||
option interface 'mygre_static'
|
||||
option target '172.16.2.0'
|
||||
option netmask '255.255.255.0'
|
||||
option gateway '172.16.12.2'
|
||||
7
bbfd/test/files/etc/config/users
Normal file
7
bbfd/test/files/etc/config/users
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
config user 'user'
|
||||
option enabled '1'
|
||||
option remote_access '1'
|
||||
list _access_w 'admin'
|
||||
list _access_w 'support'
|
||||
list _access_w 'user'
|
||||
6
bbfd/test/files/etc/config/uspd
Normal file
6
bbfd/test/files/etc/config/uspd
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
config uspd 'usp'
|
||||
option granularitylevel '0'
|
||||
option debug '1'
|
||||
option loglevel '2'
|
||||
option subprocess_level '1'
|
||||
option refresh_time '0'
|
||||
56
bbfd/test/files/etc/config/wireless
Normal file
56
bbfd/test/files/etc/config/wireless
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
config wifi-device 'test1'
|
||||
option type 'mac80211'
|
||||
option channel '36'
|
||||
option hwmode '11a'
|
||||
option country 'DE'
|
||||
option htmode 'HE80'
|
||||
option apsta '0'
|
||||
option phy 'phy0'
|
||||
|
||||
config wifi-iface 'no_mp_test1'
|
||||
option device 'test1'
|
||||
option network 'lan'
|
||||
option mode 'ap'
|
||||
option ifname 'test1'
|
||||
option encryption 'psk2'
|
||||
option wps_pushbutton '1'
|
||||
option ieee80211k '1'
|
||||
option ieee80211v '1'
|
||||
option bss_transition '1'
|
||||
option ssid 'NON-MULTI-AP-TEST'
|
||||
|
||||
config wifi-iface 'default_test1'
|
||||
option device 'test1'
|
||||
option network 'lan'
|
||||
option mode 'ap'
|
||||
option ifname 'test1'
|
||||
option ssid 'MAP-44D43771B810-BH-5GHz'
|
||||
option encryption 'psk2'
|
||||
option wps_pushbutton '1'
|
||||
option ieee80211k '1'
|
||||
option ieee80211v '1'
|
||||
option bss_transition '1'
|
||||
option multi_ap '3'
|
||||
|
||||
config wifi-device 'test2'
|
||||
option type 'mac80211'
|
||||
option channel '11'
|
||||
option hwmode '11g'
|
||||
option country 'DE'
|
||||
option htmode 'HE20'
|
||||
option apsta '0'
|
||||
option phy 'phy1'
|
||||
|
||||
config wifi-iface 'default_test2'
|
||||
option device 'test2'
|
||||
option network 'lan'
|
||||
option mode 'ap'
|
||||
option ifname 'test2'
|
||||
option ssid 'iopsysWrt-44D43771B810'
|
||||
option encryption 'psk2'
|
||||
option key 'MPUEO3L7WHJ45P'
|
||||
option wps_pushbutton '1'
|
||||
option ieee80211k '1'
|
||||
option ieee80211v '1'
|
||||
option bss_transition '1'
|
||||
option multi_ap '2'
|
||||
25
bbfd/test/files/etc/init.d/uspd
Executable file
25
bbfd/test/files/etc/init.d/uspd
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=94
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/uspd
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command ${PROG}
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "cwmp"
|
||||
procd_add_config_trigger "config.change" "uspd" /etc/init.d/uspd restart
|
||||
}
|
||||
13
bbfd/test/funl/json/gran/gran.validation.json
Normal file
13
bbfd/test/funl/json/gran/gran.validation.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"object": "usp.Device.",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Users."
|
||||
},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
350
bbfd/test/funl/json/usp.raw.validation.json
Normal file
350
bbfd/test/funl/json/usp.raw.validation.json
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
{
|
||||
"object": "usp.raw",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "both"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1",
|
||||
"next-level": true
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#1+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#*+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Stats.PacketsSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[BytesSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable==true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable!=true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.[Enable==0].Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.*.Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort==68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort!=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order==1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order!=1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>=8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<=2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference+.Alias==\"cpe-1\"].AssociatedDeviceNumberOfEntries"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference#1+.Alias==\"cpe-1\"].WPS.ConfigMethodsSupported"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.[Enable==0].Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.*.Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "hello",
|
||||
"rc": 3
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.SSID",
|
||||
"value": "test-2g",
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"iopsys.eu"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "dump_schema",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "list_operate",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_commit",
|
||||
"args": {
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_abort",
|
||||
"args": {
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "getm_names",
|
||||
"args": {
|
||||
"paths": ["Device.WiFi.SSID.1.SSID","Device.WiFi.SSID.2.SSID"],
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "setm_values",
|
||||
"args": {
|
||||
"pv_tuple": [{"path":"Device.Users.User.1.Alias", "value":"cpe-1"}, {"path":"Device.Users.User.2.Alias", "value":"cpe-2"}],
|
||||
"proto": "usp",
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
463
bbfd/test/funl/json/usp.validation.json
Normal file
463
bbfd/test/funl/json/usp.validation.json
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
{
|
||||
"object": "usp",
|
||||
"methods": [
|
||||
{
|
||||
"method": "list_operate",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "both"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1",
|
||||
"next-level": true
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#1+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#*+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.IP.Interface.*.IPv4Address.*.AddressingType"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Stats.PacketsSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[BytesSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable==true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable!=true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.[Enable==0].Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.*.Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort==68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort!=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order==1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order!=1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>=8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<=2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Status>\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.{Status==\"Up\"}.Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference+.Alias==\"cpe-1\"].AssociatedDeviceNumberOfEntries"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference#1+.Alias==\"cpe-1\"].WPS.ConfigMethodsSupported"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference#*+.Alias==\"cpe-1\"].WPS.ConfigMethodsSupported"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.Stats.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "validate",
|
||||
"args": {
|
||||
"path": "Device.Users.User.1.Alias",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "validate",
|
||||
"args": {
|
||||
"path": "Device.Users.User.1.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "validate",
|
||||
"args": {
|
||||
"path": "Device.Users.User.*.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.SSID",
|
||||
"value": "test-1g"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.Users.User.1.",
|
||||
"values": {"username":"funl-test", "password":"ft1234"}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.Firewall.Chain.1.Rule.1.",
|
||||
"values": {"DestPortRangeMax":"5"}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.Firewall.Chain.1.Rule.1.",
|
||||
"values": {"Order":"7"}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.Firewall.Chain.1.Rule.1.",
|
||||
"values": {"DestPortRangeMax":5}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"iopsys.eu"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"iopsys.eu",
|
||||
"Host":"localhost"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.",
|
||||
"action":"NeighboringWiFiDiagnostic()"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.WiFi",
|
||||
"action":""
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "add_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "del_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.[Username>admin].",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "del_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.2.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1183
bbfd/test/funl/schema/usp.raw_test_negative.json
Normal file
1183
bbfd/test/funl/schema/usp.raw_test_negative.json
Normal file
File diff suppressed because it is too large
Load diff
1383
bbfd/test/funl/schema/usp.raw_test_positive.json
Normal file
1383
bbfd/test/funl/schema/usp.raw_test_positive.json
Normal file
File diff suppressed because it is too large
Load diff
338
bbfd/test/funl/schema/usp_test_negative.json
Normal file
338
bbfd/test/funl/schema/usp_test_negative.json
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
{
|
||||
"definitions": {
|
||||
"path_t": {
|
||||
"description": "Complete object element path as per TR181",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.1.",
|
||||
"Device.WiFi."
|
||||
]
|
||||
},
|
||||
"schema_path_t": {
|
||||
"description": "Datamodel object schema path",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.Bridging.Bridge.{i}.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.{i}.SSID"
|
||||
]
|
||||
},
|
||||
"boolean_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"0",
|
||||
"1"
|
||||
]
|
||||
},
|
||||
"operate_path_t": {
|
||||
"description": "Datamodel object schema path",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.DHCPv4.Client.{i}.Renew()",
|
||||
"Device.FactoryReset()"
|
||||
]
|
||||
},
|
||||
"operate_type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"query_path_t": {
|
||||
"description": "DM object path with search queries",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.[SSID==\"test_ssid\"].BSSID",
|
||||
"Device.WiFi.SSID.*.BSSID",
|
||||
"Device.WiFi.SSID.[SSID!=\"test_ssid\"&&Enable==1].BSSID",
|
||||
"Device.WiFi."
|
||||
]
|
||||
},
|
||||
"instance_t": {
|
||||
"description": "Multi object instances",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 256
|
||||
},
|
||||
"proto_t": {
|
||||
"type": "string",
|
||||
"default": "both",
|
||||
"enum": [
|
||||
"usp",
|
||||
"cwmp",
|
||||
"both"
|
||||
]
|
||||
},
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"xsd:string",
|
||||
"xsd:unsignedInt",
|
||||
"xsd:int",
|
||||
"xsd:unsignedLong",
|
||||
"xsd:long",
|
||||
"xsd:boolean",
|
||||
"xsd:dateTime",
|
||||
"xsd:hexBinary",
|
||||
"xsd:object"
|
||||
]
|
||||
},
|
||||
"fault_t": {
|
||||
"type": "integer",
|
||||
"minimum": 7000,
|
||||
"maximum": 9050
|
||||
}
|
||||
},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://dev.iopsys.eu/iopsys/uspd/-/blob/devel/docs/api/usp.md",
|
||||
"type": "object",
|
||||
"title": "usp",
|
||||
"object": "usp",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"get": {
|
||||
"title": "Get handler",
|
||||
"description": "Query the datamodel object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"maxdepth": {
|
||||
"type": "integer",
|
||||
"description": "Integer to decide the depth of data model to be parsed"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"required": [
|
||||
"fault"
|
||||
],
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
"title": "Set handler",
|
||||
"description": "Set values of datamodel object element",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"values": {
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"fault"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean",
|
||||
"const": false
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"add_object": {
|
||||
"title": "Add a new object instance",
|
||||
"description": "Add a new object in multi instance object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"status",
|
||||
"fault"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"del_object": {
|
||||
"title": "Delete object instance",
|
||||
"description": "Delete a object instance from multi instance object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"fault"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"fault": {
|
||||
"$ref": "#/definitions/fault_t"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
315
bbfd/test/funl/schema/usp_test_positive.json
Normal file
315
bbfd/test/funl/schema/usp_test_positive.json
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
{
|
||||
"definitions": {
|
||||
"path_t": {
|
||||
"description": "Complete object element path as per TR181",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.1.",
|
||||
"Device.WiFi."
|
||||
]
|
||||
},
|
||||
"schema_path_t": {
|
||||
"description": "Datamodel object schema path",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.Bridging.Bridge.{i}.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.{i}.SSID"
|
||||
]
|
||||
},
|
||||
"boolean_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"0",
|
||||
"1"
|
||||
]
|
||||
},
|
||||
"operate_path_t": {
|
||||
"description": "Datamodel object schema path",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.DHCPv4.Client.{i}.Renew()",
|
||||
"Device.FactoryReset()"
|
||||
]
|
||||
},
|
||||
"operate_type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"query_path_t": {
|
||||
"description": "DM object path with search queries",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 1024,
|
||||
"examples": [
|
||||
"Device.",
|
||||
"Device.DeviceInfo.Manufacturer",
|
||||
"Device.WiFi.SSID.[SSID==\"test_ssid\"].BSSID",
|
||||
"Device.WiFi.SSID.*.BSSID",
|
||||
"Device.WiFi.SSID.[SSID!=\"test_ssid\"&&Enable==1].BSSID",
|
||||
"Device.WiFi."
|
||||
]
|
||||
},
|
||||
"instance_t": {
|
||||
"description": "Multi object instances",
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 256
|
||||
},
|
||||
"proto_t": {
|
||||
"type": "string",
|
||||
"default": "both",
|
||||
"enum": [
|
||||
"usp",
|
||||
"cwmp",
|
||||
"both"
|
||||
]
|
||||
},
|
||||
"type_t": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"xsd:string",
|
||||
"xsd:unsignedInt",
|
||||
"xsd:int",
|
||||
"xsd:unsignedLong",
|
||||
"xsd:long",
|
||||
"xsd:boolean",
|
||||
"xsd:dateTime",
|
||||
"xsd:hexBinary",
|
||||
"xsd:object"
|
||||
]
|
||||
},
|
||||
"fault_t": {
|
||||
"type": "integer",
|
||||
"minimum": 7000,
|
||||
"maximum": 9050
|
||||
}
|
||||
},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://dev.iopsys.eu/iopsys/uspd/-/blob/devel/docs/api/usp.md",
|
||||
"type": "object",
|
||||
"title": "usp",
|
||||
"object": "usp",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"get": {
|
||||
"title": "Get handler",
|
||||
"description": "Query the datamodel object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"maxdepth": {
|
||||
"type": "integer",
|
||||
"description": "Integer to decide the depth of data model to be parsed"
|
||||
},
|
||||
"next-level": {
|
||||
"type": "boolean",
|
||||
"description": "gets only next level objects if true"
|
||||
},
|
||||
"instance-mode": {
|
||||
"type": "integer",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
"title": "Set handler",
|
||||
"description": "Set values of datamodel object element",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"values": {
|
||||
"description": "To set multiple values at once, path should be relative to object elements",
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"add_object": {
|
||||
"title": "Add a new object instance",
|
||||
"description": "Add a new object in multi instance object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"status",
|
||||
"instance"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"instance": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"del_object": {
|
||||
"title": "Delete object instance",
|
||||
"description": "Delete a object instance from multi instance object",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"input",
|
||||
"output"
|
||||
],
|
||||
"properties": {
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/query_path_t"
|
||||
},
|
||||
"proto": {
|
||||
"$ref": "#/definitions/proto_t"
|
||||
},
|
||||
"instance_mode": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parameter",
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
"parameter": {
|
||||
"$ref": "#/definitions/path_t"
|
||||
},
|
||||
"status": {
|
||||
"type": "boolean",
|
||||
"const": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
bbfd/test/funl/validation/usp.raw.validation.negative.json
Normal file
64
bbfd/test/funl/validation/usp.raw.validation.negative.json
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"object": "usp.raw",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.InvalidPath",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.InvalidPath",
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.InvalidUser.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.InvalidPath",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"iopsys.eu"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "getm_names",
|
||||
"args": {
|
||||
"paths": ["Device.WiFi.SSID.1.Invalid","Device.WiFi.SSID.2.Invalid"],
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.Invalid",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
368
bbfd/test/funl/validation/usp.raw.validation.positive.json
Normal file
368
bbfd/test/funl/validation/usp.raw.validation.positive.json
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
{
|
||||
"object": "usp.raw",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "both"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1",
|
||||
"next-level": true
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#1+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#*+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Stats.PacketsSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[BytesSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable==true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable!=true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.[Enable==0].Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.*.Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort==68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort!=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order==1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order!=1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>=8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<=2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference+.Alias==\"cpe-1\"].AssociatedDeviceNumberOfEntries"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference#1+.Alias==\"cpe-1\"].WPS.ConfigMethodsSupported"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.[Enable==0].Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.*.Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "hello",
|
||||
"rc": 3
|
||||
},
|
||||
{
|
||||
"method": "instances",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.SSID",
|
||||
"value": "test-2g",
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "object_names",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"iopsys.eu"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "dump_schema",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "list_operate",
|
||||
"args": {},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get_supported_dm",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.",
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "operate",
|
||||
"args": {
|
||||
"path":"Device.IP.Diagnostics.",
|
||||
"action":"IPPing()",
|
||||
"input":{
|
||||
"Host":"iopsys.eu"
|
||||
}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_commit",
|
||||
"args": {
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "transaction_abort",
|
||||
"args": {
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "getm_names",
|
||||
"args": {
|
||||
"paths": ["Device.WiFi.SSID.1.SSID","Device.WiFi.SSID.2.SSID"],
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "setm_values",
|
||||
"args": {
|
||||
"pv_tuple": [{"path":"Device.Users.User.1.Alias", "value":"cpe-1"}, {"path":"Device.Users.User.2.Alias", "value":"cpe-2"}],
|
||||
"proto": "usp",
|
||||
"transaction_id": 123
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
62
bbfd/test/funl/validation/usp.validation.negative.json
Normal file
62
bbfd/test/funl/validation/usp.validation.negative.json
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"object": "usp",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Invalid",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.Invalid",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Invalid",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.Invalid",
|
||||
"value": "test-1g"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "add_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.Invalid",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "del_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.Invalid.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "del_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.[Username>admin].",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
323
bbfd/test/funl/validation/usp.validation.positive.json
Normal file
323
bbfd/test/funl/validation/usp.validation.positive.json
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
{
|
||||
"object": "usp",
|
||||
"methods": [
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias",
|
||||
"proto": "cwmp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "both"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path": "Device.DeviceInfo.Manufacturer",
|
||||
"proto": "usp",
|
||||
"maxdepth": "1",
|
||||
"next-level": true
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#1+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Users.User.*.Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.1.LowerLayers#*+.Name"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.IP.Interface.*.IPv4Address.*.AddressingType"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Status==\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[SSID==\"test-2g\"&&Stats.PacketsSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[BytesSent>0].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable==true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Enable!=true].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.[Enable==0].Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.USB.USBHosts.Host.*.Device."
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort==68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort!=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort>=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[DestPort<=68].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order==1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order!=1].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order>=8].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.Firewall.Chain.1.Rule.[Order<=2].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[Status>\"Up\"].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.{Status==\"Up\"}.Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.SSID.[].Alias"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference+.Alias==\"cpe-1\"].AssociatedDeviceNumberOfEntries"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference#1+.Alias==\"cpe-1\"].WPS.ConfigMethodsSupported"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "get",
|
||||
"args": {
|
||||
"path":"Device.WiFi.AccessPoint.[SSIDReference#*+.Alias==\"cpe-1\"].WPS.ConfigMethodsSupported"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.WiFi.SSID.1.SSID",
|
||||
"value": "test-1g"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "set",
|
||||
"args": {
|
||||
"path": "Device.Firewall.Chain.1.Rule.1.",
|
||||
"values": {"Order":"7"}
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
{
|
||||
"method": "add_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
},
|
||||
|
||||
{
|
||||
"method": "del_object",
|
||||
"args": {
|
||||
"path": "Device.Users.User.2.",
|
||||
"proto": "usp"
|
||||
},
|
||||
"rc": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
52
bbfd/test/libuspd_test.c
Normal file
52
bbfd/test/libuspd_test.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2021 iopsys Software Solutions AB
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* Author: Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
|
||||
*/
|
||||
|
||||
/* This file is used for validating USPD max msg len using libbbf APIs */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <libbbf_api/dmbbf.h>
|
||||
#include <libbbf_api/dmcommon.h>
|
||||
|
||||
#ifndef DEF_IPC_DATA_LEN
|
||||
#define DEF_IPC_DATA_LEN (1024 * 1024 - 128)
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* GET PARAM
|
||||
**************************************************************/
|
||||
static int get_X_IOPSYS_EU_testUSPDParam_TestText(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
char *ptr = (char *)calloc(1, DEF_IPC_DATA_LEN);
|
||||
if (ptr == NULL) {
|
||||
*value = "";
|
||||
return 0;
|
||||
}
|
||||
memset(ptr, 'a', DEF_IPC_DATA_LEN - 1);
|
||||
dmasprintf(value, ptr);
|
||||
free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************
|
||||
* OBJ & PARAM DEFINITION
|
||||
***********************************************************************************************************************************/
|
||||
/*** Device. ***/
|
||||
DMLEAF tX_IOPSYS_EU_testUSPDParam[] = {
|
||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
|
||||
{"X_IOPSYS_EU_TestText", &DMREAD, DMT_STRING, get_X_IOPSYS_EU_testUSPDParam_TestText, NULL, BBFDM_BOTH},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* ********** DynamicObj ********** */
|
||||
DM_MAP_OBJ tDynamicObj[] = {
|
||||
/* parentobj, nextobject, parameter */
|
||||
{"Device.", NULL, tX_IOPSYS_EU_testUSPDParam},
|
||||
{0}
|
||||
};
|
||||
27
bbfd/test/python/validate_3272.py
Executable file
27
bbfd/test/python/validate_3272.py
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
TEST_NAME = "BUG_3272"
|
||||
|
||||
print("Running: " + TEST_NAME)
|
||||
|
||||
def usp_get(path, proto = ""):
|
||||
path_arg = "{\"path\":\"" + path + "\",\"proto\":\"" + proto + "\"}"
|
||||
cmd = ['ubus', 'call', 'usp.raw', 'get', path_arg]
|
||||
|
||||
out = subprocess.Popen(cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
stdout,stderr = out.communicate()
|
||||
return stdout
|
||||
|
||||
# check fault code of invalid path
|
||||
output = json.loads(usp_get("Device.USB.USBHosts.Host.[Enable==0].Device."))
|
||||
|
||||
for param in enumerate(output["parameters"]):
|
||||
assert param[1]["parameter"].endswith("DeviceNumberOfEntries") == False, "FAIL" + TEST_NAME
|
||||
|
||||
print("PASS: " + TEST_NAME)
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue