Vinay Shrivastav / Mbed OS AAT_LWM2M_K64F

Dependencies:   FXOS8700Q-driver MODSERIAL

Fork of mbed-os-example-client by mbed-os-examples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers resources.h Source File

resources.h

00001 #include "simpleclient.h"
00002 #include "mbed-trace/mbed_trace.h"
00003 #include "mbedtls/entropy_poll.h"
00004 #include "FXOS8700Q.h"
00005 #include "MODSERIAL.h"
00006 
00007 #define PI 3.14159265
00008  
00009 //MODSERIAL gps
00010 MODSERIAL gps(PTD3, PTD2); // (PTC17, PTC16) UART3 not functional on etherenet enabling
00011 I2C i2c(PTE25, PTE24);     // Configured for the FRDM-K64F with onboard sensors
00012 FXOS8700QAccelerometer accel(i2c,FXOS8700CQ_SLAVE_ADDR1);
00013 char cDataBuffer[500];
00014 
00015 struct gnss_params
00016 {
00017      float   latitude;    //Latitude
00018      float   longitude;   //Longitude
00019      float   altitude;    //Altitude 
00020      float   baselineLen; //BaseLine Length
00021      float   heading;     // Heading
00022      int     date;
00023      int     time;
00024      int     fix_quality; // 0 INVALID, 1 GPS, 2 DIFF   
00025      int     numsat;     
00026 };
00027 
00028 
00029 #if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
00030     #if TARGET_UBLOX_EVK_ODIN_W2
00031         #include "OdinWiFiInterface.h"
00032         OdinWiFiInterface wifi;
00033     #else
00034         #include "ESP8266Interface.h"
00035         ESP8266Interface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX);
00036     #endif
00037 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
00038     #include "EthernetInterface.h"
00039     EthernetInterface eth;
00040 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
00041     #define MESH
00042     #include "NanostackInterface.h"
00043     LoWPANNDInterface mesh;
00044 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
00045     #define MESH
00046     #include "NanostackInterface.h"
00047     ThreadInterface mesh;
00048 #endif
00049 
00050 #if defined(MESH)
00051 #if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL
00052 #include "NanostackRfPhyAtmel.h"
00053 NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS,
00054                            ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL);
00055 #elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20
00056 #include "NanostackRfPhyMcr20a.h"
00057 NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ);
00058 #endif //MBED_CONF_APP_RADIO_TYPE
00059 #endif //MESH
00060 
00061 #ifdef MESH
00062     // Mesh does not have DNS, so must use direct IPV6 address
00063     #define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684"
00064 #else
00065     // This is address to mbed Device Connector, name based
00066     // assume all other stacks support DNS properly
00067     #define MBED_SERVER_ADDRESS "coap://leshan.eclipse.org:5683" //"coap://api.connector.mbed.com:5684"
00068 #endif
00069 
00070 RawSerial output(USBTX, USBRX);
00071 
00072 // Status indication
00073 DigitalOut red_led(LED1);
00074 DigitalOut green_led(LED2);
00075 DigitalOut blue_led(LED3);
00076 //Ticker status_ticker;
00077 void blinky() {
00078     red_led = !red_led;
00079 
00080 }
00081 
00082 // These are example resource values for the Device Object
00083 struct MbedClientDevice device = {
00084     "RJio",         // Manufacturer
00085     "Netra2.0",              // Type
00086     "0.01",                 // ModelNumber
00087     "007"                   // SerialNumber
00088 };
00089 
00090 // Instantiate the class which implements LWM2M Client API (from simpleclient.h)
00091 MbedClient mbed_client(device);
00092 
00093 
00094 // In case of K64F board , there is button resource available
00095 // to change resource value and unregister
00096 #ifdef TARGET_K64F
00097 // Set up Hardware interrupt button.
00098 InterruptIn obs_button(SW2);
00099 InterruptIn unreg_button(SW3);
00100 #endif
00101 
00102 // set up a timer to simulate updating resource,
00103 // there is no functionality to unregister.
00104 Ticker timer;
00105 
00106 /*
00107  * Arguments for running "blink" in it's own thread.
00108  */
00109 class BlinkArgs {
00110 public:
00111     BlinkArgs() {
00112         clear();
00113     }
00114     void clear() {
00115         position = 0;
00116         blink_pattern.clear();
00117     }
00118     uint16_t position;
00119     std::vector<uint32_t> blink_pattern;
00120 };
00121 
00122 /*
00123  * The Led contains one property (pattern) and a function (blink).
00124  * When the function blink is executed, the pattern is read, and the LED
00125  * will blink based on the pattern.
00126  */
00127 class LedResource {
00128 public:
00129     LedResource() {
00130         // create ObjectID with metadata tag of '3201', which is 'digital output'
00131         led_object = M2MInterfaceFactory::create_object("3201");
00132         M2MObjectInstance* led_inst = led_object->create_object_instance();
00133 
00134         // 5853 = Multi-state output
00135         M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern",
00136             M2MResourceInstance::STRING, false);
00137         // read and write
00138         pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00139         // set initial pattern (toggle every 200ms. 7 toggles in total)
00140         pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27);
00141 
00142         // there's not really an execute LWM2M ID that matches... hmm...
00143         M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink",
00144             M2MResourceInstance::OPAQUE, false);
00145         // we allow executing a function here...
00146         led_res->set_operation(M2MBase::POST_ALLOWED);
00147         // when a POST comes in, we want to execute the led_execute_callback
00148         led_res->set_execute_function(execute_callback(this, &LedResource::blink));
00149         // Completion of execute function can take a time, that's why delayed response is used
00150         led_res->set_delayed_response(true);
00151         blink_args = new BlinkArgs();
00152     }
00153 
00154     ~LedResource() {
00155         delete blink_args;
00156     }
00157 
00158     M2MObject* get_object() {
00159         return led_object;
00160     }
00161 
00162     void blink(void *argument) {
00163         // read the value of 'Pattern'
00164         //status_ticker.detach();
00165         green_led = 1;
00166 
00167         M2MObjectInstance* inst = led_object->object_instance();
00168         M2MResource* res = inst->resource("5853");
00169         // Clear previous blink data
00170         blink_args->clear();
00171 
00172         // values in mbed Client are all buffers, and we need a vector of int's
00173         uint8_t* buffIn = NULL;
00174         uint32_t sizeIn;
00175         res->get_value(buffIn, sizeIn);
00176 
00177         // turn the buffer into a string, and initialize a vector<int> on the heap
00178         std::string s((char*)buffIn, sizeIn);
00179         free(buffIn);
00180         output.printf("led_execute_callback pattern=%s\r\n", s.c_str());
00181 
00182         // our pattern is something like 500:200:500, so parse that
00183         std::size_t found = s.find_first_of(":");
00184         while (found!=std::string::npos) {
00185             blink_args->blink_pattern.push_back(atoi((const char*)s.substr(0,found).c_str()));
00186             s = s.substr(found+1);
00187             found=s.find_first_of(":");
00188             if(found == std::string::npos) {
00189                 blink_args->blink_pattern.push_back(atoi((const char*)s.c_str()));
00190             }
00191         }
00192         // check if POST contains payload
00193         if (argument) {
00194             M2MResource::M2MExecuteParameter* param = (M2MResource::M2MExecuteParameter*)argument;
00195             String object_name = param->get_argument_object_name();
00196             uint16_t object_instance_id = param->get_argument_object_instance_id();
00197             String resource_name = param->get_argument_resource_name();
00198             int payload_length = param->get_argument_value_length();
00199             uint8_t* payload = param->get_argument_value();
00200             output.printf("Resource: %s/%d/%s executed\r\n", object_name.c_str(), object_instance_id, resource_name.c_str());
00201             output.printf("Payload: %.*s\r\n", payload_length, payload);
00202         }
00203         // do_blink is called with the vector, and starting at -1
00204         blinky_thread.start(this, &LedResource::do_blink);
00205     }
00206 
00207 private:
00208     M2MObject* led_object;
00209     Thread blinky_thread;
00210     BlinkArgs *blink_args;
00211     void do_blink() {
00212         for (;;) {
00213             // blink the LED
00214             green_led = !green_led;
00215             // up the position, if we reached the end of the vector
00216             if (blink_args->position >= blink_args->blink_pattern.size()) {
00217                 // send delayed response after blink is done
00218                 M2MObjectInstance* inst = led_object->object_instance();
00219                 M2MResource* led_res = inst->resource("5850");
00220                 led_res->send_delayed_post_response();
00221                 red_led = 1;
00222                 //status_ticker.attach_us(blinky, 250000);
00223                 return;
00224             }
00225             // Wait requested time, then continue prosessing the blink pattern from next position.
00226             Thread::wait(blink_args->blink_pattern.at(blink_args->position));
00227             blink_args->position++;
00228         }
00229     }
00230 };
00231 
00232 /*
00233  * The button contains one property (click count).
00234  * When `handle_button_click` is executed, the counter updates.
00235  */
00236 class ButtonResource {
00237 public:
00238     ButtonResource(): counter(0) {
00239         // create ObjectID with metadata tag of '3200', which is 'digital input'
00240         btn_object = M2MInterfaceFactory::create_object("3200");
00241         M2MObjectInstance* btn_inst = btn_object->create_object_instance();
00242         // create resource with ID '5501', which is digital input counter
00243         M2MResource* btn_res = btn_inst->create_dynamic_resource("5501", "Button",
00244             M2MResourceInstance::INTEGER, true /* observable */);
00245         // we can read this value
00246         btn_res->set_operation(M2MBase::GET_ALLOWED);
00247         // set initial value (all values in mbed Client are buffers)
00248         // to be able to read this data easily in the Connector console, we'll use a string
00249         btn_res->set_value((uint8_t*)"0", 1);
00250     }
00251 
00252     ~ButtonResource() {
00253     }
00254 
00255     M2MObject* get_object() {
00256         return btn_object;
00257     }
00258 
00259     /*
00260      * When you press the button, we read the current value of the click counter
00261      * from mbed Device Connector, then up the value with one.
00262      */
00263     void handle_button_click() {
00264         M2MObjectInstance* inst = btn_object->object_instance();
00265         M2MResource* res = inst->resource("5501");
00266 
00267         // up counter
00268         counter++;
00269 #ifdef TARGET_K64F
00270         //printf("handle_button_click, new value of counter is %d\r\n", counter);
00271 #endif
00272 
00273         // serialize the value of counter as a string, and tell connector
00274         char buffer[20];
00275         int size = sprintf(buffer,"%d",counter);
00276         res->set_value((uint8_t*)buffer, size);
00277     }
00278 
00279 private:
00280     M2MObject* btn_object;
00281     uint16_t counter;
00282 };
00283 
00284 /*
00285  * The GNSS contains 1 property (Azimuth).
00286  * When `handle_azimuth_update` is executed, the azimuth updates.
00287  */
00288 class GnssResource {
00289 public:
00290     GnssResource(): azimuth(0) {
00291         // create ObjectID with metadata tag of '3336', which is 'GPS location'
00292         gnss_object = M2MInterfaceFactory::create_object("3336");
00293         
00294         M2MObjectInstance* gnss_inst = gnss_object->create_object_instance();
00295         // create resource with ID '5513', which is digital input Latitude
00296         M2MResource* lat_res = gnss_inst->create_dynamic_resource("5513", "Latitude",
00297             M2MResourceInstance::FLOAT, true /* observable */);
00298         // we can read this value
00299         lat_res->set_operation(M2MBase::GET_ALLOWED);
00300         // set initial value (all values in mbed Client are buffers)
00301         // to be able to read this data easily in the Connector console, we'll use a string
00302         lat_res->set_value(0.0);
00303         
00304         M2MResource* long_res = gnss_inst->create_dynamic_resource("5514", "Longitude",
00305             M2MResourceInstance::FLOAT, true /* observable */);
00306         // we can read this value
00307         long_res->set_operation(M2MBase::GET_ALLOWED);
00308         // set initial value (all values in mbed Client are buffers)
00309         // to be able to read this data easily in the Connector console, we'll use a string
00310         long_res->set_value(0.0);
00311         
00312         M2MResource* alt_res = gnss_inst->create_dynamic_resource("5515", "Altitude",
00313         M2MResourceInstance::FLOAT, true /* observable */);
00314         // we can read this value
00315         alt_res->set_operation(M2MBase::GET_ALLOWED);
00316         // set initial value (all values in mbed Client are buffers)
00317         // to be able to read this data easily in the Connector console, we'll use a string
00318         alt_res->set_value(0.0);        
00319 
00320         M2MResource* azi_res = gnss_inst->create_dynamic_resource("5705", "Heading",
00321             M2MResourceInstance::FLOAT, true /* observable */);
00322         // we can read this value
00323         azi_res->set_operation(M2MBase::GET_ALLOWED);
00324         // set initial value (all values in mbed Client are buffers)
00325         // to be able to read this data easily in the Connector console, we'll use a string
00326         azi_res->set_value(0.0);
00327         
00328         M2MResource* app_res = gnss_inst->create_dynamic_resource("5750", "AppType",
00329             M2MResourceInstance::STRING, true /* observable */);
00330         // we can read this value
00331         app_res->set_operation(M2MBase::GET_ALLOWED);
00332         // set initial value (all values in mbed Client are buffers)
00333         // to be able to read this data easily in the Connector console, we'll use a string
00334         size = sprintf(buffer,"%s","AntennaAlignment");
00335         app_res->set_value((const uint8_t*)buffer, size);       
00336         
00337 #if 0       
00338         M2MResource* time_res = gnss_inst->create_dynamic_resource("5707", "Time",
00339         M2MResourceInstance::INTEGER, true /* observable */);
00340         // we can read this value
00341         time_res->set_operation(M2MBase::GET_ALLOWED);
00342         // set initial value (all values in mbed Client are buffers)
00343         // to be able to read this data easily in the Connector console, we'll use a string
00344         time_res->set_value((uint8_t*)"0", 1);
00345         
00346         M2MResource* numsat_res = gnss_inst->create_dynamic_resource("5708", "NumSat",
00347         M2MResourceInstance::INTEGER, true /* observable */);
00348         // we can read this value
00349         numsat_res->set_operation(M2MBase::GET_ALLOWED);
00350         // set initial value (all values in mbed Client are buffers)
00351         // to be able to read this data easily in the Connector console, we'll use a string
00352         numsat_res->set_value((uint8_t*)"0", 1);
00353         
00354         M2MResource* blen_res = gnss_inst->create_dynamic_resource("5709", "BaseLen",
00355         M2MResourceInstance::FLOAT, true /* observable */);
00356         // we can read this value
00357         blen_res->set_operation(M2MBase::GET_ALLOWED);
00358         // set initial value (all values in mbed Client are buffers)
00359         // to be able to read this data easily in the Connector console, we'll use a string
00360         blen_res->set_value(0.0);
00361 
00362         M2MResource* fq_res = gnss_inst->create_dynamic_resource("5710", "FixQuality",
00363         M2MResourceInstance::INTEGER, true /* observable */);
00364         // we can read this value
00365         fq_res->set_operation(M2MBase::GET_ALLOWED);
00366         // set initial value (all values in mbed Client are buffers)
00367         // to be able to read this data easily in the Connector console, we'll use a string
00368         fq_res->set_value((uint8_t*)"0", 1);
00369         
00370         M2MResource* date_res = gnss_inst->create_dynamic_resource("5706", "Date",
00371         M2MResourceInstance::INTEGER, true /* observable */);
00372         // we can read this value
00373         date_res->set_operation(M2MBase::GET_ALLOWED);
00374         // set initial value (all values in mbed Client are buffers)
00375         // to be able to read this data easily in the Connector console, we'll use a string
00376         date_res->set_value((uint8_t*)"0", 1);
00377 #endif
00378         
00379     }
00380 
00381     ~GnssResource() {
00382     }
00383 
00384     M2MObject* get_object() {
00385         return gnss_object;
00386     }
00387 
00388     /*
00389      * When you press the button, we read the current value of the click azimuth
00390      * from mbed Device Connector, then up the value with one.
00391      */
00392     void gps_scan(void) 
00393     {
00394         char c;
00395         PSTI32 = false; GPGGA = false;
00396         Timer timeout;      
00397         timeout.start();
00398         
00399         while((!PSTI32 || !GPGGA) && (timeout.read() < 10))
00400         {           
00401             if(gps.readable())
00402             { 
00403                 if(gps.getc() == '$');           // wait for a $
00404                 {
00405                     for(int i=0; i<sizeof(cDataBuffer); i++)
00406                     {
00407                         c = gps.getc();
00408                         if( c == '\r' )
00409                         {
00410                             //pc.printf("%s\n", cDataBuffer);
00411                             parse(cDataBuffer, i);
00412                             i = sizeof(cDataBuffer);
00413                         }
00414                         else
00415                         {
00416                             cDataBuffer[i] = c;
00417                         }                 
00418                     }
00419                 }
00420              }
00421              else break;     
00422         }       
00423         timeout.stop();
00424     }
00425 
00426     void parse(char *cmd, int n)
00427     {
00428         char ns, ew, tf, status, mode;
00429         int fq, nst, fix, date, timefix, pstino;   // fix quality, Number of satellites being tracked, 3D fix
00430         float latitude, longitude, speed, altitude, eastprj, northprj, upprj, blength, bcourse;
00431         
00432         // Global Positioning System Fix Data
00433         if(strncmp(cmd,"$GPGGA", 6) == 0)
00434         {
00435             sscanf(cmd, "$GPGGA,%d,%f,%c,%f,%c,%d,%d,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude);
00436             //output.printf("GPGGA Fix taken at: %d, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude);
00437             gnss_scan.latitude  = latitude;
00438             gnss_scan.longitude = longitude;
00439             //gnss_scan.date = date; 
00440             gnss_scan.time = timefix;
00441             gnss_scan.altitude = altitude;
00442             gnss_scan.fix_quality = fq;
00443             gnss_scan.numsat = nst;
00444             GPGGA = true;
00445         }
00446         
00447         // Baseline length, Azimuth
00448         if(strncmp(cmd,"$PSTI", 5) == 0)
00449         {
00450             sscanf(cmd, "$PSTI,%d,%d,%d,%c,%c,%f,%f,%f,%f,%f", &pstino, &timefix, &date, &status, &mode, &eastprj, &northprj, &upprj, &blength, &bcourse);
00451             if(32 == pstino)
00452             {
00453                 //output.printf("PSTI32 Fix taken at: %d, Date: %d, Status: %c, Mode: %c, Baseline length: %f m, Azimuth: %f degrees\n", timefix, date, status, mode, blength, bcourse);
00454                 gnss_scan.heading = bcourse; gnss_scan.date = date; gnss_scan.time = timefix; 
00455                 gnss_scan.baselineLen = blength; //BaseLine Length
00456                 PSTI32 = true;
00457             }
00458         }
00459 #if 0
00460         // Satellite status
00461         if(strncmp(cmd,"$GPGSA", 6) == 0) 
00462         {
00463             sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst);
00464             pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst);
00465         }
00466         
00467         // Geographic position, Latitude and Longitude
00468         if(strncmp(cmd,"$GPGLL", 6) == 0) 
00469         {
00470             sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix);
00471             pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix);
00472         }
00473         
00474         // Geographic position, Latitude and Longitude
00475         if(strncmp(cmd,"$GPRMC", 6) == 0) 
00476         {
00477             sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date);
00478             pc.printf("GPRMC Fix taken at: %f, Status: %c, Latitude: %f %c, Longitude: %f %c, Speed: %f, Date: %d\n", timefix, status, latitude, ns, longitude, ew, speed, date);
00479         }
00480 #endif
00481     }
00482     void handle_gnss_update() {
00483         M2MObjectInstance* inst = gnss_object->object_instance();
00484         M2MResource* latituderes = inst->resource("5513");
00485         M2MResource* longituderes = inst->resource("5514");
00486         M2MResource* altres = inst->resource("5515");
00487         M2MResource* azimuthres = inst->resource("5705");
00488         M2MResource* appres = inst->resource("5750");
00489         
00490         gps_scan();
00491         
00492         size = sprintf(buffer,"%f",gnss_scan.latitude);
00493         latituderes->set_value((const uint8_t*)buffer, size);
00494 
00495         size = sprintf(buffer,"%f",gnss_scan.longitude);
00496         longituderes->set_value((const uint8_t*)buffer, size);
00497         
00498         size = sprintf(buffer,"%f",gnss_scan.altitude);
00499         altres->set_value((const uint8_t*)buffer, size);
00500         
00501         size = sprintf(buffer,"%f",gnss_scan.heading);
00502         azimuthres->set_value((const uint8_t*)buffer, size);
00503 
00504         size = sprintf(buffer,"%s","AntennaAlignment");
00505         appres->set_value((const uint8_t*)buffer, size);            
00506 
00507 #if 0       
00508 
00509         M2MResource* dateres = inst->resource("5706");
00510         M2MResource* timeres = inst->resource("5707");
00511         M2MResource* numsatres = inst->resource("5708");
00512         M2MResource* blenres = inst->resource("5709");
00513         M2MResource* fqres = inst->resource("5710");
00514 
00515         size = sprintf(buffer,"%d",gnss_scan.date);
00516         dateres->set_value((const uint8_t*)buffer, size);
00517 
00518         size = sprintf(buffer,"%d",gnss_scan.time);
00519         timeres->set_value((const uint8_t*)buffer, size);
00520 
00521         size = sprintf(buffer,"%d",gnss_scan.numsat);
00522         numsatres->set_value((const uint8_t*)buffer, size);
00523 
00524         size = sprintf(buffer,"%f",gnss_scan.baselineLen);
00525         blenres->set_value((const uint8_t*)buffer, size);
00526 
00527         size = sprintf(buffer,"%d",gnss_scan.fix_quality);
00528         fqres->set_value((const uint8_t*)buffer, size); 
00529 #endif
00530         
00531         output.printf("GNSS data updated\n");   
00532     }
00533 
00534 private:
00535     M2MObject* gnss_object;
00536     uint16_t azimuth;
00537     bool PSTI32;
00538     bool GPGGA;
00539     gnss_params gnss_scan;
00540     char buffer[20];
00541     int size;   
00542 };
00543 
00544 const uint8_t STATIC_VALUE[] = "Cellular Antenna Alignment";
00545 /*
00546  * The GNSS custom object
00547  */
00548 /*
00549  * The GNSS custom object
00550  */
00551 class GnssCustomResource {
00552 public:
00553     GnssCustomResource() {
00554         // create ObjectID with metadata custom tag
00555         gnss_object = M2MInterfaceFactory::create_object("JioNetraGNSScompass");    
00556         M2MObjectInstance* gnss_inst = gnss_object->create_object_instance();
00557         
00558         
00559         M2MResource* lat_res = gnss_inst->create_dynamic_resource("E",
00560                                                          "JioLatitude",
00561                                                          M2MResourceInstance::FLOAT,
00562                                                          true);
00563         // we can read this value
00564         lat_res->set_operation(M2MBase::GET_ALLOWED);
00565         // set initial value (all values in mbed Client are buffers)
00566         // to be able to read this data easily in the Connector console, we'll use a string
00567         lat_res->set_value(0.0);
00568         
00569         M2MResource* app_res = gnss_inst->create_static_resource("N",
00570                                                  "JioAppType",
00571                                                  M2MResourceInstance::STRING,
00572                                                  STATIC_VALUE,
00573                                                  sizeof(STATIC_VALUE)-1);
00574         // we can read this value
00575         app_res->set_operation(M2MBase::GET_ALLOWED);
00576         // set initial value (all values in mbed Client are buffers)
00577         // to be able to read this data easily in the Connector console, we'll use a string
00578         size = sprintf(buffer,"%s","AntennaAlignment");
00579         app_res->set_value((const uint8_t*)buffer, size);       
00580    
00581        
00582     }
00583 
00584     ~GnssCustomResource() {
00585     }
00586 
00587     M2MObject* get_object() {
00588         return gnss_object;
00589     }
00590 
00591     /*
00592      * When you press the button, we read the current value of the click azimuth
00593      * from mbed Device Connector, then up the value with one.
00594      */
00595     void gps_scan(void) 
00596     {
00597         char c;
00598         PSTI32 = false; GPGGA = false;
00599         Timer timeout;      
00600         timeout.start();
00601         
00602         while((!PSTI32 || !GPGGA) && (timeout.read() < 10))
00603         {           
00604             if(gps.readable())
00605             { 
00606                 if(gps.getc() == '$');           // wait for a $
00607                 {
00608                     for(int i=0; i<sizeof(cDataBuffer); i++)
00609                     {
00610                         c = gps.getc();
00611                         if( c == '\r' )
00612                         {
00613                             //pc.printf("%s\n", cDataBuffer);
00614                             parse(cDataBuffer, i);
00615                             i = sizeof(cDataBuffer);
00616                         }
00617                         else
00618                         {
00619                             cDataBuffer[i] = c;
00620                         }                 
00621                     }
00622                 }
00623              }
00624              else break;     
00625         }       
00626         timeout.stop();
00627     }
00628 
00629     void parse(char *cmd, int n)
00630     {
00631         char ns, ew, tf, status, mode;
00632         int fq, nst, fix, date, timefix, pstino;   // fix quality, Number of satellites being tracked, 3D fix
00633         float latitude, longitude, speed, altitude, eastprj, northprj, upprj, blength, bcourse;
00634         
00635         // Global Positioning System Fix Data
00636         if(strncmp(cmd,"$GPGGA", 6) == 0) 
00637         {
00638             sscanf(cmd, "$GPGGA,%d,%f,%c,%f,%c,%d,%d,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude);
00639             //output.printf("GPGGA Fix taken at: %d, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude);
00640             gnss_scan.latitude  = latitude;
00641             gnss_scan.longitude = longitude;
00642             //gnss_scan.date = date; 
00643             gnss_scan.time = timefix;
00644             gnss_scan.altitude = altitude;
00645             gnss_scan.fix_quality = fq;
00646             gnss_scan.numsat = nst;
00647             GPGGA = true;
00648         }
00649         
00650         // Baseline length, Azimuth
00651         if(strncmp(cmd,"$PSTI", 5) == 0)
00652         {
00653             sscanf(cmd, "$PSTI,%d,%d,%d,%c,%c,%f,%f,%f,%f,%f", &pstino, &timefix, &date, &status, &mode, &eastprj, &northprj, &upprj, &blength, &bcourse);
00654             if(32 == pstino)
00655             {
00656                 //output.printf("PSTI32 Fix taken at: %d, Date: %d, Status: %c, Mode: %c, Baseline length: %f m, Azimuth: %f degrees\n", timefix, date, status, mode, blength, bcourse);
00657                 gnss_scan.heading = bcourse; gnss_scan.date = date; gnss_scan.time = timefix; 
00658                 gnss_scan.baselineLen = blength; //BaseLine Length
00659                 PSTI32 = true;
00660             }
00661         }
00662 #if 0
00663         // Satellite status
00664         if(strncmp(cmd,"$GPGSA", 6) == 0) 
00665         {
00666             sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst);
00667             pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst);
00668         }
00669         
00670         // Geographic position, Latitude and Longitude
00671         if(strncmp(cmd,"$GPGLL", 6) == 0) 
00672         {
00673             sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix);
00674             pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix);
00675         }
00676         
00677         // Geographic position, Latitude and Longitude
00678         if(strncmp(cmd,"$GPRMC", 6) == 0) 
00679         {
00680             sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date);
00681             pc.printf("GPRMC Fix taken at: %f, Status: %c, Latitude: %f %c, Longitude: %f %c, Speed: %f, Date: %d\n", timefix, status, latitude, ns, longitude, ew, speed, date);
00682         }
00683 #endif
00684     }
00685     void handle_gnss_update() {
00686         M2MObjectInstance* inst = gnss_object->object_instance();
00687         M2MResource* latituderes = inst->resource("E");
00688         M2MResource* appres = inst->resource("N");
00689         
00690         gps_scan();
00691         
00692         size = sprintf(buffer,"%f",gnss_scan.latitude);
00693         latituderes->set_value((const uint8_t*)buffer, size);
00694 
00695         
00696         output.printf("GNSS data updated\n");   
00697     }
00698 
00699 private:
00700     M2MObject* gnss_object;
00701     uint16_t azimuth;
00702     bool PSTI32;
00703     bool GPGGA;
00704     gnss_params gnss_scan;
00705     char buffer[20];
00706     int size;   
00707 };
00708 
00709 class AccelResource {
00710 public:
00711     AccelResource(){
00712         
00713         // create ObjectID with metadata tag of '3313', which is 'IPSO Accelerometer'
00714         accel_object = M2MInterfaceFactory::create_object("3313");
00715         M2MObjectInstance* accel_inst = accel_object->create_object_instance();
00716         
00717         // create resource with ID '5701', which is accelerometer units
00718         M2MResource* units_res = accel_inst->create_dynamic_resource("5701", "Units",
00719             M2MResourceInstance::STRING, false /* non-observable */);
00720         // we can read this value
00721         units_res->set_operation(M2MBase::GET_ALLOWED);
00722         // set initial value (all values in mbed Client are buffers)
00723         // to be able to read this data easily in the Connector console, we'll use a string
00724         size = sprintf(buffer,"%s","degrees");
00725         units_res->set_value((const uint8_t*)buffer, size);     
00726         
00727         
00728         // create resource with ID '5702', which is accelerometer X value
00729         M2MResource* x_res = accel_inst->create_dynamic_resource("5702", "Tilt",
00730             M2MResourceInstance::FLOAT, true /* observable */);
00731         // we can read this value
00732         x_res->set_operation(M2MBase::GET_ALLOWED);
00733         // set initial value (all values in mbed Client are buffers)
00734         // to be able to read this data easily in the Connector console, we'll use a string
00735         size = sprintf(buffer,"%f",0.0);
00736         x_res->set_value((const uint8_t*)buffer, size);
00737         
00738         // create resource with ID '5703', which is accelerometer Y value
00739         M2MResource* y_res = accel_inst->create_dynamic_resource("5703", "Roll",
00740             M2MResourceInstance::FLOAT, true /* observable */);
00741         // we can read this value
00742         y_res->set_operation(M2MBase::GET_ALLOWED);
00743         // set initial value (all values in mbed Client are buffers)
00744         // to be able to read this data easily in the Connector console, we'll use a string
00745         size = sprintf(buffer,"%f",0.0);
00746         y_res->set_value((const uint8_t*)buffer, size);
00747     
00748     }
00749 
00750     ~AccelResource() {
00751     }
00752 
00753     M2MObject* get_object() {
00754         return accel_object;
00755     }
00756 
00757     /*
00758      * Timer based update triggers planned
00759      */
00760      
00761     void handle_accel_update() 
00762     {
00763         double angleX, denomX_T, denomX_A, denomX_B, denomX_C;           //intializing variable to hold the angle calculation 
00764         double angleY, denomY_T, denomY_A, denomY_B, denomY_C; 
00765         float faX, faY, faZ;
00766         
00767         M2MObjectInstance* inst = accel_object->object_instance();
00768         M2MResource* xres = inst->resource("5702");
00769         M2MResource* yres = inst->resource("5703");
00770         
00771         // Read accelerometer data
00772         //accel.getAxis(acc_data);
00773         accel.getX(faX);
00774         accel.getY(faY);
00775         accel.getZ(faZ);
00776         
00777         // Canculate angles in degrees
00778         //X-AXIS
00779         denomX_A = pow(faY, 2);
00780         denomX_B = pow(faZ, 2);
00781         denomX_C = denomX_A + denomX_B;
00782         denomX_T = pow(denomX_C, .5);                   //pow returns base raised to the power exponent 
00783         
00784         angleX = atan(faX/denomX_T) * 180/PI;           //should calculate the angle on the X axis in degrees based on raw data         
00785 
00786         //Y-AXIS
00787         denomY_A = pow(faX, 2);
00788         denomY_B = pow(faZ, 2);
00789         denomY_C = denomY_A + denomY_B;
00790         denomY_T = pow(denomY_C, .5);                   //pow returns base raised to the power exponent 
00791         
00792         angleY = atan(faY/denomY_T) * 180/PI;           //should calculate the angle on the Y axis in degrees based on raw data         
00793 
00794         // serialize the value of x & y accel ops as a string, and tell connector
00795         size = sprintf(buffer,"%f",angleX);
00796         xres->set_value((const uint8_t*)buffer, size);
00797         
00798         size = sprintf(buffer,"%f",angleY);
00799         yres->set_value((const uint8_t*)buffer, size);      
00800         printf("Accelerometer update, x:%f degrees, y:%f degrees\r\n", angleX, angleY );
00801     
00802     }
00803 
00804 private:
00805     M2MObject* accel_object;
00806     //motion_data_units_t acc_data;
00807     char buffer[20];
00808     int size;   
00809 };
00810 
00811 class BigPayloadResource {
00812 public:
00813     BigPayloadResource() {
00814         big_payload = M2MInterfaceFactory::create_object("1000");
00815         M2MObjectInstance* payload_inst = big_payload->create_object_instance();
00816         M2MResource* payload_res = payload_inst->create_dynamic_resource("1", "BigData",
00817             M2MResourceInstance::STRING, true /* observable */);
00818         payload_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00819         payload_res->set_value((uint8_t*)"0", 1);
00820         payload_res->set_incoming_block_message_callback(
00821                     incoming_block_message_callback(this, &BigPayloadResource::block_message_received));
00822         payload_res->set_outgoing_block_message_callback(
00823                     outgoing_block_message_callback(this, &BigPayloadResource::block_message_requested));
00824     }
00825 
00826     M2MObject* get_object() {
00827         return big_payload;
00828     }
00829 
00830     void block_message_received(M2MBlockMessage *argument) {
00831         if (argument) {
00832             if (M2MBlockMessage::ErrorNone == argument->error_code()) {
00833                 if (argument->is_last_block()) {
00834                     output.printf("Last block received\r\n");
00835                 }
00836                 output.printf("Block number: %d\r\n", argument->block_number());
00837                 // First block received
00838                 if (argument->block_number() == 0) {
00839                     // Store block
00840                 // More blocks coming
00841                 } else {
00842                     // Store blocks
00843                 }
00844             } else {
00845                 output.printf("Error when receiving block message!  - EntityTooLarge\r\n");
00846             }
00847             output.printf("Total message size: %d\r\n", argument->total_message_size());
00848         }
00849     }
00850 
00851     void block_message_requested(const String& resource, uint8_t *&/*data*/, uint32_t &/*len*/) {
00852         output.printf("GET request received for resource: %s\r\n", resource.c_str());
00853         // Copy data and length to coap response
00854     }
00855 
00856 private:
00857     M2MObject*  big_payload;
00858 };