Erick / Mbed 2 deprecated ICE_BLE_TEST

Dependencies:   NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed

Fork of ICE by Erick

Committer:
jmarkel44
Date:
Tue Sep 20 12:49:58 2016 +0000
Revision:
80:b12b0adfcdc2
Parent:
77:43e0a3d9e536
Child:
84:7b7cad3ba139
unregister function implemented;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmarkel44 70:7427f4959201 1 /******************************************************************************
jmarkel44 70:7427f4959201 2 *
jmarkel44 70:7427f4959201 3 * File: OutputTask.cpp
jmarkel44 70:7427f4959201 4 * Desciption: source for the ICE Output task
jmarkel44 70:7427f4959201 5 *
jmarkel44 70:7427f4959201 6 *****************************************************************************/
jmarkel44 67:49f266601d83 7 #include "OutputTask.h"
jmarkel44 48:1c7861d80d16 8 #include "global.h"
jmarkel44 66:db1425574b58 9 #include "MbedJSONValue.h"
jmarkel44 70:7427f4959201 10 #include <vector>
jmarkel44 77:43e0a3d9e536 11 #include <string>
jmarkel44 77:43e0a3d9e536 12 #include <algorithm>
jmarkel44 48:1c7861d80d16 13
jmarkel44 70:7427f4959201 14 // locals
jmarkel44 67:49f266601d83 15 static int createOutput(const char *controlFile);
jmarkel44 66:db1425574b58 16 static void loadPersistentOutputs(void);
jmarkel44 63:0ded43237b22 17
jmarkel44 74:03ccf04998b5 18 // local helpers
jmarkel44 77:43e0a3d9e536 19 static int enableOutputReq (const char* id, unsigned int pri, const char* output);
jmarkel44 77:43e0a3d9e536 20 static int disableOutputReq (const char *id, unsigned int pri, const char *output);
jmarkel44 72:3754b352f156 21 static int unregisterControl(const char *id, unsigned int pri, const char *output);
jmarkel44 71:34856d21f2bf 22
jmarkel44 71:34856d21f2bf 23 typedef std::map<string, vector<Control> > StringOutputVector_t;
jmarkel44 77:43e0a3d9e536 24 StringOutputVector_t outputMap;
jmarkel44 66:db1425574b58 25
jmarkel44 80:b12b0adfcdc2 26 bool operator<(const Control &control1, const Control &control2)
jmarkel44 80:b12b0adfcdc2 27 {
jmarkel44 77:43e0a3d9e536 28 return control1.getPriority() < control2.getPriority();
jmarkel44 77:43e0a3d9e536 29 }
jmarkel44 63:0ded43237b22 30
jmarkel44 70:7427f4959201 31 /*****************************************************************************
jmarkel44 70:7427f4959201 32 * Function: OutputTask
jmarkel44 70:7427f4959201 33 * Description: Main entry point for the Output Task
jmarkel44 70:7427f4959201 34 *
jmarkel44 70:7427f4959201 35 * @param args -> not used
jmarkel44 70:7427f4959201 36 * @return none
jmarkel44 70:7427f4959201 37 *****************************************************************************/
jmarkel44 48:1c7861d80d16 38 void OutputTask(void const *args)
jmarkel44 48:1c7861d80d16 39 {
jmarkel44 80:b12b0adfcdc2 40 int rc;
jmarkel44 51:66b820f203a5 41 UNUSED(args);
jmarkel44 70:7427f4959201 42
jmarkel44 67:49f266601d83 43 printf("\r%s has started...\n", __func__);
jmarkel44 63:0ded43237b22 44
jmarkel44 66:db1425574b58 45 loadPersistentOutputs();
jmarkel44 75:96512ccc0443 46 osSignalSet(mainThreadId, sig_output_continue);
jmarkel44 75:96512ccc0443 47
jmarkel44 66:db1425574b58 48
jmarkel44 48:1c7861d80d16 49 while (true) {
jmarkel44 51:66b820f203a5 50 // wait for an event
jmarkel44 56:225786c56315 51 osEvent evt = OutputMasterMailBox.get();
jmarkel44 51:66b820f203a5 52 if (evt.status == osEventMail) {
jmarkel44 80:b12b0adfcdc2 53
jmarkel44 63:0ded43237b22 54 OutputControlMsg_t *msg = (OutputControlMsg_t*) evt.value.p;
jmarkel44 63:0ded43237b22 55
jmarkel44 63:0ded43237b22 56 switch ( msg->action ) {
jmarkel44 63:0ded43237b22 57 case ACTION_NEW:
jmarkel44 63:0ded43237b22 58 // read the file and and create an output entry
jmarkel44 80:b12b0adfcdc2 59 rc = createOutput(msg->controlFile);
jmarkel44 80:b12b0adfcdc2 60 if ( rc != 0 ) {
jmarkel44 80:b12b0adfcdc2 61 logError("%s: failed to create output %s\n",
jmarkel44 80:b12b0adfcdc2 62 __func__, msg->controlFile);
jmarkel44 80:b12b0adfcdc2 63 }
jmarkel44 63:0ded43237b22 64 break;
jmarkel44 71:34856d21f2bf 65 case ACTION_CONTROL_ON:
jmarkel44 77:43e0a3d9e536 66 logInfo("%s is requesting ON control of %s", msg->id, msg->output);
jmarkel44 80:b12b0adfcdc2 67 rc = enableOutputReq(msg->id, msg->priority, msg->output);
jmarkel44 80:b12b0adfcdc2 68 if ( rc != 0 ) {
jmarkel44 80:b12b0adfcdc2 69 logError("%s: failed to enabled output for %s",
jmarkel44 80:b12b0adfcdc2 70 __func__, msg->id);
jmarkel44 80:b12b0adfcdc2 71 }
jmarkel44 71:34856d21f2bf 72 break;
jmarkel44 71:34856d21f2bf 73 case ACTION_CONTROL_OFF:
jmarkel44 77:43e0a3d9e536 74 logInfo("%s is requesting OFF control of %s", msg->id, msg->output);
jmarkel44 80:b12b0adfcdc2 75 rc = disableOutputReq(msg->id, msg->priority, msg->output);
jmarkel44 80:b12b0adfcdc2 76 if ( rc != 0 ) {
jmarkel44 80:b12b0adfcdc2 77 printf("%s: failed to disabled output for %s",
jmarkel44 80:b12b0adfcdc2 78 __func__, msg->id);
jmarkel44 80:b12b0adfcdc2 79 }
jmarkel44 71:34856d21f2bf 80 break;
jmarkel44 72:3754b352f156 81 case ACTION_CONTROL_UNREGISTER:
jmarkel44 77:43e0a3d9e536 82 logInfo("%s is requesting its deletion from %s", msg->id, msg->output);
jmarkel44 80:b12b0adfcdc2 83 rc = unregisterControl(msg->id, msg->priority, msg->output);
jmarkel44 80:b12b0adfcdc2 84 if ( rc != 0 ) {
jmarkel44 80:b12b0adfcdc2 85 printf("%s: failed to unregister control %s",
jmarkel44 80:b12b0adfcdc2 86 __func__, msg->id);
jmarkel44 80:b12b0adfcdc2 87 }
jmarkel44 72:3754b352f156 88 break;
jmarkel44 63:0ded43237b22 89 default:
jmarkel44 63:0ded43237b22 90 break;
jmarkel44 63:0ded43237b22 91 }
jmarkel44 63:0ded43237b22 92
jmarkel44 56:225786c56315 93 // free the message
jmarkel44 56:225786c56315 94 OutputMasterMailBox.free(msg);
jmarkel44 51:66b820f203a5 95 }
jmarkel44 48:1c7861d80d16 96 }
jmarkel44 66:db1425574b58 97 }
jmarkel44 66:db1425574b58 98
jmarkel44 70:7427f4959201 99 /*****************************************************************************
jmarkel44 70:7427f4959201 100 * Function: DisplayOutputs
jmarkel44 70:7427f4959201 101 * Description: Display a list of outputs and its controls
jmarkel44 70:7427f4959201 102 *
jmarkel44 70:7427f4959201 103 * @param args -> not used
jmarkel44 70:7427f4959201 104 * @return none
jmarkel44 70:7427f4959201 105 *****************************************************************************/
jmarkel44 66:db1425574b58 106 void DisplayOutputs(void)
jmarkel44 66:db1425574b58 107 {
jmarkel44 66:db1425574b58 108 StringOutputVector_t::iterator pos;
jmarkel44 66:db1425574b58 109
jmarkel44 66:db1425574b58 110 for ( pos = outputMap.begin(); pos != outputMap.end(); ++pos ) {
jmarkel44 71:34856d21f2bf 111 if ( pos->second.empty() ) {
jmarkel44 71:34856d21f2bf 112 printf("\r [%s]->[no controls]\n", pos->first.c_str());
jmarkel44 71:34856d21f2bf 113 } else {
jmarkel44 71:34856d21f2bf 114 printf("\r [%s]->", pos->first.c_str());
jmarkel44 71:34856d21f2bf 115 vector<Control>::iterator i;
jmarkel44 71:34856d21f2bf 116 for ( i = pos->second.begin(); i != pos->second.end(); ++i ) {
jmarkel44 71:34856d21f2bf 117 i->display();
jmarkel44 71:34856d21f2bf 118 }
jmarkel44 71:34856d21f2bf 119 printf("\n");
jmarkel44 71:34856d21f2bf 120 }
jmarkel44 66:db1425574b58 121 }
jmarkel44 66:db1425574b58 122 printf("\r\n");
jmarkel44 66:db1425574b58 123 }
jmarkel44 66:db1425574b58 124
jmarkel44 71:34856d21f2bf 125
jmarkel44 71:34856d21f2bf 126 /*****************************************************************************
jmarkel44 72:3754b352f156 127 * Function: createOutput
jmarkel44 72:3754b352f156 128 * Description:
jmarkel44 71:34856d21f2bf 129 *
jmarkel44 77:43e0a3d9e536 130 * @param controlFile -> name of output file
jmarkel44 71:34856d21f2bf 131 * @return none
jmarkel44 71:34856d21f2bf 132 *****************************************************************************/
jmarkel44 77:43e0a3d9e536 133 static int createOutput(const char *outputFile)
jmarkel44 66:db1425574b58 134 {
jmarkel44 66:db1425574b58 135 char dataBuf[1024];
jmarkel44 77:43e0a3d9e536 136 int status = GLOBAL_mdot->readUserFile(outputFile, (void *)dataBuf, sizeof(dataBuf));
jmarkel44 67:49f266601d83 137 if ( status != true ) {
jmarkel44 77:43e0a3d9e536 138 logError("%s failed to read %s", __func__, outputFile);
jmarkel44 66:db1425574b58 139 return -1;
jmarkel44 66:db1425574b58 140 }
jmarkel44 66:db1425574b58 141
jmarkel44 66:db1425574b58 142 MbedJSONValue json_value;
jmarkel44 66:db1425574b58 143 parse(json_value, dataBuf);
jmarkel44 66:db1425574b58 144
jmarkel44 66:db1425574b58 145 // extract the relay information
jmarkel44 66:db1425574b58 146 string id = json_value["id"].get<string>();
jmarkel44 66:db1425574b58 147
jmarkel44 77:43e0a3d9e536 148 // maps don't allow duplicates, and the vector is empty for now
jmarkel44 71:34856d21f2bf 149 vector<Control> v;
jmarkel44 71:34856d21f2bf 150 outputMap[id] = v;
jmarkel44 71:34856d21f2bf 151
jmarkel44 71:34856d21f2bf 152 return 0;
jmarkel44 71:34856d21f2bf 153 }
jmarkel44 71:34856d21f2bf 154
jmarkel44 71:34856d21f2bf 155
jmarkel44 71:34856d21f2bf 156 /*****************************************************************************
jmarkel44 72:3754b352f156 157 * Function: enableOutputReq
jmarkel44 71:34856d21f2bf 158 * Description: Display a list of outputs and its controls
jmarkel44 71:34856d21f2bf 159 *
jmarkel44 71:34856d21f2bf 160 * @param args -> not used
jmarkel44 71:34856d21f2bf 161 * @return none
jmarkel44 71:34856d21f2bf 162 *****************************************************************************/
jmarkel44 71:34856d21f2bf 163 static int enableOutputReq(const char *id, unsigned int priority, const char *output)
jmarkel44 71:34856d21f2bf 164 {
jmarkel44 71:34856d21f2bf 165 // attempt to find the output in the map
jmarkel44 71:34856d21f2bf 166 StringOutputVector_t::iterator pos;
jmarkel44 71:34856d21f2bf 167
jmarkel44 71:34856d21f2bf 168 pos = outputMap.find(output);
jmarkel44 71:34856d21f2bf 169 if ( pos == outputMap.end() ) {
jmarkel44 71:34856d21f2bf 170 printf("%s: failed to find the designated output %s\n",
jmarkel44 71:34856d21f2bf 171 __func__, output);
jmarkel44 71:34856d21f2bf 172 return -1;
jmarkel44 71:34856d21f2bf 173 }
jmarkel44 71:34856d21f2bf 174
jmarkel44 71:34856d21f2bf 175 if ( pos->second.empty() ) {
jmarkel44 71:34856d21f2bf 176 // this is a new request
jmarkel44 71:34856d21f2bf 177 string cid(id);
jmarkel44 71:34856d21f2bf 178 Control c(cid, priority, CONTROL_ON);
jmarkel44 71:34856d21f2bf 179 pos->second.push_back(c);
jmarkel44 71:34856d21f2bf 180 } else {
jmarkel44 71:34856d21f2bf 181 // find this control in the list
jmarkel44 71:34856d21f2bf 182 vector<Control>::iterator v;
jmarkel44 71:34856d21f2bf 183 for ( v = pos->second.begin(); v != pos->second.end(); ++v ) {
jmarkel44 71:34856d21f2bf 184 if ( strcmp(v->getId().c_str(), id) == 0 ) {
jmarkel44 71:34856d21f2bf 185 v->setState(CONTROL_ON);
jmarkel44 77:43e0a3d9e536 186 break;
jmarkel44 71:34856d21f2bf 187 }
jmarkel44 71:34856d21f2bf 188 }
jmarkel44 77:43e0a3d9e536 189 if ( v == pos->second.end() ) {
jmarkel44 77:43e0a3d9e536 190 // this is a new request, so add it and sort the vector
jmarkel44 77:43e0a3d9e536 191 string cid(id);
jmarkel44 77:43e0a3d9e536 192 Control c(cid, priority, CONTROL_ON);
jmarkel44 77:43e0a3d9e536 193 pos->second.push_back(c);
jmarkel44 77:43e0a3d9e536 194 std::sort(pos->second.begin(), pos->second.end());
jmarkel44 77:43e0a3d9e536 195 }
jmarkel44 71:34856d21f2bf 196 }
jmarkel44 71:34856d21f2bf 197
jmarkel44 71:34856d21f2bf 198 return 0;
jmarkel44 71:34856d21f2bf 199 }
jmarkel44 71:34856d21f2bf 200
jmarkel44 71:34856d21f2bf 201 /*****************************************************************************
jmarkel44 72:3754b352f156 202 * Function: disableOutputReq
jmarkel44 72:3754b352f156 203 * Description:
jmarkel44 71:34856d21f2bf 204 *
jmarkel44 71:34856d21f2bf 205 * @param args -> not used
jmarkel44 71:34856d21f2bf 206 * @return none
jmarkel44 71:34856d21f2bf 207 *****************************************************************************/
jmarkel44 71:34856d21f2bf 208 static int disableOutputReq(const char *id, unsigned int priority, const char *output)
jmarkel44 71:34856d21f2bf 209 {
jmarkel44 71:34856d21f2bf 210 // attempt to find the output in the map
jmarkel44 71:34856d21f2bf 211 StringOutputVector_t::iterator pos;
jmarkel44 71:34856d21f2bf 212
jmarkel44 71:34856d21f2bf 213 pos = outputMap.find(output);
jmarkel44 71:34856d21f2bf 214 if ( pos == outputMap.end() ) {
jmarkel44 71:34856d21f2bf 215 printf("%s: failed to find the designated output %s\n",
jmarkel44 71:34856d21f2bf 216 __func__, output);
jmarkel44 71:34856d21f2bf 217 return -1;
jmarkel44 71:34856d21f2bf 218 }
jmarkel44 71:34856d21f2bf 219
jmarkel44 80:b12b0adfcdc2 220 // if the control list is empty, push this control on the list
jmarkel44 71:34856d21f2bf 221 if ( pos->second.empty() ) {
jmarkel44 71:34856d21f2bf 222 string cid(id);
jmarkel44 71:34856d21f2bf 223 Control c(cid, priority, CONTROL_OFF);
jmarkel44 71:34856d21f2bf 224 pos->second.push_back(c);
jmarkel44 71:34856d21f2bf 225 } else {
jmarkel44 71:34856d21f2bf 226 // find this control in the list
jmarkel44 71:34856d21f2bf 227 vector<Control>::iterator v;
jmarkel44 71:34856d21f2bf 228 for ( v = pos->second.begin(); v != pos->second.end(); ++v ) {
jmarkel44 71:34856d21f2bf 229 if ( strcmp(v->getId().c_str(), id) == 0 ) {
jmarkel44 71:34856d21f2bf 230 v->setState(CONTROL_OFF);
jmarkel44 77:43e0a3d9e536 231 break;
jmarkel44 71:34856d21f2bf 232 }
jmarkel44 71:34856d21f2bf 233 }
jmarkel44 80:b12b0adfcdc2 234
jmarkel44 80:b12b0adfcdc2 235 if ( v == pos->second.end() ) {
jmarkel44 80:b12b0adfcdc2 236 // this is a new request, so add it and sort the vector
jmarkel44 80:b12b0adfcdc2 237 string cid(id);
jmarkel44 80:b12b0adfcdc2 238 Control c(cid, priority, CONTROL_OFF);
jmarkel44 80:b12b0adfcdc2 239 pos->second.push_back(c);
jmarkel44 80:b12b0adfcdc2 240 std::sort(pos->second.begin(), pos->second.end());
jmarkel44 80:b12b0adfcdc2 241 }
jmarkel44 71:34856d21f2bf 242 }
jmarkel44 66:db1425574b58 243
jmarkel44 66:db1425574b58 244 return 0;
jmarkel44 66:db1425574b58 245 }
jmarkel44 66:db1425574b58 246
jmarkel44 74:03ccf04998b5 247 /*****************************************************************************
jmarkel44 74:03ccf04998b5 248 * Function: unregisterControl
jmarkel44 74:03ccf04998b5 249 * Description:
jmarkel44 74:03ccf04998b5 250 *
jmarkel44 74:03ccf04998b5 251 * @param id -> control identifier
jmarkel44 74:03ccf04998b5 252 * @param pri -> priority
jmarkel44 74:03ccf04998b5 253 * @param output -> output (e.g. "o_rly5)
jmarkel44 74:03ccf04998b5 254 *
jmarkel44 74:03ccf04998b5 255 * @return 0 on success; -1 on error
jmarkel44 74:03ccf04998b5 256 *****************************************************************************/
jmarkel44 72:3754b352f156 257 static int unregisterControl(const char *id, unsigned int pri, const char *output)
jmarkel44 72:3754b352f156 258 {
jmarkel44 72:3754b352f156 259 // attempt to find the output in the map
jmarkel44 72:3754b352f156 260 StringOutputVector_t::iterator pos;
jmarkel44 80:b12b0adfcdc2 261 bool found = false;
jmarkel44 72:3754b352f156 262
jmarkel44 72:3754b352f156 263 pos = outputMap.find(output);
jmarkel44 72:3754b352f156 264 if ( pos == outputMap.end() ) {
jmarkel44 72:3754b352f156 265 printf("%s: failed to find the designated output %s\n",
jmarkel44 72:3754b352f156 266 __func__, output);
jmarkel44 72:3754b352f156 267 return -1;
jmarkel44 72:3754b352f156 268 }
jmarkel44 72:3754b352f156 269
jmarkel44 72:3754b352f156 270 // find the control in the list
jmarkel44 72:3754b352f156 271 vector<Control>::iterator v;
jmarkel44 72:3754b352f156 272 for ( v = pos->second.begin(); v != pos->second.end(); ++v) {
jmarkel44 72:3754b352f156 273 if ( strcmp(v->getId().c_str(), id) == 0 ) {
jmarkel44 72:3754b352f156 274 // delete this entry
jmarkel44 72:3754b352f156 275 pos->second.erase(v);
jmarkel44 80:b12b0adfcdc2 276 found = true;
jmarkel44 72:3754b352f156 277 break;
jmarkel44 72:3754b352f156 278 }
jmarkel44 74:03ccf04998b5 279 }
jmarkel44 80:b12b0adfcdc2 280 if ( !found ) {
jmarkel44 80:b12b0adfcdc2 281 logError("%s: failed to find control %s in list", __func__, id);
jmarkel44 80:b12b0adfcdc2 282 return -1;
jmarkel44 80:b12b0adfcdc2 283 }
jmarkel44 72:3754b352f156 284 return 0;
jmarkel44 72:3754b352f156 285 }
jmarkel44 72:3754b352f156 286
jmarkel44 72:3754b352f156 287 /*****************************************************************************
jmarkel44 72:3754b352f156 288 * Function: loadPersistentOutputs
jmarkel44 72:3754b352f156 289 * Description: pump up the output map based on persistent files
jmarkel44 72:3754b352f156 290 *
jmarkel44 72:3754b352f156 291 * @param args -> not used
jmarkel44 72:3754b352f156 292 * @return none
jmarkel44 72:3754b352f156 293 *****************************************************************************/
jmarkel44 66:db1425574b58 294 static void loadPersistentOutputs(void)
jmarkel44 66:db1425574b58 295 {
jmarkel44 66:db1425574b58 296 bool status;
jmarkel44 66:db1425574b58 297 MbedJSONValue json_value;
jmarkel44 71:34856d21f2bf 298
jmarkel44 77:43e0a3d9e536 299 printf("\rLoading persistent outputs:\n");
jmarkel44 66:db1425574b58 300
jmarkel44 66:db1425574b58 301 std::vector<mDot::mdot_file> file_list = GLOBAL_mdot->listUserFiles();
jmarkel44 70:7427f4959201 302
jmarkel44 66:db1425574b58 303 for (std::vector<mDot::mdot_file>::iterator i = file_list.begin(); i != file_list.end(); ++i) {
jmarkel44 67:49f266601d83 304 if( strncmp( i->name, OUTPUT_STR, strlen(OUTPUT_STR)) == 0 ) {
jmarkel44 66:db1425574b58 305
jmarkel44 66:db1425574b58 306 logInfo("%s: FOUND OUTPUT FILE: %s", __func__, i->name);
jmarkel44 66:db1425574b58 307
jmarkel44 66:db1425574b58 308 char scratchBuf[1024];
jmarkel44 66:db1425574b58 309
jmarkel44 66:db1425574b58 310 status = GLOBAL_mdot->readUserFile(i->name, scratchBuf, 1024);
jmarkel44 66:db1425574b58 311 if( status != true ) {
jmarkel44 66:db1425574b58 312 logInfo("(%d)read file failed, status=%d", __LINE__, status);
jmarkel44 66:db1425574b58 313 } else {
jmarkel44 66:db1425574b58 314 logInfo("(%d)Read File SUCCESS: %s", __LINE__, scratchBuf );
jmarkel44 66:db1425574b58 315 }
jmarkel44 66:db1425574b58 316
jmarkel44 66:db1425574b58 317 parse( json_value, scratchBuf );
jmarkel44 66:db1425574b58 318
jmarkel44 66:db1425574b58 319 string id = json_value["id"].get<string>();
jmarkel44 77:43e0a3d9e536 320 printf("\r output %s loaded\n", i->name);
jmarkel44 74:03ccf04998b5 321
jmarkel44 80:b12b0adfcdc2 322 // emplace the empty control vector into the output map
jmarkel44 71:34856d21f2bf 323 vector<Control> v;
jmarkel44 71:34856d21f2bf 324 outputMap[id] = v;
jmarkel44 66:db1425574b58 325 }
jmarkel44 66:db1425574b58 326 }
jmarkel44 70:7427f4959201 327 }