Axeda Ready Demo for Freescale FRDM-KL46Z as accident alert system

Dependencies:   FRDM_MMA8451Q KL46Z-USBHost MAG3110 SocketModem TSI mbed FATFileSystem

Fork of AxedaGo-Freescal_FRDM-KL46Z by Axeda Corp

Committer:
AxedaCorp
Date:
Wed Jul 02 19:57:37 2014 +0000
Revision:
2:2f9019c5a9fc
Parent:
0:65004368569c
ip switch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AxedaCorp 0:65004368569c 1 /*
AxedaCorp 0:65004368569c 2 Copyright (c) 2009 Dave Gamble
AxedaCorp 0:65004368569c 3
AxedaCorp 0:65004368569c 4 Permission is hereby granted, free of charge, to any person obtaining a copy
AxedaCorp 0:65004368569c 5 of this software and associated documentation files (the "Software"), to deal
AxedaCorp 0:65004368569c 6 in the Software without restriction, including without limitation the rights
AxedaCorp 0:65004368569c 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
AxedaCorp 0:65004368569c 8 copies of the Software, and to permit persons to whom the Software is
AxedaCorp 0:65004368569c 9 furnished to do so, subject to the following conditions:
AxedaCorp 0:65004368569c 10
AxedaCorp 0:65004368569c 11 The above copyright notice and this permission notice shall be included in
AxedaCorp 0:65004368569c 12 all copies or substantial portions of the Software.
AxedaCorp 0:65004368569c 13
AxedaCorp 0:65004368569c 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
AxedaCorp 0:65004368569c 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
AxedaCorp 0:65004368569c 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AxedaCorp 0:65004368569c 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
AxedaCorp 0:65004368569c 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
AxedaCorp 0:65004368569c 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
AxedaCorp 0:65004368569c 20 THE SOFTWARE.
AxedaCorp 0:65004368569c 21 */
AxedaCorp 0:65004368569c 22
AxedaCorp 0:65004368569c 23 Welcome to cJSON.
AxedaCorp 0:65004368569c 24
AxedaCorp 0:65004368569c 25 cJSON aims to be the dumbest possible parser that you can get your job done with.
AxedaCorp 0:65004368569c 26 It's a single file of C, and a single header file.
AxedaCorp 0:65004368569c 27
AxedaCorp 0:65004368569c 28 JSON is described best here: http://www.json.org/
AxedaCorp 0:65004368569c 29 It's like XML, but fat-free. You use it to move data around, store things, or just
AxedaCorp 0:65004368569c 30 generally represent your program's state.
AxedaCorp 0:65004368569c 31
AxedaCorp 0:65004368569c 32
AxedaCorp 0:65004368569c 33 First up, how do I build?
AxedaCorp 0:65004368569c 34 Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
AxedaCorp 0:65004368569c 35 For example, to build the test app:
AxedaCorp 0:65004368569c 36
AxedaCorp 0:65004368569c 37 gcc cJSON.c test.c -o test -lm
AxedaCorp 0:65004368569c 38 ./test
AxedaCorp 0:65004368569c 39
AxedaCorp 0:65004368569c 40
AxedaCorp 0:65004368569c 41 As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
AxedaCorp 0:65004368569c 42 As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
AxedaCorp 0:65004368569c 43 in one of two modes: Auto and Manual. Let's have a quick run-through.
AxedaCorp 0:65004368569c 44
AxedaCorp 0:65004368569c 45
AxedaCorp 0:65004368569c 46 I lifted some JSON from this page: http://www.json.org/fatfree.html
AxedaCorp 0:65004368569c 47 That page inspired me to write cJSON, which is a parser that tries to share the same
AxedaCorp 0:65004368569c 48 philosophy as JSON itself. Simple, dumb, out of the way.
AxedaCorp 0:65004368569c 49
AxedaCorp 0:65004368569c 50 Some JSON:
AxedaCorp 0:65004368569c 51 {
AxedaCorp 0:65004368569c 52 "name": "Jack (\"Bee\") Nimble",
AxedaCorp 0:65004368569c 53 "format": {
AxedaCorp 0:65004368569c 54 "type": "rect",
AxedaCorp 0:65004368569c 55 "width": 1920,
AxedaCorp 0:65004368569c 56 "height": 1080,
AxedaCorp 0:65004368569c 57 "interlace": false,
AxedaCorp 0:65004368569c 58 "frame rate": 24
AxedaCorp 0:65004368569c 59 }
AxedaCorp 0:65004368569c 60 }
AxedaCorp 0:65004368569c 61
AxedaCorp 0:65004368569c 62 Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
AxedaCorp 0:65004368569c 63 you have a char * to it. Everything is a cJSON struct.
AxedaCorp 0:65004368569c 64 Get it parsed:
AxedaCorp 0:65004368569c 65 cJSON *root = cJSON_Parse(my_json_string);
AxedaCorp 0:65004368569c 66
AxedaCorp 0:65004368569c 67 This is an object. We're in C. We don't have objects. But we do have structs.
AxedaCorp 0:65004368569c 68 What's the framerate?
AxedaCorp 0:65004368569c 69
AxedaCorp 0:65004368569c 70 cJSON *format = cJSON_GetObjectItem(root,"format");
AxedaCorp 0:65004368569c 71 int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
AxedaCorp 0:65004368569c 72
AxedaCorp 0:65004368569c 73
AxedaCorp 0:65004368569c 74 Want to change the framerate?
AxedaCorp 0:65004368569c 75 cJSON_GetObjectItem(format,"frame rate")->valueint=25;
AxedaCorp 0:65004368569c 76
AxedaCorp 0:65004368569c 77 Back to disk?
AxedaCorp 0:65004368569c 78 char *rendered=cJSON_Print(root);
AxedaCorp 0:65004368569c 79
AxedaCorp 0:65004368569c 80 Finished? Delete the root (this takes care of everything else).
AxedaCorp 0:65004368569c 81 cJSON_Delete(root);
AxedaCorp 0:65004368569c 82
AxedaCorp 0:65004368569c 83 That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
AxedaCorp 0:65004368569c 84 before you dereference them. If you want to see how you'd build this struct in code?
AxedaCorp 0:65004368569c 85 cJSON *root,*fmt;
AxedaCorp 0:65004368569c 86 root=cJSON_CreateObject();
AxedaCorp 0:65004368569c 87 cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
AxedaCorp 0:65004368569c 88 cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
AxedaCorp 0:65004368569c 89 cJSON_AddStringToObject(fmt,"type", "rect");
AxedaCorp 0:65004368569c 90 cJSON_AddNumberToObject(fmt,"width", 1920);
AxedaCorp 0:65004368569c 91 cJSON_AddNumberToObject(fmt,"height", 1080);
AxedaCorp 0:65004368569c 92 cJSON_AddFalseToObject (fmt,"interlace");
AxedaCorp 0:65004368569c 93 cJSON_AddNumberToObject(fmt,"frame rate", 24);
AxedaCorp 0:65004368569c 94
AxedaCorp 0:65004368569c 95 Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
AxedaCorp 0:65004368569c 96 Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
AxedaCorp 0:65004368569c 97 a few from elsewhere.
AxedaCorp 0:65004368569c 98
AxedaCorp 0:65004368569c 99 What about manual mode? First up you need some detail.
AxedaCorp 0:65004368569c 100 Let's cover how the cJSON objects represent the JSON data.
AxedaCorp 0:65004368569c 101 cJSON doesn't distinguish arrays from objects in handling; just type.
AxedaCorp 0:65004368569c 102 Each cJSON has, potentially, a child, siblings, value, a name.
AxedaCorp 0:65004368569c 103
AxedaCorp 0:65004368569c 104 The root object has: Object Type and a Child
AxedaCorp 0:65004368569c 105 The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
AxedaCorp 0:65004368569c 106 Sibling has type Object, name "format", and a child.
AxedaCorp 0:65004368569c 107 That child has type String, name "type", value "rect", and a sibling:
AxedaCorp 0:65004368569c 108 Sibling has type Number, name "width", value 1920, and a sibling:
AxedaCorp 0:65004368569c 109 Sibling has type Number, name "height", value 1080, and a sibling:
AxedaCorp 0:65004368569c 110 Sibling hs type False, name "interlace", and a sibling:
AxedaCorp 0:65004368569c 111 Sibling has type Number, name "frame rate", value 24
AxedaCorp 0:65004368569c 112
AxedaCorp 0:65004368569c 113 Here's the structure:
AxedaCorp 0:65004368569c 114 typedef struct cJSON {
AxedaCorp 0:65004368569c 115 struct cJSON *next,*prev;
AxedaCorp 0:65004368569c 116 struct cJSON *child;
AxedaCorp 0:65004368569c 117
AxedaCorp 0:65004368569c 118 int type;
AxedaCorp 0:65004368569c 119
AxedaCorp 0:65004368569c 120 char *valuestring;
AxedaCorp 0:65004368569c 121 int valueint;
AxedaCorp 0:65004368569c 122 double valuedouble;
AxedaCorp 0:65004368569c 123
AxedaCorp 0:65004368569c 124 char *string;
AxedaCorp 0:65004368569c 125 } cJSON;
AxedaCorp 0:65004368569c 126
AxedaCorp 0:65004368569c 127 By default all values are 0 unless set by virtue of being meaningful.
AxedaCorp 0:65004368569c 128
AxedaCorp 0:65004368569c 129 next/prev is a doubly linked list of siblings. next takes you to your sibling,
AxedaCorp 0:65004368569c 130 prev takes you back from your sibling to you.
AxedaCorp 0:65004368569c 131 Only objects and arrays have a "child", and it's the head of the doubly linked list.
AxedaCorp 0:65004368569c 132 A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
AxedaCorp 0:65004368569c 133 The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
AxedaCorp 0:65004368569c 134 cJSON.h
AxedaCorp 0:65004368569c 135
AxedaCorp 0:65004368569c 136 A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
AxedaCorp 0:65004368569c 137 valuedouble.
AxedaCorp 0:65004368569c 138
AxedaCorp 0:65004368569c 139 Any entry which is in the linked list which is the child of an object will have a "string"
AxedaCorp 0:65004368569c 140 which is the "name" of the entry. When I said "name" in the above example, that's "string".
AxedaCorp 0:65004368569c 141 "string" is the JSON name for the 'variable name' if you will.
AxedaCorp 0:65004368569c 142
AxedaCorp 0:65004368569c 143 Now you can trivially walk the lists, recursively, and parse as you please.
AxedaCorp 0:65004368569c 144 You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
AxedaCorp 0:65004368569c 145 the root object, and traverse the structure (which is, formally, an N-tree),
AxedaCorp 0:65004368569c 146 and tokenise as you please. If you wanted to build a callback style parser, this is how
AxedaCorp 0:65004368569c 147 you'd do it (just an example, since these things are very specific):
AxedaCorp 0:65004368569c 148
AxedaCorp 0:65004368569c 149 void parse_and_callback(cJSON *item,const char *prefix)
AxedaCorp 0:65004368569c 150 {
AxedaCorp 0:65004368569c 151 while (item)
AxedaCorp 0:65004368569c 152 {
AxedaCorp 0:65004368569c 153 char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
AxedaCorp 0:65004368569c 154 sprintf(newprefix,"%s/%s",prefix,item->name);
AxedaCorp 0:65004368569c 155 int dorecurse=callback(newprefix, item->type, item);
AxedaCorp 0:65004368569c 156 if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
AxedaCorp 0:65004368569c 157 item=item->next;
AxedaCorp 0:65004368569c 158 free(newprefix);
AxedaCorp 0:65004368569c 159 }
AxedaCorp 0:65004368569c 160 }
AxedaCorp 0:65004368569c 161
AxedaCorp 0:65004368569c 162 The prefix process will build you a separated list, to simplify your callback handling.
AxedaCorp 0:65004368569c 163 The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
AxedaCorp 0:65004368569c 164 let you invoke it per-item. For the item above, your callback might look like this:
AxedaCorp 0:65004368569c 165
AxedaCorp 0:65004368569c 166 int callback(const char *name,int type,cJSON *item)
AxedaCorp 0:65004368569c 167 {
AxedaCorp 0:65004368569c 168 if (!strcmp(name,"name")) { /* populate name */ }
AxedaCorp 0:65004368569c 169 else if (!strcmp(name,"format/type") { /* handle "rect" */ }
AxedaCorp 0:65004368569c 170 else if (!strcmp(name,"format/width") { /* 800 */ }
AxedaCorp 0:65004368569c 171 else if (!strcmp(name,"format/height") { /* 600 */ }
AxedaCorp 0:65004368569c 172 else if (!strcmp(name,"format/interlace") { /* false */ }
AxedaCorp 0:65004368569c 173 else if (!strcmp(name,"format/frame rate") { /* 24 */ }
AxedaCorp 0:65004368569c 174 return 1;
AxedaCorp 0:65004368569c 175 }
AxedaCorp 0:65004368569c 176
AxedaCorp 0:65004368569c 177 Alternatively, you might like to parse iteratively.
AxedaCorp 0:65004368569c 178 You'd use:
AxedaCorp 0:65004368569c 179
AxedaCorp 0:65004368569c 180 void parse_object(cJSON *item)
AxedaCorp 0:65004368569c 181 {
AxedaCorp 0:65004368569c 182 int i; for (i=0;i<cJSON_GetArraySize(item);i++)
AxedaCorp 0:65004368569c 183 {
AxedaCorp 0:65004368569c 184 cJSON *subitem=cJSON_GetArrayItem(item,i);
AxedaCorp 0:65004368569c 185 // handle subitem.
AxedaCorp 0:65004368569c 186 }
AxedaCorp 0:65004368569c 187 }
AxedaCorp 0:65004368569c 188
AxedaCorp 0:65004368569c 189 Or, for PROPER manual mode:
AxedaCorp 0:65004368569c 190
AxedaCorp 0:65004368569c 191 void parse_object(cJSON *item)
AxedaCorp 0:65004368569c 192 {
AxedaCorp 0:65004368569c 193 cJSON *subitem=item->child;
AxedaCorp 0:65004368569c 194 while (subitem)
AxedaCorp 0:65004368569c 195 {
AxedaCorp 0:65004368569c 196 // handle subitem
AxedaCorp 0:65004368569c 197 if (subitem->child) parse_object(subitem->child);
AxedaCorp 0:65004368569c 198
AxedaCorp 0:65004368569c 199 subitem=subitem->next;
AxedaCorp 0:65004368569c 200 }
AxedaCorp 0:65004368569c 201 }
AxedaCorp 0:65004368569c 202
AxedaCorp 0:65004368569c 203 Of course, this should look familiar, since this is just a stripped-down version
AxedaCorp 0:65004368569c 204 of the callback-parser.
AxedaCorp 0:65004368569c 205
AxedaCorp 0:65004368569c 206 This should cover most uses you'll find for parsing. The rest should be possible
AxedaCorp 0:65004368569c 207 to infer.. and if in doubt, read the source! There's not a lot of it! ;)
AxedaCorp 0:65004368569c 208
AxedaCorp 0:65004368569c 209
AxedaCorp 0:65004368569c 210 In terms of constructing JSON data, the example code above is the right way to do it.
AxedaCorp 0:65004368569c 211 You can, of course, hand your sub-objects to other functions to populate.
AxedaCorp 0:65004368569c 212 Also, if you find a use for it, you can manually build the objects.
AxedaCorp 0:65004368569c 213 For instance, suppose you wanted to build an array of objects?
AxedaCorp 0:65004368569c 214
AxedaCorp 0:65004368569c 215 cJSON *objects[24];
AxedaCorp 0:65004368569c 216
AxedaCorp 0:65004368569c 217 cJSON *Create_array_of_anything(cJSON **items,int num)
AxedaCorp 0:65004368569c 218 {
AxedaCorp 0:65004368569c 219 int i;cJSON *prev, *root=cJSON_CreateArray();
AxedaCorp 0:65004368569c 220 for (i=0;i<24;i++)
AxedaCorp 0:65004368569c 221 {
AxedaCorp 0:65004368569c 222 if (!i) root->child=objects[i];
AxedaCorp 0:65004368569c 223 else prev->next=objects[i], objects[i]->prev=prev;
AxedaCorp 0:65004368569c 224 prev=objects[i];
AxedaCorp 0:65004368569c 225 }
AxedaCorp 0:65004368569c 226 return root;
AxedaCorp 0:65004368569c 227 }
AxedaCorp 0:65004368569c 228
AxedaCorp 0:65004368569c 229 and simply: Create_array_of_anything(objects,24);
AxedaCorp 0:65004368569c 230
AxedaCorp 0:65004368569c 231 cJSON doesn't make any assumptions about what order you create things in.
AxedaCorp 0:65004368569c 232 You can attach the objects, as above, and later add children to each
AxedaCorp 0:65004368569c 233 of those objects.
AxedaCorp 0:65004368569c 234
AxedaCorp 0:65004368569c 235 As soon as you call cJSON_Print, it renders the structure to text.
AxedaCorp 0:65004368569c 236
AxedaCorp 0:65004368569c 237
AxedaCorp 0:65004368569c 238
AxedaCorp 0:65004368569c 239 The test.c code shows how to handle a bunch of typical cases. If you uncomment
AxedaCorp 0:65004368569c 240 the code, it'll load, parse and print a bunch of test files, also from json.org,
AxedaCorp 0:65004368569c 241 which are more complex than I'd care to try and stash into a const char array[].
AxedaCorp 0:65004368569c 242
AxedaCorp 0:65004368569c 243
AxedaCorp 0:65004368569c 244 Enjoy cJSON!
AxedaCorp 0:65004368569c 245
AxedaCorp 0:65004368569c 246
AxedaCorp 0:65004368569c 247 - Dave Gamble, Aug 2009
AxedaCorp 0:65004368569c 248