Junichi Katsu / Milkcocoa-os

Dependents:   mbed-os-example-wifi-milkcocoa MilkcocoaOsSample_Eth MilkcocoaOsSample_ESP8266 MilkcocoaOsSample_Eth_DigitalIn

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Milkcocoa.cpp Source File

Milkcocoa.cpp

00001 #include "Milkcocoa.h"
00002 #include "OldTimer.h"
00003 
00004 #if 0
00005 extern RawSerial pc;
00006 
00007 #define DBG(x)  x
00008 #else
00009 #define DBG(x)
00010 #endif
00011 
00012 DataElement::DataElement() {
00013     json_msg[0] = '\0';
00014     strcpy(json_msg,"{\"params\":{");
00015 }
00016 
00017 DataElement::DataElement(char *json_string) {
00018     json_msg[0] = '\0';
00019     strcpy(json_msg,json_string);
00020 }
00021 
00022 void DataElement::setValue(const char *key, const char *v) {
00023     char json_string[64];
00024     if( json_msg[strlen(json_msg)-1] != '{' )
00025     {
00026         strcat(json_msg,",");
00027     }
00028     sprintf(json_string,"\"%s\":\"%s\"",key,v);
00029     strcat(json_msg,json_string);
00030 }
00031 
00032 void DataElement::setValue(const char *key, int v) {
00033     char json_string[64];
00034     if( json_msg[strlen(json_msg)-1] != '{' )
00035     {
00036         strcat(json_msg,",");
00037     }
00038     sprintf(json_string,"\"%s\":\"%d\"",key,v);
00039     strcat(json_msg,json_string);
00040 }
00041 
00042 void DataElement::setValue(const char *key, double v) {
00043     char json_string[64];
00044     if( json_msg[strlen(json_msg)-1] != '{' )
00045     {
00046         strcat(json_msg,",");
00047     }
00048     sprintf(json_string,"\"%s\":\"%f\"",key,v);
00049     strcat(json_msg,json_string);
00050 }
00051 
00052 char *DataElement::getString(const char *key) {
00053     static char _word[64];
00054     char *p;
00055     int i=0;
00056     
00057     strcpy(_word , "\"\0");
00058     strcat(_word , key );
00059     strcat(_word , "\"" );
00060  
00061     p = strstr( (char*)json_msg , _word ) + 2 + strlen(_word);
00062     
00063     while( (p[i] != ',')&&(p[i] != '\n')&&(p[i] != '\"') )
00064     {
00065         _word[i] = p[i];
00066         i++;
00067     }
00068     _word[i] = '\0';
00069     
00070     return _word;
00071 }
00072 
00073 int DataElement::getInt(const char *key) {
00074     return atoi(getString(key));
00075 }
00076 
00077 float DataElement::getFloat(const char *key) {
00078     return atof(getString(key));
00079 }
00080 
00081 char *DataElement::toCharArray() {
00082     if( json_msg[strlen(json_msg)-1] != '{' )
00083     {
00084         strcat(json_msg,"}");
00085     }
00086     strcat(json_msg,"}");
00087     
00088     return(json_msg);
00089 }
00090 
00091 Milkcocoa::Milkcocoa(NetworkInterface* nif){
00092     ipstack = new MQTTInterface(nif);
00093     client = new MClient(ipstack);
00094     
00095     for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) {
00096         milkcocoaSubscribers[i] = NULL;
00097     }
00098 }
00099 
00100 Milkcocoa::Milkcocoa(NetworkInterface* nif, const char *host, uint16_t port, const char *_app_id, const char *client_id){
00101     ipstack = new MQTTInterface(nif);
00102     client = new MClient(ipstack);
00103     strcpy(servername,host);
00104     portnum = port;
00105     strcpy(app_id,_app_id);
00106     strcpy(_clientid,client_id);
00107     strcpy(username,"sdammy");
00108     strcpy(password,app_id);
00109     
00110     for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) {
00111         milkcocoaSubscribers[i] = NULL;
00112     }
00113     
00114 #ifdef __MILKCOCOA_THREAD
00115     setLoopCycle(5000);
00116     
00117     cycleThread1.start(Milkcocoa::threadStarter1,this);
00118     cycleThread2.start(Milkcocoa::threadStarter2,this);
00119 #endif
00120 }
00121 
00122 Milkcocoa::Milkcocoa(NetworkInterface* nif, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session){
00123     ipstack = new MQTTInterface(nif);
00124     client = new MClient(ipstack);
00125     strcpy(servername,host);
00126     portnum = port;
00127     strcpy(app_id,_app_id);
00128     strcpy(_clientid,client_id);
00129     strcpy(username,_session);
00130     strcpy(password,app_id);
00131     
00132     for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) {
00133         milkcocoaSubscribers[i] = NULL;
00134     }
00135     
00136 #ifdef __MILKCOCOA_THREAD
00137     setLoopCycle(5000);
00138     
00139     cycleThread1.start(Milkcocoa::threadStarter1,this);
00140     cycleThread2.start(Milkcocoa::threadStarter2,this);
00141 #endif
00142 }
00143 
00144 Milkcocoa* Milkcocoa::createWithApiKey(NetworkInterface* nif, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret) {
00145     char session[60];
00146     sprintf(session, "k%s:%s", key, secret);
00147     return new Milkcocoa(nif, host, port, _app_id, client_id, session);
00148 }
00149 
00150 void Milkcocoa::set_network_settinng(const char *host, uint16_t port, const char *_app_id, const char *client_id){
00151     strcpy(servername,host);
00152     portnum = port;
00153     strcpy(app_id,_app_id);
00154     strcpy(_clientid,client_id);
00155     strcpy(username,"sdammy");
00156     strcpy(password,app_id);
00157 }
00158 
00159 void Milkcocoa::connect() {
00160 
00161     if(client->isConnected())
00162         return;
00163 
00164     if(client->connect(servername, portnum)!=0) {
00165         DBG(pc.printf("Network connect err\r\n");)
00166         return;
00167     }
00168 
00169     MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
00170     data.keepAliveInterval = 20;
00171     data.cleansession = 1;
00172     data.MQTTVersion = 4;
00173     data.clientID.cstring = _clientid;
00174     data.username.cstring = username;
00175     data.password.cstring = password;
00176 
00177     if (client->connect(data) != 0)  {
00178         DBG(pc.printf("Milkcocoa connect err\r\n");)
00179         return;
00180     }
00181 
00182 }
00183 
00184 bool Milkcocoa::push(const char *path, DataElement dataelement) {
00185     milkcocoa_message_t *message = message_box.alloc();
00186     char *buf;
00187     
00188     if(message == NULL) return false;
00189 
00190     sprintf(message->topic, "%s/%s/push", app_id, path);
00191     buf = dataelement.toCharArray();
00192     strcpy(message->message , buf);
00193     
00194     osStatus stat = message_box.put(message);
00195     
00196     if( stat != osOK ) return false;
00197 
00198     return true;
00199 }
00200 
00201 bool Milkcocoa::push(const char *path, char *data) {
00202 
00203     milkcocoa_message_t *message = message_box.alloc();
00204     char *buf;
00205     
00206     if(message == NULL) return false;
00207 
00208     sprintf(message->topic, "%s/%s/push", app_id, path);
00209     
00210     strcpy(message->message , "{\"params\":");
00211     strcat(message->message , data);
00212     strcat(message->message , "}");
00213     
00214     osStatus stat = message_box.put(message);
00215     
00216     if( stat != osOK ) return false;
00217 
00218     return true;
00219 }
00220 
00221 bool Milkcocoa::send(const char *path, DataElement dataelement) {
00222     milkcocoa_message_t *message = message_box.alloc();
00223     char *buf;
00224     
00225     if(message == NULL) return false;
00226 
00227     sprintf(message->topic, "%s/%s/send", app_id, path);
00228     buf = dataelement.toCharArray();
00229     strcpy(message->message , buf);
00230     
00231     osStatus stat = message_box.put(message);
00232     
00233     if( stat != osOK ) return false;
00234 
00235     return true;
00236 }
00237 
00238 bool Milkcocoa::send(const char *path, char *data) {
00239     milkcocoa_message_t *message = message_box.alloc();
00240     char *buf;
00241     
00242     if(message == NULL) return false;
00243 
00244     sprintf(message->topic, "%s/%s/send", app_id, path);
00245     
00246     strcpy(message->message , "{\"params\":");
00247     strcat(message->message , data);
00248     strcat(message->message , "}");
00249     
00250     osStatus stat = message_box.put(message);
00251     
00252     if( stat != osOK ) return false;
00253 
00254     return true;
00255 }
00256 
00257 void Milkcocoa::loop() {
00258     connect();
00259 #ifndef __MILKCOCOA_THREAD
00260     send_massage();
00261 #endif
00262     client->yield(1);
00263 }
00264 
00265 void Milkcocoa::send_massage(){
00266     while(1){
00267         osEvent evt = message_box.get(0);
00268         if (evt.status == osEventMail) {
00269             milkcocoa_message_t *message = (milkcocoa_message_t*)evt.value.p;
00270             MQTT::Message mq_message;
00271             if(message != NULL) {
00272                 mq_message.qos = MQTT::QOS0;
00273                 mq_message.retained = 0;
00274                 mq_message.dup = false;
00275                 mq_message.payload = (void*)message->message;
00276                 mq_message.payloadlen = strlen(message->message);
00277                 printf("milkcocoa send\r\n");
00278                 client->publish(message->topic, mq_message);
00279                 
00280                 message_box.free(message);
00281             }
00282         }
00283         else{
00284             break;
00285         }
00286     }
00287 }
00288 
00289 bool Milkcocoa::on(const char *path, const char *event, GeneralFunction cb) {
00290     MilkcocoaSubscriber *sub = new MilkcocoaSubscriber(cb);
00291     sprintf(sub->topic, "%s/%s/%s", app_id, path, event);
00292 
00293     if (client->subscribe(sub->topic, MQTT::QOS0, cb) != 0)  {
00294         DBG(pc.printf("Milkcocoa subscribe err\r\n");)
00295         return false;
00296     }
00297     for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) {
00298         if (milkcocoaSubscribers[i] == sub) {
00299             return false;
00300         }
00301     }
00302     for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) {
00303         if (milkcocoaSubscribers[i] == 0) {
00304             milkcocoaSubscribers[i] = sub;
00305             return true;
00306         }
00307     }
00308     return true;
00309 }
00310 
00311 #ifdef __MILKCOCOA_THREAD
00312 void Milkcocoa::setLoopCycle(int cycle) {
00313     loop_cycle = cycle;
00314 }
00315 void Milkcocoa::start() {
00316     cycleThread1.signal_set(START_THREAD);
00317     cycleThread2.signal_set(START_THREAD);
00318 }
00319 
00320 void Milkcocoa::cycle_Thread1(void) {
00321     cycleThread1.signal_wait(START_THREAD);
00322     while(1) {
00323         OldTimer timer;
00324         timer.start();
00325         connect();
00326                 
00327         client->yield(RECV_TIMEOUT);
00328         
00329         int sub_time = loop_cycle - timer.read();
00330         if( sub_time > 0 ){
00331              Thread::wait(sub_time);
00332         }
00333         timer.stop();
00334     }
00335 }
00336 void Milkcocoa::cycle_Thread2(void) {
00337     cycleThread2.signal_wait(START_THREAD);
00338     while(1) {
00339 
00340         osEvent evt = message_box.get();
00341         if (evt.status == osEventMail) {
00342             milkcocoa_message_t *message = (milkcocoa_message_t*)evt.value.p;
00343             MQTT::Message mq_message;
00344             
00345             if(message == NULL) break;
00346             
00347             mq_message.qos = MQTT::QOS0;
00348             mq_message.retained = 0;
00349             mq_message.dup = false;
00350             mq_message.payload = (void*)message->message;
00351             mq_message.payloadlen = strlen(message->message);
00352         
00353             client->publish(message->topic, mq_message);
00354             
00355             message_box.free(message);
00356         }
00357         Thread::wait(1000);
00358     }
00359 }
00360 
00361 void Milkcocoa::threadStarter1(void const *p) {
00362   Milkcocoa *instance = (Milkcocoa*)p;
00363   instance->cycle_Thread1();
00364 }
00365 void Milkcocoa::threadStarter2(void const *p) {
00366   Milkcocoa *instance = (Milkcocoa*)p;
00367   instance->cycle_Thread2();
00368 }
00369 #endif
00370 
00371 MilkcocoaSubscriber::MilkcocoaSubscriber(GeneralFunction _cb) {
00372   cb = _cb;
00373 }
00374