research application on sending data to headend

Dependencies:   DataStore JobScheduler NetworkServices W5500Interface nanopb protocol

See "main.cpp" documentation on "API Documentation" tab for details about application.

Committer:
sgnezdov
Date:
Fri Aug 11 19:07:20 2017 +0000
Revision:
28:7214f7806526
Parent:
20:5b52a42b9a5d
fixed compilation bug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgnezdov 11:acaefb63fc6b 1 #include "jobSchedulesUpload.h"
sgnezdov 11:acaefb63fc6b 2
sgnezdov 11:acaefb63fc6b 3 #include "mbed-trace/mbed_trace.h"
sgnezdov 11:acaefb63fc6b 4 #define TRACE_GROUP "scup"
sgnezdov 11:acaefb63fc6b 5
sgnezdov 13:0fdbc14c33e7 6 #include "nanopb/source/protobuf/pb.h"
sgnezdov 13:0fdbc14c33e7 7 #include "nanopb/source/protobuf/pb_encode.h"
sgnezdov 13:0fdbc14c33e7 8 #include "protocol/source/job.pb.h"
sgnezdov 13:0fdbc14c33e7 9 #include <string.h>
sgnezdov 13:0fdbc14c33e7 10 #include "LinkedList.h"
sgnezdov 13:0fdbc14c33e7 11 #include "scheduler.h"
sgnezdov 13:0fdbc14c33e7 12 #include "schedules.h"
sgnezdov 13:0fdbc14c33e7 13
sgnezdov 14:65d69aed6540 14 bool fillScheduleData(protocol_Job_ScheduleData_t& pbSchedData, JobScheduler::Appointment& apt) {
sgnezdov 14:65d69aed6540 15 JobScheduler::Job* job = apt.GetJob();
sgnezdov 14:65d69aed6540 16 JobScheduler::ISchedule* schedule = job->GetSchedule();
sgnezdov 13:0fdbc14c33e7 17 int schedType = schedule->ScheduleType();
sgnezdov 13:0fdbc14c33e7 18 switch (schedType) {
sgnezdov 13:0fdbc14c33e7 19 case 1: {
sgnezdov 13:0fdbc14c33e7 20 // protocol_ScheduleType_RunOnce case
sgnezdov 13:0fdbc14c33e7 21 tr_debug("encoding RunOnceSchedule");
sgnezdov 13:0fdbc14c33e7 22 JobScheduler::RunOnceSchedule* s = static_cast<JobScheduler::RunOnceSchedule*>(schedule);
sgnezdov 13:0fdbc14c33e7 23 protocol_RunOnceSchedule pbSched;
sgnezdov 13:0fdbc14c33e7 24 pbSched.AtUnixSec = (uint32_t)s->AtTime();
sgnezdov 14:65d69aed6540 25 // Time should've been pushed to Appointment structure in all cases.
sgnezdov 14:65d69aed6540 26 if (pbSched.AtUnixSec != 0) {
sgnezdov 14:65d69aed6540 27 tr_warn("Run once has not be assigned to appointment yet. AtUnixSec: %d", pbSched.AtUnixSec);
sgnezdov 14:65d69aed6540 28 } else {
sgnezdov 14:65d69aed6540 29 pbSched.AtUnixSec = (uint32_t)apt.GetTime();
sgnezdov 14:65d69aed6540 30 }
sgnezdov 13:0fdbc14c33e7 31 pb_ostream_t stream = pb_ostream_from_buffer(pbSchedData.bytes, sizeof(pbSchedData.bytes));
sgnezdov 13:0fdbc14c33e7 32 pb_encode(&stream, protocol_RunOnceSchedule_fields, &pbSched);
sgnezdov 13:0fdbc14c33e7 33 pbSchedData.size = stream.bytes_written;
sgnezdov 14:65d69aed6540 34 //tr_debug("sizeof(pbSchedData.bytes): %d, AtUnixSec: %d, bytes written: %d", sizeof(pbSchedData.bytes), pbSched.AtUnixSec, stream.bytes_written);
sgnezdov 13:0fdbc14c33e7 35 return true;
sgnezdov 13:0fdbc14c33e7 36 }
sgnezdov 13:0fdbc14c33e7 37 case 2: {
sgnezdov 13:0fdbc14c33e7 38 // protocol_ScheduleType_Periodic case
sgnezdov 13:0fdbc14c33e7 39 tr_debug("encoding RunPeriodicSchedule");
sgnezdov 13:0fdbc14c33e7 40 //JobScheduler::RunPeriodicSchedule* s = static_cast<JobScheduler::RunPeriodicSchedule*>(schedule);
sgnezdov 13:0fdbc14c33e7 41 //protocol_PeriodicSchedule pbSched;
sgnezdov 13:0fdbc14c33e7 42 return true;
sgnezdov 13:0fdbc14c33e7 43 }
sgnezdov 13:0fdbc14c33e7 44 default: {
sgnezdov 13:0fdbc14c33e7 45 tr_error("Unknown schedule type %d", schedType);
sgnezdov 13:0fdbc14c33e7 46 return false;
sgnezdov 13:0fdbc14c33e7 47 }
sgnezdov 13:0fdbc14c33e7 48 }
sgnezdov 13:0fdbc14c33e7 49 }
sgnezdov 13:0fdbc14c33e7 50
sgnezdov 11:acaefb63fc6b 51 void JobSchedulesUpload::Run() {
sgnezdov 11:acaefb63fc6b 52 tr_info("Job Schedules Upload");
sgnezdov 13:0fdbc14c33e7 53
sgnezdov 18:133a51becbe1 54 // if used on the stack like:
sgnezdov 18:133a51becbe1 55 // protocol_JobList* pbJobsPtr = protocol_JobList_init_zero;
sgnezdov 18:133a51becbe1 56 // the code terminates with error:
sgnezdov 18:133a51becbe1 57 // CMSIS-RTOS error: Stack underflow (status: 0x1, task ID: 0x20002464, task name: )
sgnezdov 18:133a51becbe1 58 // shortly after quitting this function.
sgnezdov 20:5b52a42b9a5d 59 //
sgnezdov 20:5b52a42b9a5d 60 // Bob P recommendation: try static as a solution.
sgnezdov 20:5b52a42b9a5d 61
sgnezdov 28:7214f7806526 62 // protocol_JobList pbJobsPtr; /// = new protocol_JobList(); // protocol_JobList_init_zero;
sgnezdov 18:133a51becbe1 63
sgnezdov 18:133a51becbe1 64 protocol_JobList* pbJobsPtr = new protocol_JobList(); // protocol_JobList_init_zero;
sgnezdov 18:133a51becbe1 65 protocol_JobList& pbJobs = *pbJobsPtr;
sgnezdov 20:5b52a42b9a5d 66 //tr_debug("pbJobs size: %d", sizeof(pbJobs));
sgnezdov 18:133a51becbe1 67
sgnezdov 18:133a51becbe1 68 strcpy(pbJobs.sn, this->_conf.SerialNumber());
sgnezdov 13:0fdbc14c33e7 69
sgnezdov 18:133a51becbe1 70 {
sgnezdov 18:133a51becbe1 71 LinkedList<JobScheduler::Appointment> apts;
sgnezdov 18:133a51becbe1 72 this->_scheduler.AppointmentList(apts);
sgnezdov 18:133a51becbe1 73 node<JobScheduler::Appointment>* aptn = apts.pop(1);
sgnezdov 18:133a51becbe1 74 int idx = 0;
sgnezdov 18:133a51becbe1 75 pbJobs.items_count = 0;
sgnezdov 18:133a51becbe1 76 while (aptn != NULL) {
sgnezdov 18:133a51becbe1 77 JobScheduler::Appointment* apt = aptn->data;
sgnezdov 18:133a51becbe1 78 JobScheduler::Job* job = apt->GetJob();
sgnezdov 18:133a51becbe1 79 tr_debug("adding job ID: %d, type: %d\n", job->GetID(), job->GetTypeID());
sgnezdov 18:133a51becbe1 80 pbJobs.items[idx].ID = job->GetID();
sgnezdov 18:133a51becbe1 81 pbJobs.items[idx].TypeID = job->GetTypeID();
sgnezdov 18:133a51becbe1 82 pbJobs.items[idx].ScheduleTypeID = static_cast<protocol_ScheduleType>(job->GetSchedule()->ScheduleType());
sgnezdov 18:133a51becbe1 83 // pbJobs.items[idx].ScheduleData =
sgnezdov 18:133a51becbe1 84 if (!fillScheduleData(pbJobs.items[idx].ScheduleData, *apt)) {
sgnezdov 18:133a51becbe1 85 tr_error("job error: failed to fill schedule");
sgnezdov 18:133a51becbe1 86 return;
sgnezdov 18:133a51becbe1 87 }
sgnezdov 18:133a51becbe1 88 //tr_debug("schedule data size: %d", pbJobs.items[idx].ScheduleData.size);
sgnezdov 18:133a51becbe1 89 // pbJobs.items[idx].Data =
sgnezdov 20:5b52a42b9a5d 90 idx++;
sgnezdov 18:133a51becbe1 91 pbJobs.items_count = idx;
sgnezdov 18:133a51becbe1 92
sgnezdov 18:133a51becbe1 93 apts.remove(1);
sgnezdov 18:133a51becbe1 94 aptn = apts.pop(1);
sgnezdov 20:5b52a42b9a5d 95 }
sgnezdov 20:5b52a42b9a5d 96 if (idx == 0) {
sgnezdov 20:5b52a42b9a5d 97 tr_info("There are no jobs to send.");
sgnezdov 18:133a51becbe1 98 }
sgnezdov 18:133a51becbe1 99 }
sgnezdov 18:133a51becbe1 100
sgnezdov 18:133a51becbe1 101 // encode to nothing to detect buffer size
sgnezdov 18:133a51becbe1 102 pb_ostream_t sizeStream = {0};
sgnezdov 18:133a51becbe1 103 pb_encode(&sizeStream, protocol_JobList_fields, &pbJobs);
sgnezdov 18:133a51becbe1 104
sgnezdov 18:133a51becbe1 105 // allocate output buffer and encode into it
sgnezdov 18:133a51becbe1 106 uint8_t* outBuf = new uint8_t[sizeStream.bytes_written];
sgnezdov 18:133a51becbe1 107 pb_ostream_t outStream = pb_ostream_from_buffer(outBuf, sizeStream.bytes_written);
sgnezdov 18:133a51becbe1 108 pb_encode(&outStream, protocol_JobList_fields, &pbJobs);
sgnezdov 18:133a51becbe1 109
sgnezdov 18:133a51becbe1 110 tr_array(outBuf, outStream.bytes_written);
sgnezdov 16:bef1673b199e 111
sgnezdov 16:bef1673b199e 112 // send CoAP message
sgnezdov 16:bef1673b199e 113 time_t now = time(NULL);
sgnezdov 17:b79ce8109995 114
sgnezdov 18:133a51becbe1 115 //uint8_t msg[] = { 0x0a, 0x07, 0x4e, 0x75, 0x63, 0x6c, 0x65, 0x6f, 0x31 };
sgnezdov 18:133a51becbe1 116 //size_t msgLen = 9;
sgnezdov 18:133a51becbe1 117 //_lce.SendV1("/uw/joblist", msg, msgLen, false, now);
sgnezdov 17:b79ce8109995 118
sgnezdov 18:133a51becbe1 119 _lce.SendV1("/uw/joblist", outBuf, outStream.bytes_written, false, now);
sgnezdov 18:133a51becbe1 120 delete outBuf;
sgnezdov 18:133a51becbe1 121 delete pbJobsPtr;
sgnezdov 11:acaefb63fc6b 122 }
sgnezdov 11:acaefb63fc6b 123
sgnezdov 11:acaefb63fc6b 124
sgnezdov 11:acaefb63fc6b 125