k64f targated antenna alignment tool with lwm2m client capabilities.
Dependencies: FXOS8700Q-driver MODSERIAL
Fork of mbed-os-example-client by
Diff: resources.h
- Revision:
- 52:74019970a2bf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources.h Fri Jan 20 12:34:35 2017 +0000 @@ -0,0 +1,858 @@ +#include "simpleclient.h" +#include "mbed-trace/mbed_trace.h" +#include "mbedtls/entropy_poll.h" +#include "FXOS8700Q.h" +#include "MODSERIAL.h" + +#define PI 3.14159265 + +//MODSERIAL gps +MODSERIAL gps(PTD3, PTD2); // (PTC17, PTC16) UART3 not functional on etherenet enabling +I2C i2c(PTE25, PTE24); // Configured for the FRDM-K64F with onboard sensors +FXOS8700QAccelerometer accel(i2c,FXOS8700CQ_SLAVE_ADDR1); +char cDataBuffer[500]; + +struct gnss_params +{ + float latitude; //Latitude + float longitude; //Longitude + float altitude; //Altitude + float baselineLen; //BaseLine Length + float heading; // Heading + int date; + int time; + int fix_quality; // 0 INVALID, 1 GPS, 2 DIFF + int numsat; +}; + + +#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI + #if TARGET_UBLOX_EVK_ODIN_W2 + #include "OdinWiFiInterface.h" + OdinWiFiInterface wifi; + #else + #include "ESP8266Interface.h" + ESP8266Interface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX); + #endif +#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET + #include "EthernetInterface.h" + EthernetInterface eth; +#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND + #define MESH + #include "NanostackInterface.h" + LoWPANNDInterface mesh; +#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD + #define MESH + #include "NanostackInterface.h" + ThreadInterface mesh; +#endif + +#if defined(MESH) +#if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL +#include "NanostackRfPhyAtmel.h" +NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS, + ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL); +#elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20 +#include "NanostackRfPhyMcr20a.h" +NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ); +#endif //MBED_CONF_APP_RADIO_TYPE +#endif //MESH + +#ifdef MESH + // Mesh does not have DNS, so must use direct IPV6 address + #define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684" +#else + // This is address to mbed Device Connector, name based + // assume all other stacks support DNS properly + #define MBED_SERVER_ADDRESS "coap://leshan.eclipse.org:5683" //"coap://api.connector.mbed.com:5684" +#endif + +RawSerial output(USBTX, USBRX); + +// Status indication +DigitalOut red_led(LED1); +DigitalOut green_led(LED2); +DigitalOut blue_led(LED3); +//Ticker status_ticker; +void blinky() { + red_led = !red_led; + +} + +// These are example resource values for the Device Object +struct MbedClientDevice device = { + "RJio", // Manufacturer + "Netra2.0", // Type + "0.01", // ModelNumber + "007" // SerialNumber +}; + +// Instantiate the class which implements LWM2M Client API (from simpleclient.h) +MbedClient mbed_client(device); + + +// In case of K64F board , there is button resource available +// to change resource value and unregister +#ifdef TARGET_K64F +// Set up Hardware interrupt button. +InterruptIn obs_button(SW2); +InterruptIn unreg_button(SW3); +#endif + +// set up a timer to simulate updating resource, +// there is no functionality to unregister. +Ticker timer; + +/* + * Arguments for running "blink" in it's own thread. + */ +class BlinkArgs { +public: + BlinkArgs() { + clear(); + } + void clear() { + position = 0; + blink_pattern.clear(); + } + uint16_t position; + std::vector<uint32_t> blink_pattern; +}; + +/* + * The Led contains one property (pattern) and a function (blink). + * When the function blink is executed, the pattern is read, and the LED + * will blink based on the pattern. + */ +class LedResource { +public: + LedResource() { + // create ObjectID with metadata tag of '3201', which is 'digital output' + led_object = M2MInterfaceFactory::create_object("3201"); + M2MObjectInstance* led_inst = led_object->create_object_instance(); + + // 5853 = Multi-state output + M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern", + M2MResourceInstance::STRING, false); + // read and write + pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED); + // set initial pattern (toggle every 200ms. 7 toggles in total) + pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27); + + // there's not really an execute LWM2M ID that matches... hmm... + M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink", + M2MResourceInstance::OPAQUE, false); + // we allow executing a function here... + led_res->set_operation(M2MBase::POST_ALLOWED); + // when a POST comes in, we want to execute the led_execute_callback + led_res->set_execute_function(execute_callback(this, &LedResource::blink)); + // Completion of execute function can take a time, that's why delayed response is used + led_res->set_delayed_response(true); + blink_args = new BlinkArgs(); + } + + ~LedResource() { + delete blink_args; + } + + M2MObject* get_object() { + return led_object; + } + + void blink(void *argument) { + // read the value of 'Pattern' + //status_ticker.detach(); + green_led = 1; + + M2MObjectInstance* inst = led_object->object_instance(); + M2MResource* res = inst->resource("5853"); + // Clear previous blink data + blink_args->clear(); + + // values in mbed Client are all buffers, and we need a vector of int's + uint8_t* buffIn = NULL; + uint32_t sizeIn; + res->get_value(buffIn, sizeIn); + + // turn the buffer into a string, and initialize a vector<int> on the heap + std::string s((char*)buffIn, sizeIn); + free(buffIn); + output.printf("led_execute_callback pattern=%s\r\n", s.c_str()); + + // our pattern is something like 500:200:500, so parse that + std::size_t found = s.find_first_of(":"); + while (found!=std::string::npos) { + blink_args->blink_pattern.push_back(atoi((const char*)s.substr(0,found).c_str())); + s = s.substr(found+1); + found=s.find_first_of(":"); + if(found == std::string::npos) { + blink_args->blink_pattern.push_back(atoi((const char*)s.c_str())); + } + } + // check if POST contains payload + if (argument) { + M2MResource::M2MExecuteParameter* param = (M2MResource::M2MExecuteParameter*)argument; + String object_name = param->get_argument_object_name(); + uint16_t object_instance_id = param->get_argument_object_instance_id(); + String resource_name = param->get_argument_resource_name(); + int payload_length = param->get_argument_value_length(); + uint8_t* payload = param->get_argument_value(); + output.printf("Resource: %s/%d/%s executed\r\n", object_name.c_str(), object_instance_id, resource_name.c_str()); + output.printf("Payload: %.*s\r\n", payload_length, payload); + } + // do_blink is called with the vector, and starting at -1 + blinky_thread.start(this, &LedResource::do_blink); + } + +private: + M2MObject* led_object; + Thread blinky_thread; + BlinkArgs *blink_args; + void do_blink() { + for (;;) { + // blink the LED + green_led = !green_led; + // up the position, if we reached the end of the vector + if (blink_args->position >= blink_args->blink_pattern.size()) { + // send delayed response after blink is done + M2MObjectInstance* inst = led_object->object_instance(); + M2MResource* led_res = inst->resource("5850"); + led_res->send_delayed_post_response(); + red_led = 1; + //status_ticker.attach_us(blinky, 250000); + return; + } + // Wait requested time, then continue prosessing the blink pattern from next position. + Thread::wait(blink_args->blink_pattern.at(blink_args->position)); + blink_args->position++; + } + } +}; + +/* + * The button contains one property (click count). + * When `handle_button_click` is executed, the counter updates. + */ +class ButtonResource { +public: + ButtonResource(): counter(0) { + // create ObjectID with metadata tag of '3200', which is 'digital input' + btn_object = M2MInterfaceFactory::create_object("3200"); + M2MObjectInstance* btn_inst = btn_object->create_object_instance(); + // create resource with ID '5501', which is digital input counter + M2MResource* btn_res = btn_inst->create_dynamic_resource("5501", "Button", + M2MResourceInstance::INTEGER, true /* observable */); + // we can read this value + btn_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + btn_res->set_value((uint8_t*)"0", 1); + } + + ~ButtonResource() { + } + + M2MObject* get_object() { + return btn_object; + } + + /* + * When you press the button, we read the current value of the click counter + * from mbed Device Connector, then up the value with one. + */ + void handle_button_click() { + M2MObjectInstance* inst = btn_object->object_instance(); + M2MResource* res = inst->resource("5501"); + + // up counter + counter++; +#ifdef TARGET_K64F + //printf("handle_button_click, new value of counter is %d\r\n", counter); +#endif + + // serialize the value of counter as a string, and tell connector + char buffer[20]; + int size = sprintf(buffer,"%d",counter); + res->set_value((uint8_t*)buffer, size); + } + +private: + M2MObject* btn_object; + uint16_t counter; +}; + +/* + * The GNSS contains 1 property (Azimuth). + * When `handle_azimuth_update` is executed, the azimuth updates. + */ +class GnssResource { +public: + GnssResource(): azimuth(0) { + // create ObjectID with metadata tag of '3336', which is 'GPS location' + gnss_object = M2MInterfaceFactory::create_object("3336"); + + M2MObjectInstance* gnss_inst = gnss_object->create_object_instance(); + // create resource with ID '5513', which is digital input Latitude + M2MResource* lat_res = gnss_inst->create_dynamic_resource("5513", "Latitude", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + lat_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + lat_res->set_value(0.0); + + M2MResource* long_res = gnss_inst->create_dynamic_resource("5514", "Longitude", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + long_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + long_res->set_value(0.0); + + M2MResource* alt_res = gnss_inst->create_dynamic_resource("5515", "Altitude", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + alt_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + alt_res->set_value(0.0); + + M2MResource* azi_res = gnss_inst->create_dynamic_resource("5705", "Heading", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + azi_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + azi_res->set_value(0.0); + + M2MResource* app_res = gnss_inst->create_dynamic_resource("5750", "AppType", + M2MResourceInstance::STRING, true /* observable */); + // we can read this value + app_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + size = sprintf(buffer,"%s","AntennaAlignment"); + app_res->set_value((const uint8_t*)buffer, size); + +#if 0 + M2MResource* time_res = gnss_inst->create_dynamic_resource("5707", "Time", + M2MResourceInstance::INTEGER, true /* observable */); + // we can read this value + time_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + time_res->set_value((uint8_t*)"0", 1); + + M2MResource* numsat_res = gnss_inst->create_dynamic_resource("5708", "NumSat", + M2MResourceInstance::INTEGER, true /* observable */); + // we can read this value + numsat_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + numsat_res->set_value((uint8_t*)"0", 1); + + M2MResource* blen_res = gnss_inst->create_dynamic_resource("5709", "BaseLen", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + blen_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + blen_res->set_value(0.0); + + M2MResource* fq_res = gnss_inst->create_dynamic_resource("5710", "FixQuality", + M2MResourceInstance::INTEGER, true /* observable */); + // we can read this value + fq_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + fq_res->set_value((uint8_t*)"0", 1); + + M2MResource* date_res = gnss_inst->create_dynamic_resource("5706", "Date", + M2MResourceInstance::INTEGER, true /* observable */); + // we can read this value + date_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + date_res->set_value((uint8_t*)"0", 1); +#endif + + } + + ~GnssResource() { + } + + M2MObject* get_object() { + return gnss_object; + } + + /* + * When you press the button, we read the current value of the click azimuth + * from mbed Device Connector, then up the value with one. + */ + void gps_scan(void) + { + char c; + PSTI32 = false; GPGGA = false; + Timer timeout; + timeout.start(); + + while((!PSTI32 || !GPGGA) && (timeout.read() < 10)) + { + if(gps.readable()) + { + if(gps.getc() == '$'); // wait for a $ + { + for(int i=0; i<sizeof(cDataBuffer); i++) + { + c = gps.getc(); + if( c == '\r' ) + { + //pc.printf("%s\n", cDataBuffer); + parse(cDataBuffer, i); + i = sizeof(cDataBuffer); + } + else + { + cDataBuffer[i] = c; + } + } + } + } + else break; + } + timeout.stop(); + } + + void parse(char *cmd, int n) + { + char ns, ew, tf, status, mode; + int fq, nst, fix, date, timefix, pstino; // fix quality, Number of satellites being tracked, 3D fix + float latitude, longitude, speed, altitude, eastprj, northprj, upprj, blength, bcourse; + + // Global Positioning System Fix Data + if(strncmp(cmd,"$GPGGA", 6) == 0) + { + sscanf(cmd, "$GPGGA,%d,%f,%c,%f,%c,%d,%d,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude); + //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); + gnss_scan.latitude = latitude; + gnss_scan.longitude = longitude; + //gnss_scan.date = date; + gnss_scan.time = timefix; + gnss_scan.altitude = altitude; + gnss_scan.fix_quality = fq; + gnss_scan.numsat = nst; + GPGGA = true; + } + + // Baseline length, Azimuth + if(strncmp(cmd,"$PSTI", 5) == 0) + { + sscanf(cmd, "$PSTI,%d,%d,%d,%c,%c,%f,%f,%f,%f,%f", &pstino, &timefix, &date, &status, &mode, &eastprj, &northprj, &upprj, &blength, &bcourse); + if(32 == pstino) + { + //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); + gnss_scan.heading = bcourse; gnss_scan.date = date; gnss_scan.time = timefix; + gnss_scan.baselineLen = blength; //BaseLine Length + PSTI32 = true; + } + } +#if 0 + // Satellite status + if(strncmp(cmd,"$GPGSA", 6) == 0) + { + sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst); + pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst); + } + + // Geographic position, Latitude and Longitude + if(strncmp(cmd,"$GPGLL", 6) == 0) + { + sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix); + pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix); + } + + // Geographic position, Latitude and Longitude + if(strncmp(cmd,"$GPRMC", 6) == 0) + { + sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date); + 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); + } +#endif + } + void handle_gnss_update() { + M2MObjectInstance* inst = gnss_object->object_instance(); + M2MResource* latituderes = inst->resource("5513"); + M2MResource* longituderes = inst->resource("5514"); + M2MResource* altres = inst->resource("5515"); + M2MResource* azimuthres = inst->resource("5705"); + M2MResource* appres = inst->resource("5750"); + + gps_scan(); + + size = sprintf(buffer,"%f",gnss_scan.latitude); + latituderes->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%f",gnss_scan.longitude); + longituderes->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%f",gnss_scan.altitude); + altres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%f",gnss_scan.heading); + azimuthres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%s","AntennaAlignment"); + appres->set_value((const uint8_t*)buffer, size); + +#if 0 + + M2MResource* dateres = inst->resource("5706"); + M2MResource* timeres = inst->resource("5707"); + M2MResource* numsatres = inst->resource("5708"); + M2MResource* blenres = inst->resource("5709"); + M2MResource* fqres = inst->resource("5710"); + + size = sprintf(buffer,"%d",gnss_scan.date); + dateres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%d",gnss_scan.time); + timeres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%d",gnss_scan.numsat); + numsatres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%f",gnss_scan.baselineLen); + blenres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%d",gnss_scan.fix_quality); + fqres->set_value((const uint8_t*)buffer, size); +#endif + + output.printf("GNSS data updated\n"); + } + +private: + M2MObject* gnss_object; + uint16_t azimuth; + bool PSTI32; + bool GPGGA; + gnss_params gnss_scan; + char buffer[20]; + int size; +}; + +const uint8_t STATIC_VALUE[] = "Cellular Antenna Alignment"; +/* + * The GNSS custom object + */ +/* + * The GNSS custom object + */ +class GnssCustomResource { +public: + GnssCustomResource() { + // create ObjectID with metadata custom tag + gnss_object = M2MInterfaceFactory::create_object("JioNetraGNSScompass"); + M2MObjectInstance* gnss_inst = gnss_object->create_object_instance(); + + + M2MResource* lat_res = gnss_inst->create_dynamic_resource("E", + "JioLatitude", + M2MResourceInstance::FLOAT, + true); + // we can read this value + lat_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + lat_res->set_value(0.0); + + M2MResource* app_res = gnss_inst->create_static_resource("N", + "JioAppType", + M2MResourceInstance::STRING, + STATIC_VALUE, + sizeof(STATIC_VALUE)-1); + // we can read this value + app_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + size = sprintf(buffer,"%s","AntennaAlignment"); + app_res->set_value((const uint8_t*)buffer, size); + + + } + + ~GnssCustomResource() { + } + + M2MObject* get_object() { + return gnss_object; + } + + /* + * When you press the button, we read the current value of the click azimuth + * from mbed Device Connector, then up the value with one. + */ + void gps_scan(void) + { + char c; + PSTI32 = false; GPGGA = false; + Timer timeout; + timeout.start(); + + while((!PSTI32 || !GPGGA) && (timeout.read() < 10)) + { + if(gps.readable()) + { + if(gps.getc() == '$'); // wait for a $ + { + for(int i=0; i<sizeof(cDataBuffer); i++) + { + c = gps.getc(); + if( c == '\r' ) + { + //pc.printf("%s\n", cDataBuffer); + parse(cDataBuffer, i); + i = sizeof(cDataBuffer); + } + else + { + cDataBuffer[i] = c; + } + } + } + } + else break; + } + timeout.stop(); + } + + void parse(char *cmd, int n) + { + char ns, ew, tf, status, mode; + int fq, nst, fix, date, timefix, pstino; // fix quality, Number of satellites being tracked, 3D fix + float latitude, longitude, speed, altitude, eastprj, northprj, upprj, blength, bcourse; + + // Global Positioning System Fix Data + if(strncmp(cmd,"$GPGGA", 6) == 0) + { + sscanf(cmd, "$GPGGA,%d,%f,%c,%f,%c,%d,%d,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude); + //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); + gnss_scan.latitude = latitude; + gnss_scan.longitude = longitude; + //gnss_scan.date = date; + gnss_scan.time = timefix; + gnss_scan.altitude = altitude; + gnss_scan.fix_quality = fq; + gnss_scan.numsat = nst; + GPGGA = true; + } + + // Baseline length, Azimuth + if(strncmp(cmd,"$PSTI", 5) == 0) + { + sscanf(cmd, "$PSTI,%d,%d,%d,%c,%c,%f,%f,%f,%f,%f", &pstino, &timefix, &date, &status, &mode, &eastprj, &northprj, &upprj, &blength, &bcourse); + if(32 == pstino) + { + //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); + gnss_scan.heading = bcourse; gnss_scan.date = date; gnss_scan.time = timefix; + gnss_scan.baselineLen = blength; //BaseLine Length + PSTI32 = true; + } + } +#if 0 + // Satellite status + if(strncmp(cmd,"$GPGSA", 6) == 0) + { + sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst); + pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst); + } + + // Geographic position, Latitude and Longitude + if(strncmp(cmd,"$GPGLL", 6) == 0) + { + sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix); + pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix); + } + + // Geographic position, Latitude and Longitude + if(strncmp(cmd,"$GPRMC", 6) == 0) + { + sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date); + 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); + } +#endif + } + void handle_gnss_update() { + M2MObjectInstance* inst = gnss_object->object_instance(); + M2MResource* latituderes = inst->resource("E"); + M2MResource* appres = inst->resource("N"); + + gps_scan(); + + size = sprintf(buffer,"%f",gnss_scan.latitude); + latituderes->set_value((const uint8_t*)buffer, size); + + + output.printf("GNSS data updated\n"); + } + +private: + M2MObject* gnss_object; + uint16_t azimuth; + bool PSTI32; + bool GPGGA; + gnss_params gnss_scan; + char buffer[20]; + int size; +}; + +class AccelResource { +public: + AccelResource(){ + + // create ObjectID with metadata tag of '3313', which is 'IPSO Accelerometer' + accel_object = M2MInterfaceFactory::create_object("3313"); + M2MObjectInstance* accel_inst = accel_object->create_object_instance(); + + // create resource with ID '5701', which is accelerometer units + M2MResource* units_res = accel_inst->create_dynamic_resource("5701", "Units", + M2MResourceInstance::STRING, false /* non-observable */); + // we can read this value + units_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + size = sprintf(buffer,"%s","degrees"); + units_res->set_value((const uint8_t*)buffer, size); + + + // create resource with ID '5702', which is accelerometer X value + M2MResource* x_res = accel_inst->create_dynamic_resource("5702", "Tilt", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + x_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + size = sprintf(buffer,"%f",0.0); + x_res->set_value((const uint8_t*)buffer, size); + + // create resource with ID '5703', which is accelerometer Y value + M2MResource* y_res = accel_inst->create_dynamic_resource("5703", "Roll", + M2MResourceInstance::FLOAT, true /* observable */); + // we can read this value + y_res->set_operation(M2MBase::GET_ALLOWED); + // set initial value (all values in mbed Client are buffers) + // to be able to read this data easily in the Connector console, we'll use a string + size = sprintf(buffer,"%f",0.0); + y_res->set_value((const uint8_t*)buffer, size); + + } + + ~AccelResource() { + } + + M2MObject* get_object() { + return accel_object; + } + + /* + * Timer based update triggers planned + */ + + void handle_accel_update() + { + double angleX, denomX_T, denomX_A, denomX_B, denomX_C; //intializing variable to hold the angle calculation + double angleY, denomY_T, denomY_A, denomY_B, denomY_C; + float faX, faY, faZ; + + M2MObjectInstance* inst = accel_object->object_instance(); + M2MResource* xres = inst->resource("5702"); + M2MResource* yres = inst->resource("5703"); + + // Read accelerometer data + //accel.getAxis(acc_data); + accel.getX(faX); + accel.getY(faY); + accel.getZ(faZ); + + // Canculate angles in degrees + //X-AXIS + denomX_A = pow(faY, 2); + denomX_B = pow(faZ, 2); + denomX_C = denomX_A + denomX_B; + denomX_T = pow(denomX_C, .5); //pow returns base raised to the power exponent + + angleX = atan(faX/denomX_T) * 180/PI; //should calculate the angle on the X axis in degrees based on raw data + + //Y-AXIS + denomY_A = pow(faX, 2); + denomY_B = pow(faZ, 2); + denomY_C = denomY_A + denomY_B; + denomY_T = pow(denomY_C, .5); //pow returns base raised to the power exponent + + angleY = atan(faY/denomY_T) * 180/PI; //should calculate the angle on the Y axis in degrees based on raw data + + // serialize the value of x & y accel ops as a string, and tell connector + size = sprintf(buffer,"%f",angleX); + xres->set_value((const uint8_t*)buffer, size); + + size = sprintf(buffer,"%f",angleY); + yres->set_value((const uint8_t*)buffer, size); + printf("Accelerometer update, x:%f degrees, y:%f degrees\r\n", angleX, angleY ); + + } + +private: + M2MObject* accel_object; + //motion_data_units_t acc_data; + char buffer[20]; + int size; +}; + +class BigPayloadResource { +public: + BigPayloadResource() { + big_payload = M2MInterfaceFactory::create_object("1000"); + M2MObjectInstance* payload_inst = big_payload->create_object_instance(); + M2MResource* payload_res = payload_inst->create_dynamic_resource("1", "BigData", + M2MResourceInstance::STRING, true /* observable */); + payload_res->set_operation(M2MBase::GET_PUT_ALLOWED); + payload_res->set_value((uint8_t*)"0", 1); + payload_res->set_incoming_block_message_callback( + incoming_block_message_callback(this, &BigPayloadResource::block_message_received)); + payload_res->set_outgoing_block_message_callback( + outgoing_block_message_callback(this, &BigPayloadResource::block_message_requested)); + } + + M2MObject* get_object() { + return big_payload; + } + + void block_message_received(M2MBlockMessage *argument) { + if (argument) { + if (M2MBlockMessage::ErrorNone == argument->error_code()) { + if (argument->is_last_block()) { + output.printf("Last block received\r\n"); + } + output.printf("Block number: %d\r\n", argument->block_number()); + // First block received + if (argument->block_number() == 0) { + // Store block + // More blocks coming + } else { + // Store blocks + } + } else { + output.printf("Error when receiving block message! - EntityTooLarge\r\n"); + } + output.printf("Total message size: %d\r\n", argument->total_message_size()); + } + } + + void block_message_requested(const String& resource, uint8_t *&/*data*/, uint32_t &/*len*/) { + output.printf("GET request received for resource: %s\r\n", resource.c_str()); + // Copy data and length to coap response + } + +private: + M2MObject* big_payload; +}; \ No newline at end of file