| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- // Copyright (c) 2020 Cesanta Software Limited
- // All rights reserved
- //
- // Example Websocket server. See https://mongoose.ws/tutorials/websocket-server/
- #include "mongoose.h"
- #include "datadef.h"
- #define PWR_TYPE PDU_AC_I3O3
- static const char *s_listen_on = "ws://localhost";
- static const char *s_web_root = ".";
- static void send_powerc(struct mg_connection* c);
- static int ws_send(struct mg_connection* c, int type, void *data, int len)
- {
- pkt_hdr_t* h = (pkt_hdr_t*)malloc(sizeof(pkt_hdr_t)+len);
- if (!h) {
- return -1;
- }
- h->magic = PKT_MAGIC;
- h->type = type;
- h->nack = 3;
- h->dlen = len;
- memcpy(h->data, data, len);
- mg_ws_send(c, (const void*)h, sizeof(pkt_hdr_t) + len, WEBSOCKET_OP_BINARY);
- free(h);
- return 0;
- }
- static void thrval_set(thr_val_t* tv)
- {
- tv->en = 0;
- tv->val = 100.0f;
- tv->act = 0;
- memset(tv->para, 0, 14);
- }
- static void thr_set(thr_t* thr)
- {
- thrval_set(&thr->v_upper);
- thrval_set(&thr->v_lower);
- thrval_set(&thr->c_upper);
- thrval_set(&thr->p_upper);
- thrval_set(&thr->w_upper);
- }
- static void alarm_set(alarm_t* a)
- {
- a->v_upper = 1;
- a->v_lower = 0;
- a->c_upper = 0;
- a->p_upper = 0;
- a->w_upper = 0;
- }
- static float rand_float(float min, float max) {
- return ((float)rand() / (float)RAND_MAX) * (max - min) + min;
- }
- static void powert_rand(power_total_t* pt)
- {
- int i, cnt = 1;
- if (pt->type >= PDU_AC_I3O3) {
- cnt = 3;
- }
- for (i = 0; i < cnt; i++) {
- pt->total[i].voltage = rand_float(1.0f, 100.0f);
- pt->total[i].current = rand_float(1.0f, 100.0f);
- pt->total[i].freq = rand_float(1.0f, 100.0f);
- pt->total[i].power = rand_float(1.0f, 100.0f);
- pt->total[i].consump = rand_float(1.0f, 100.0f);
- pt->total[i].active = rand_float(1.0f, 100.0f);
- pt->total[i].reactive = rand_float(1.0f, 100.0f);
- }
- }
- static void powerc_rand(power_ch_t* pc, uint8_t addr, uint8_t ch, uint8_t sch)
- {
- int i, cnt = 1;
- pc->info.type = PWR_TYPE;
- pc->info.addr = addr;
- pc->info.ch = ch;
- pc->info.sch = sch;
- pc->info.ph_id = 0;
- pc->info.start_delay = 0;
- pc->info.stop_delay = 0;
- thr_set(&pc->thr);
- alarm_set(&pc->alarm);
- if (pc->info.type >= PDU_AC_I3O3) {
- cnt = 3;
- }
- for (i = 0; i < cnt; i++) {
- pc->power[i].voltage = rand_float(100.0f, 400.0f);
- pc->power[i].current = rand_float(1.0f, 100.0f);
- pc->power[i].freq = 50.0f;
- pc->power[i].power = rand_float(1.0f, 100.0f);
- pc->power[i].consump = rand_float(1.0f, 100.0f);
- pc->power[i].factor = rand_float(0.0f, 1.0f);
- pc->power[i].status = 1;
- pc->power[i].nwire = 0;
- }
- pc->time = 0;
- }
- typedef struct {
- uint8_t chs;
- power_ch_t pch[CH_MAX];
- }powerc_data_t;
- static powerc_data_t powerc_data = {.chs=0};
- static void send_powerc(struct mg_connection* c)
- {
- int i, j, ch = 0;
- #define BOARD_CNT 2
- #define BOARC_CH_CNT 2
- //uint8_t addr[BOARD_CNT] = {2,4,6,7,8};
- uint8_t addr[BOARD_CNT] = { 2,4 };
- powerc_data_t* pc = &powerc_data;
- pc->chs = BOARD_CNT * BOARC_CH_CNT;
- for (i = 0; i < BOARD_CNT; i++) {
- for (j = 0; j < BOARC_CH_CNT; j++) {
- powerc_rand(&pc->pch[ch], addr[i], ch, j);
- ch++;
- }
- }
- ws_send(c, PKT_TYPE_POWER_CH, pc->pch, sizeof(power_ch_t)*pc->chs);
- }
- static void send_powert(struct mg_connection* c)
- {
- power_total_t pt;
- powert_rand(&pt);
- ws_send(c, PKT_TYPE_POWER_TOTAL, &pt, sizeof(pt));
- }
- static void send_alarm(struct mg_connection* c)
- {
- alarm_data_t a;
- a.ch = 0;
- a.alarm.v_upper = 1;
- a.alarm.v_lower = 0;
- a.alarm.c_upper = 0;
- a.alarm.p_upper = 0;
- a.alarm.w_upper = 0;
- a.time = 0;
- ws_send(c, PKT_TYPE_ALARM, &a, sizeof(a));
- }
- static int ws_handle(pkt_hdr_t* hdr, struct mg_connection* c)
- {
- int r = 0;
- if (!c->is_websocket) {
- printf("___ not a websocket\n");
- return -1;
- }
- if (hdr->magic != PKT_MAGIC) {
- printf("___ magic: 0x%x is wrong!, correct is: 0x%x\n", hdr->magic, PKT_MAGIC);
- return -1;
- }
- printf("_____ ws handle, type:%d, subtype:%d, flag:%d\n", hdr->type, hdr->subtype, hdr->flag);
- switch (hdr->type) {
- case PKT_TYPE_PARAS:
- {
- //setup
- }
- break;
- case PKT_TYPE_POWER_CH:
- {
- printf("_____ send_powerc\n");
- send_powerc(c);
- }
- break;
- case PKT_TYPE_POWER_TOTAL:
- {
- printf("_____ send_powert\n");
- send_powert(c);
- }
- break;
- case PKT_TYPE_CH_ALL:
- {
-
- }
- break;
- }
- return 0;
- }
- // This RESTful server implements the following endpoints:
- // /websocket - upgrade to Websocket, and implement websocket echo server
- // /rest - respond with JSON string {"result": 123}
- // any other URI serves static files from s_web_root
- static void fn(struct mg_connection *c, int ev, void *ev_data) {
- if (ev == MG_EV_WS_OPEN) {
-
- } else if (ev == MG_EV_HTTP_MSG) {
- struct mg_http_message *hm = (struct mg_http_message *) ev_data;
- if (mg_match(hm->uri, mg_str("/ws"), NULL)) {
- // Upgrade to websocket. From now on, a connection is a full-duplex
- // Websocket connection, which will receive MG_EV_WS_MSG events.
- mg_ws_upgrade(c, hm, NULL);
- } else if (mg_match(hm->uri, mg_str("/rest"), NULL)) {
- // Serve REST response
- mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
- } else {
- // Serve static files
- struct mg_http_serve_opts opts = {.root_dir = s_web_root};
- mg_http_serve_dir(c, (struct mg_http_message*)ev_data, &opts);
- }
- } else if (ev == MG_EV_WS_MSG) {
- // Got websocket frame. Received data is wm->data. Echo it back!
- struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
- pkt_hdr_t *hdr= (pkt_hdr_t*)wm->data.buf;
- ws_handle(hdr, c);
- //mg_ws_send(c, wm->data.buf, wm->data.len, WEBSOCKET_OP_TEXT);
- }
- }
- static void timer_fn(void* arg)
- {
- static uint32_t cnt = 0;
- struct mg_mgr* mgr = (struct mg_mgr*)arg;
- struct mg_connection* c;
- cnt++;
- if (cnt%10==0) {
- for (c = mgr->conns; c != NULL; c = c->next) {
- send_alarm(c);
- }
- }
- }
- int main(void) {
- struct mg_mgr mgr; // Event manager
- srand((uint32_t)time(NULL));
- mg_mgr_init(&mgr); // Initialise event manager
- printf("ws server on %s/ws\n", s_listen_on);
- mg_timer_add(&mgr, 1000, MG_TIMER_REPEAT, timer_fn, &mgr);
- mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
- for (;;) mg_mgr_poll(&mgr, 200); // Infinite event loop
- mg_mgr_free(&mgr);
- return 0;
- }
|