Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
jedi
smrtlink
Commits
3aa3cee6
Commit
3aa3cee6
authored
Oct 17, 2015
by
/jdi/
Browse files
json parser
parent
b1c5a3af
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/Options.h
View file @
3aa3cee6
...
...
@@ -25,23 +25,24 @@
-u --user <[password:]username>\n\
-p --password <password>\n\
Login with Username and Password\n\
-f --file <path>
Not yet implemented:.
choose a settings file\n\
-f --file <path> choose a settings file\n\
-t --timeout <n> Not yet implemented\n\
-w --wait Not yet implemented: blocking until operation is completed\n\
-s --permanent Not yet implemented: make changes immediately permanent\n\n\
Command Summary:\n\
help This help text\n\
list list all connected switches\n\
sniff capture and display all incoming or outgoing packets\n\
depending on the --reverse option\n\
encode use encoding algorithm on hex data separated by colon\n\
get Not yet implemented\n\
set Not yet implemented\n\
save Not yet implemented: save config to file\n\
restore Not yet implemented: restore onfig from file\n\
flash Not yet implemented: replace firmware\n\
reboot Not yet implemented\n\
reset Not yet implemented\n\n\
help This help text\n\
list list all connected switches\n\
sniff [type:<type>] [<filter>]\n\
capture and display all incoming or outgoing packets\n\
depending on the --reverse option\n\
encode use encoding algorithm on hex data separated by colon\n\
get Not yet implemented\n\
set Not yet implemented\n\
save Not yet implemented: save config to file\n\
restore Not yet implemented: restore onfig from file\n\
flash Not yet implemented: replace firmware\n\
reboot Not yet implemented\n\
reset Not yet implemented\n\n\
### for questions please contact <smrtlink@jdi.li> ###\n\n"
#define FLAG_HEX 1
...
...
src/Packet.cpp
View file @
3aa3cee6
...
...
@@ -143,8 +143,10 @@ std::string Packet::opCodeToString() {
return
"GET"
;
case
SET
:
return
"SET"
;
case
RECEIVE
:
return
"RECEIVE"
;
case
LOGIN
:
return
"LOGIN"
;
case
RETURN
:
return
"RETURN"
;
case
READ5
:
return
"READ5"
;
default:
...
...
src/Packet.h
View file @
3aa3cee6
...
...
@@ -16,7 +16,7 @@
class
Packet
{
public:
enum
OpCode
{
DISCOVERY
,
GET
,
SET
,
READ4
,
RECEIVE
,
READ5
DISCOVERY
,
GET
,
SET
,
LOGIN
,
RETURN
,
READ5
};
Packet
(
OpCode
);
void
encode
(
bytes
&
);
...
...
src/Program.cpp
View file @
3aa3cee6
...
...
@@ -9,6 +9,7 @@
#include "Options.h"
#include "Program.h"
#include "File.h"
#include "Host.h"
#include "Socket.h"
#include "Switch.h"
...
...
@@ -45,6 +46,8 @@ int Program::list() {
datasets
d
=
a
.
getPayload
();
Switch
s
=
Switch
();
s
.
parse
(
d
);
File
f
;
f
.
write
(
"config.json"
,
s
.
toString
());
std
::
cout
<<
"Devices:
\n\t
"
<<
s
.
settings
.
hostname
<<
" ("
<<
s
.
device
.
type
<<
")
\t
MAC: "
<<
s
.
device
.
mac
<<
"
\t
IP: "
<<
s
.
settings
.
ip_addr
<<
"
\n
"
;
}
return
1
;
...
...
@@ -83,7 +86,7 @@ int Program::sniff() {
auto
lookup
=
(
options
.
flags
&
FLAG_REVERSE
)
?
snd_lookup
:
rcv_lookup
;
if
(
lookup
.
exists
(
d
.
type
))
{
if
(
d
.
len
>
0
)
{
std
::
cout
<<
std
::
dec
<<
"
\t
++"
<<
std
::
hex
<<
d
.
type
<<
std
::
dec
<<
"
++
\n
"
;
std
::
cout
<<
std
::
dec
<<
"
\t
++"
<<
std
::
hex
<<
d
.
type
<<
"++ :"
<<
d
.
value
<<
std
::
dec
<<
"
\n
"
;
}
else
{
std
::
cout
<<
std
::
dec
<<
"#"
<<
d
.
type
<<
"
\t
Length: "
<<
d
.
len
<<
"
\n
"
;
std
::
cout
<<
std
::
hex
<<
"
\t
Hex: "
<<
d
.
value
<<
"
\n
"
;
...
...
@@ -163,19 +166,16 @@ int Program::getProperty() {
}
int
Program
::
save
()
{
Switch
sw
=
Switch
();
s
td
::
string
str
=
sw
.
toString
()
;
//
File
= fopen(otions.file)
return
0
;
s
w
.
settings
.
hostname
=
"testname.lan"
;
File
f
;
f
.
write
(
"config.json"
,
sw
.
toString
());
return
1
;
}
int
Program
::
restore
()
{
const
char
str
[]
=
" {
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
: true ,
\"
f
\"
: false,
\"
n
\"
: null,
\"
i
\"
:123,
\"
pi
\"
: 3.1416,
\"
a
\"
:[1, 2, 3, 4] } "
;
printf
(
"Original JSON:
\n
%s
\n
"
,
str
);
Switch
sw
=
Switch
();
sw
.
parse
(
str
);
//File = fopen(otions.file)
File
f
;
Switch
sw
;
sw
.
parse
(
f
.
read
(
"config.json"
));
std
::
cout
<<
"Devices:
\n\t
"
<<
sw
.
settings
.
hostname
<<
" ("
<<
sw
.
device
.
type
<<
")
\t
MAC: "
<<
sw
.
device
.
mac
<<
"
\t
IP: "
<<
sw
.
settings
.
ip_addr
<<
"
\n
"
;
return
1
;
}
int
Program
::
flash
()
{
...
...
src/Socket.cpp
View file @
3aa3cee6
...
...
@@ -4,9 +4,6 @@
* Created on: 02.09.2015
* Author: jdi
*/
//#include <cstdio>
//#include <cerrno>
//#include <cstring>
#include <cstdlib>
#include <array>
#include <unistd.h>
...
...
@@ -75,7 +72,7 @@ void Socket::listen() {
listen
();
}
else
{
data
.
resize
(
bytes_recvd
);
Packet
p
=
Packet
(
Packet
::
RE
CEIVE
);
Packet
p
=
Packet
(
Packet
::
RE
TURN
);
p
.
encode
(
data
);
p
.
parse
(
data
);
datasets
l
=
p
.
getPayload
();
...
...
src/Switch.cpp
View file @
3aa3cee6
...
...
@@ -9,6 +9,7 @@
#include "Types.h"
#include "Switch.h"
#include "Lookup.h"
#include "jsonNode.h"
#include "Options.h"
int
Switch
::
parse
(
datasets
arr
)
{
...
...
@@ -52,166 +53,102 @@ int Switch::parse(dataset d) {
int
Switch
::
parse
(
std
::
string
str
)
{
if
(
json
.
Parse
(
str
.
c_str
()).
HasParseError
())
return
1
;
if
(
json
.
Parse
(
str
.
c_str
()).
HasParseError
())
return
1
;
if
(
options
.
flags
&
FLAG_DEBUG
)
std
::
cout
<<
"
\n
Parsing to document succeeded.
\n
"
;
////////////////////////////////////////////////////////////////////////////
// 2. Access values in document.
printf
(
"
\n
Access values in document:
\n
"
);
assert
(
json
.
IsObject
());
// Document is a JSON value represents the root of DOM. Root can be either an object or array.
assert
(
json
.
HasMember
(
"hello"
));
assert
(
json
[
"hello"
].
IsString
());
printf
(
"hello = %s
\n
"
,
json
[
"hello"
].
GetString
());
// Since version 0.2, you can use single lookup to check the existing of member and its value:
rapidjson
::
Value
::
MemberIterator
hello
=
json
.
FindMember
(
"hello"
);
assert
(
hello
!=
json
.
MemberEnd
());
assert
(
hello
->
value
.
IsString
());
assert
(
strcmp
(
"world"
,
hello
->
value
.
GetString
())
==
0
);
(
void
)
hello
;
assert
(
json
[
"t"
].
IsBool
());
// JSON true/false are bool. Can also uses more specific function IsTrue().
printf
(
"t = %s
\n
"
,
json
[
"t"
].
GetBool
()
?
"true"
:
"false"
);
assert
(
json
[
"f"
].
IsBool
());
printf
(
"f = %s
\n
"
,
json
[
"f"
].
GetBool
()
?
"true"
:
"false"
);
printf
(
"n = %s
\n
"
,
json
[
"n"
].
IsNull
()
?
"null"
:
"?"
);
assert
(
json
[
"i"
].
IsNumber
());
// Number is a JSON type, but C++ needs more specific type.
assert
(
json
[
"i"
].
IsInt
());
// In this case, IsUint()/IsInt64()/IsUInt64() also return true.
printf
(
"i = %d
\n
"
,
json
[
"i"
].
GetInt
());
// Alternative (int)document["i"]
assert
(
json
[
"pi"
].
IsNumber
());
assert
(
json
[
"pi"
].
IsDouble
());
printf
(
"pi = %g
\n
"
,
json
[
"pi"
].
GetDouble
());
{
const
rapidjson
::
Value
&
a
=
json
[
"a"
];
// Using a reference for consecutive access is handy and faster.
assert
(
a
.
IsArray
());
for
(
rapidjson
::
SizeType
i
=
0
;
i
<
a
.
Size
();
i
++
)
// rapidjson uses SizeType instead of size_t.
printf
(
"a[%d] = %d
\n
"
,
i
,
a
[
i
].
GetInt
());
int
y
=
a
[
0
].
GetInt
();
(
void
)
y
;
// Iterating array with iterators
printf
(
"a = "
);
for
(
rapidjson
::
Value
::
ConstValueIterator
itr
=
a
.
Begin
();
itr
!=
a
.
End
();
++
itr
)
printf
(
"%d "
,
itr
->
GetInt
());
printf
(
"
\n
"
);
}
// Iterating object members
static
const
char
*
kTypeNames
[]
=
{
"Null"
,
"False"
,
"True"
,
"Object"
,
"Array"
,
"String"
,
"Number"
};
for
(
rapidjson
::
Value
::
ConstMemberIterator
itr
=
json
.
MemberBegin
();
itr
!=
json
.
MemberEnd
();
++
itr
)
printf
(
"Type of member %s is %s
\n
"
,
itr
->
name
.
GetString
(),
kTypeNames
[
itr
->
value
.
GetType
()]);
std
::
cout
<<
"
\n
Parsing to document succeeded.
\n
"
;
if
(
json
.
IsObject
())
{
if
(
json
.
HasMember
(
"hostname"
))
settings
.
hostname
=
json
[
"hostname"
].
GetString
();
if
(
json
.
HasMember
(
"type"
))
device
.
type
=
json
[
"type"
].
GetString
();
if
(
json
.
HasMember
(
"hardware_version"
))
device
.
hardware_version
=
json
[
"hardware_version"
].
GetString
();
if
(
json
.
HasMember
(
"firmware_version"
))
device
.
hardware_version
=
json
[
"firmware_version"
].
GetString
();
}
/*
json.AddMember("ports", jsonNode(ports, json), allocator);
json.AddMember("vlans", jsonNode(vlans, json), allocator);
*/
// Since version 0.2, you can use single lookup to check the existing of member and its value:
/*
rapidjson::Value::MemberIterator hello = json.FindMember("hello");
assert(hello != json.MemberEnd());
assert(hello->value.IsString());
assert(strcmp("world", hello->value.GetString()) == 0);
(void) hello;
assert(json["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue().
printf("t = %s\n", json["t"].GetBool() ? "true" : "false");
assert(json["f"].IsBool());
printf("f = %s\n", json["f"].GetBool() ? "true" : "false");
printf("n = %s\n", json["n"].IsNull() ? "null" : "?");
assert(json["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
assert(json["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
printf("i = %d\n", json["i"].GetInt()); // Alternative (int)document["i"]
assert(json["pi"].IsNumber());
assert(json["pi"].IsDouble());
printf("pi = %g\n", json["pi"].GetDouble());
{
const rapidjson::Value& a = json["a"]; // Using a reference for consecutive access is handy and faster.
assert(a.IsArray());
for (rapidjson::SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
printf("a[%d] = %d\n", i, a[i].GetInt());
int y = a[0].GetInt();
(void) y;
// Iterating array with iterators
printf("a = ");
for (rapidjson::Value::ConstValueIterator itr = a.Begin();
itr != a.End(); ++itr)
printf("%d ", itr->GetInt());
printf("\n");
}
// Iterating object members
static const char* kTypeNames[] = { "Null", "False", "True", "Object",
"Array", "String", "Number" };
for (rapidjson::Value::ConstMemberIterator itr = json.MemberBegin();
itr != json.MemberEnd(); ++itr)
printf("Type of member %s is %s\n", itr->name.GetString(),
kTypeNames[itr->value.GetType()]);
*/
return
0
;
}
std
::
string
Switch
::
toString
()
{
////////////////////////////////////////////////////////////////////////////
// 3. Modify values in document.
// Change i to a bigger number
{
uint64_t
f20
=
1
;
// compute factorial of 20
for
(
uint64_t
j
=
1
;
j
<=
20
;
j
++
)
f20
*=
j
;
json
[
"i"
]
=
f20
;
// Alternate form: document["i"].SetUint64(f20)
assert
(
!
json
[
"i"
].
IsInt
());
// No longer can be cast as int or uint.
}
// Adding values to array.
{
rapidjson
::
Value
&
a
=
json
[
"a"
];
// This time we uses non-const reference.
rapidjson
::
Document
::
AllocatorType
&
allocator
=
json
.
GetAllocator
();
for
(
int
i
=
5
;
i
<=
10
;
i
++
)
a
.
PushBack
(
i
,
allocator
);
// May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's.
// Fluent API
a
.
PushBack
(
"Lua"
,
allocator
).
PushBack
(
"Mio"
,
allocator
);
}
// Making string values.
// This version of SetString() just store the pointer to the string.
// So it is for literal and string that exists within value's life-cycle.
{
json
[
"hello"
]
=
"hostname"
;
//settings.hostname; // This will invoke strlen()
// Faster version:
// document["hello"].SetString("rapidjson", 9);
}
// This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
rapidjson
::
Value
author
;
{
char
buffer
[
10
];
int
len
=
sprintf
(
buffer
,
"%s %s"
,
"Milo"
,
"Yip"
);
// synthetic example of dynamically created string.
author
.
SetString
(
buffer
,
static_cast
<
size_t
>
(
len
),
json
.
GetAllocator
());
// Shorter but slower version:
// document["hello"].SetString(buffer, document.GetAllocator());
// Constructor version:
// Value author(buffer, len, document.GetAllocator());
// Value author(buffer, document.GetAllocator());
memset
(
buffer
,
0
,
sizeof
(
buffer
));
// For demonstration purpose.
}
// Variable 'buffer' is unusable now but 'author' has already made a copy.
json
.
AddMember
(
"author"
,
author
,
json
.
GetAllocator
());
assert
(
author
.
IsNull
());
// Move semantic for assignment. After this variable is assigned as a member, the variable becomes null.
std
::
cout
<<
"
\n
Modified JSON with reformatting:
\n
"
;
rapidjson
::
StringBuffer
sb
;
rapidjson
::
PrettyWriter
<
rapidjson
::
StringBuffer
>
writer
(
sb
);
json
.
Accept
(
writer
);
// Accept() traverses the DOM and generates Handler events.
return
sb
.
GetString
();
if
(
!
json
.
IsObject
())
{
json
.
SetObject
();
}
rapidjson
::
Document
::
AllocatorType
&
allocator
=
json
.
GetAllocator
();
json
.
AddMember
(
"hostname"
,
jsonNode
(
settings
.
hostname
,
json
),
allocator
);
json
.
AddMember
(
"ip"
,
jsonNode
(
settings
.
ip_addr
,
json
),
allocator
);
json
.
AddMember
(
"netmask"
,
jsonNode
(
settings
.
ip_mask
,
json
),
allocator
);
json
.
AddMember
(
"gateway"
,
jsonNode
(
settings
.
gateway
,
json
),
allocator
);
json
.
AddMember
(
"type"
,
jsonNode
(
device
.
type
,
json
),
allocator
);
json
.
AddMember
(
"hardware_version"
,
jsonNode
(
device
.
hardware_version
,
json
),
allocator
);
json
.
AddMember
(
"firmware_version"
,
jsonNode
(
device
.
firmware_version
,
json
),
allocator
);
json
.
AddMember
(
"ports"
,
jsonNode
(
ports
,
json
),
allocator
);
json
.
AddMember
(
"vlans"
,
jsonNode
(
vlans
,
json
),
allocator
);
rapidjson
::
StringBuffer
sb
;
rapidjson
::
PrettyWriter
<
rapidjson
::
StringBuffer
>
writer
(
sb
);
json
.
Accept
(
writer
);
return
sb
.
GetString
();
}
src/Switch.h
View file @
3aa3cee6
...
...
@@ -17,44 +17,17 @@
#define DEFAULT_USER "admin"
#define DEFAULT_PASS "admin"
typedef
rapidjson
::
Value
jsonNode
;
/*
template<typename T>
jsonNode to_json(const T &x) {
// TODO Throw undefined
return NULL;
}
template<> jsonNode to_json<vlan>(const vlan &x) {
jsonNode ret;
return ret;
}
template<typename T>
T from_json(const jsonNode &s) {
// TODO Throw not implemented
return NULL;
}
template<> vlan from_json<vlan>(const jsonNode &s) {
vlan ret;
return ret;
}*/
struct
vlan
{
int
vlan_id
;
std
::
string
name
;
std
::
vector
<
byte
>
tagged_member
;
std
::
vector
<
byte
>
untagged_member
;
};
struct
port
{
byte
id
;
byte
status
;
struct
{
std
::
vector
<
vlan
*>
tagged
;
std
::
vector
<
vlan
*>
untagged
;
int
pvid
;
}
vlan
;
int
pvid
;
};
class
Switch
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment