void printMyIp(net_if_t *net_if) { char buffer[16]; struct sockaddr_in myaddr; getMyAddress(net_if, &myaddr); udpc_flprintf("%s", udpc_getIpString(&myaddr,buffer)); }
int setMcastDestination(int sock, net_if_t *net_if, struct sockaddr_in *addr) { #ifdef WINDOWS int r; struct sockaddr_in interface_addr; struct in_addr if_addr; getMyAddress(net_if, &interface_addr); if_addr = getSinAddr(&interface_addr); r = setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (char *) &if_addr, sizeof(if_addr)); if(r < 0) fatal(1, "Set multicast send interface"); return 0; #else /* IP_MULTICAST_IF not correctly supported on Cygwin */ return mcastOp(sock, net_if, getSinAddr(addr), IP_MULTICAST_IF, "Set multicast send interface"); #endif }
void GreenHouseMiddleLayer::decodeMessage(Message& msg) { Serial.print(msg.source); if (CommonValues::emptyMessage == msg.messageType) { //do nothing the message is empty return; } DateTime dateTime; clock.createDateTime(dateTime); msg.dateTime = dateTime; //add time to message if (msg.dest != CommonValues::middleLayerAddress) { //check if the message is for me sendMessage(msg); // if so, pass it on return; } //the message is from higer layer if (msg.source >= CommonValues::highLayerMinAddress && msg.source < CommonValues::highLayerMaxAddress) { switch (msg.messageType) { case CommonValues::policyChange: switch (msg.sensorType) { case CommonValues::soilHumidityType: //if it's soil Humidity policy changes, send it to the lower layers for (int i = 0; i<lowersIds.size() ; ++i) { if (lowersIds.get(i) != CommonValues::lowerLayerConsumptionAdress) { prepareMessage(msg, lowersIds.get(i)); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } } } break; case CommonValues::temperatureType: CommonValues::temperatureThresholdMin = msg.data; CommonValues::temperatureThresholdMax = msg.additionalData; break; case CommonValues::humidityType: CommonValues::airHumidityThresholdMin = msg.data; CommonValues::airHumidityThresholdMax = msg.additionalData; break; case CommonValues::lightType: CommonValues::lightThresholdMin = msg.data; CommonValues::lightThresholdMax = msg.additionalData; break; } case CommonValues::loopTimeChange: break; case CommonValues::myAddressChange: break; case CommonValues::yourAddressChange: break; case CommonValues::ACTION_TYPE: switch (msg.action) { case PUMP1: prepareMessage(msg, lowersIds.get(0)); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case PUMP2: prepareMessage(msg, lowersIds.get(1)); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case FAN: msg.messageType = CommonValues::dataType; msg.action = actuate(CommonValues::fanPin,msg.data); prepareMessage(msg, CommonValues::highLayerAddress); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case LIGHT: msg.messageType = CommonValues::dataType; msg.action = actuate(CommonValues::lampPin, msg.data); prepareMessage(msg, CommonValues::highLayerAddress); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case HEATER: msg.messageType = CommonValues::dataType; msg.action = actuate(CommonValues::heatPin,msg.data); prepareMessage(msg, CommonValues::highLayerAddress); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case VENT: msg.messageType = CommonValues::dataType; msg.action = actuate(CommonValues::ventPin,msg.data); prepareMessage(msg, CommonValues::highLayerAddress); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case STEAMER: msg.messageType = CommonValues::dataType; msg.action = actuate(CommonValues::steamPin,msg.data); prepareMessage(msg, CommonValues::highLayerAddress); if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case NONE: //TODO break; default: //TODO break; } break; case CommonValues::arduinoMalfunction: break; } } //if the meesgae came from bottom layer //the layer should act/send up the hirarchy if needed else if (msg.source >= CommonValues::lowerLayerMinAddress && msg.source < CommonValues::lowerLayerMaxAddress) { switch (msg.messageType) { //first check if it's an emergency message case CommonValues::emergencyType: actuate(CommonValues::fanPin, true); actuate(CommonValues::ventPin, true); prepareMessage(msg, CommonValues::highLayerAddress); // prepare to send to high if (!sendMessage(msg)) { //unsentImportantMessages.add(msg); } break; case CommonValues::dataType: switch (msg.sensorType) { case CommonValues::soilHumidityType: //if it's soil Humidity data, send it to the high layer msg.additionalData = getMyAddress(); // the higher needs to know which pot it is. msg.dest = CommonValues::highLayerAddress; //check if the message is important (action performed),and add to unsentImportantMessages if not sent if (NONE != msg.action) { if (!sendMessage(msg)) { // unsentImportantMessages.add(msg); } } else sendMessage(msg); break; case CommonValues::currentType: //if it's current consumption data, send it to the high layer prepareMessage(msg, CommonValues::highLayerAddress); // prepare to send to high sendMessage(msg); break; case CommonValues::waterType: //if it's water consumption data, send it to the high layer prepareMessage(msg, CommonValues::highLayerAddress); sendMessage(msg); break; case CommonValues::temperatureType: isTemperatureReadyToAnalyze = ((updateDataAndCheckIfFull(temperatureData,msg,plantsLowerLayers)) && isTimeConsistency(temperatureData, CommonValues::minutesInInterval)); break; case CommonValues::humidityType: isHumidityReadyToAnalyze = ((updateDataAndCheckIfFull(humidityData,msg, plantsLowerLayers)) && isTimeConsistency(humidityData, CommonValues::minutesInInterval)); break; case CommonValues::lightType: isLightReadyToAnalyze = ((updateDataAndCheckIfFull(lightData,msg, plantsLowerLayers)) && isTimeConsistency(lightData, CommonValues::minutesInInterval)); break; } break; //TODO think maybe handle with more messageTypes //TODO action type //TODO what happens if we are not erady to analyze?? }//end of switch (msg.messageType) analyze(); }//end of if (msg.source >= CommonValues::lowerLayerMinAddress && msg.source < CommonValues::lowerLayerMaxAddress) }
void getDefaultMcastAddress(net_if_t *net_if, struct sockaddr_in *mcast) { getMyAddress(net_if, mcast); mcast->sin_addr.s_addr &= htonl(0x07ffffff); mcast->sin_addr.s_addr |= htonl(0xe8000000); }
int startReceiver(int doWarn, struct disk_config *disk_config, struct net_config *net_config, struct stat_config *stat_config, const char *ifName) { char ipBuffer[16]; union serverControlMsg Msg; int connectReqSent=0; struct client_config client_config; int outFile=1; int pipedOutFile; struct sockaddr_in myIp; int pipePid = 0; int origOutFile; int haveServerAddress; client_config.sender_is_newgen = 0; net_config->net_if = getNetIf(ifName); zeroSockArray(client_config.socks, NR_CLIENT_SOCKS); client_config.S_UCAST = makeSocket(ADDR_TYPE_UCAST, net_config->net_if, 0, RECEIVER_PORT(net_config->portBase)); client_config.S_BCAST = makeSocket(ADDR_TYPE_BCAST, net_config->net_if, 0, RECEIVER_PORT(net_config->portBase)); if(net_config->ttl == 1 && net_config->mcastRdv == NULL) { getBroadCastAddress(net_config->net_if, &net_config->controlMcastAddr, SENDER_PORT(net_config->portBase)); setSocketToBroadcast(client_config.S_UCAST); } else { getMcastAllAddress(&net_config->controlMcastAddr, net_config->mcastRdv, SENDER_PORT(net_config->portBase)); if(isMcastAddress(&net_config->controlMcastAddr)) { setMcastDestination(client_config.S_UCAST, net_config->net_if, &net_config->controlMcastAddr); setTtl(client_config.S_UCAST, net_config->ttl); client_config.S_MCAST_CTRL = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->controlMcastAddr, RECEIVER_PORT(net_config->portBase)); // TODO: subscribe address as receiver to! } } clearIp(&net_config->dataMcastAddr); udpc_flprintf("%sUDP receiver for %s at ", disk_config->pipeName == NULL ? "" : "Compressed ", disk_config->fileName == NULL ? "(stdout)":disk_config->fileName); printMyIp(net_config->net_if); udpc_flprintf(" on %s\n", net_config->net_if->name); connectReqSent = 0; haveServerAddress = 0; client_config.clientNumber= 0; /*default number for asynchronous transfer*/ while(1) { // int len; int msglen; int sock; if (!connectReqSent) { if (sendConnectReq(&client_config, net_config, haveServerAddress) < 0) { perror("sendto to locate server"); } connectReqSent = 1; } haveServerAddress=0; sock = udpc_selectSock(client_config.socks, NR_CLIENT_SOCKS, net_config->startTimeout); if(sock < 0) { return -1; } // len = sizeof(server); msglen=RECV(sock, Msg, client_config.serverAddr, net_config->portBase); if (msglen < 0) { perror("recvfrom to locate server"); exit(1); } if(getPort(&client_config.serverAddr) != SENDER_PORT(net_config->portBase)) /* not from the right port */ continue; switch(ntohs(Msg.opCode)) { case CMD_CONNECT_REPLY: client_config.clientNumber = ntohl(Msg.connectReply.clNr); net_config->blockSize = ntohl(Msg.connectReply.blockSize); udpc_flprintf("received message, cap=%08lx\n", (long) ntohl(Msg.connectReply.capabilities)); if(ntohl(Msg.connectReply.capabilities) & CAP_NEW_GEN) { client_config.sender_is_newgen = 1; copyFromMessage(&net_config->dataMcastAddr, Msg.connectReply.mcastAddr); } if (client_config.clientNumber == -1) { udpc_fatal(1, "Too many clients already connected\n"); } goto break_loop; case CMD_HELLO_STREAMING: case CMD_HELLO_NEW: case CMD_HELLO: connectReqSent = 0; if(ntohs(Msg.opCode) == CMD_HELLO_STREAMING) net_config->flags |= FLAG_STREAMING; if(ntohl(Msg.hello.capabilities) & CAP_NEW_GEN) { client_config.sender_is_newgen = 1; copyFromMessage(&net_config->dataMcastAddr, Msg.hello.mcastAddr); net_config->blockSize = ntohs(Msg.hello.blockSize); if(ntohl(Msg.hello.capabilities) & CAP_ASYNC) net_config->flags |= FLAG_PASSIVE; if(net_config->flags & FLAG_PASSIVE) goto break_loop; } haveServerAddress=1; continue; case CMD_CONNECT_REQ: case CMD_DATA: case CMD_FEC: continue; default: break; } udpc_fatal(1, "Bad server reply %04x. Other transfer in progress?\n", (unsigned short) ntohs(Msg.opCode)); } break_loop: udpc_flprintf("Connected as #%d to %s\n", client_config.clientNumber, getIpString(&client_config.serverAddr, ipBuffer)); getMyAddress(net_config->net_if, &myIp); if(!ipIsZero(&net_config->dataMcastAddr) && !ipIsEqual(&net_config->dataMcastAddr, &myIp) && (ipIsZero(&net_config->controlMcastAddr) || !ipIsEqual(&net_config->dataMcastAddr, &net_config->controlMcastAddr) )) { udpc_flprintf("Listening to multicast on %s\n", getIpString(&net_config->dataMcastAddr, ipBuffer)); client_config.S_MCAST_DATA = makeSocket(ADDR_TYPE_MCAST, net_config->net_if, &net_config->dataMcastAddr, RECEIVER_PORT(net_config->portBase)); } if(net_config->requestedBufSize) { int i; for(i=0; i<NR_CLIENT_SOCKS; i++) if(client_config.socks[i] != -1) setRcvBuf(client_config.socks[i],net_config->requestedBufSize); } outFile=openOutFile(disk_config); origOutFile = outFile; pipedOutFile = openPipe(outFile, disk_config, &pipePid); global_client_config= &client_config; atexit(sendDisconnectWrapper); { struct fifo fifo; int printUncompressedPos = udpc_shouldPrintUncompressedPos(stat_config->printUncompressedPos, origOutFile, pipedOutFile); receiver_stats_t stats = allocReadStats(origOutFile, stat_config->statPeriod, printUncompressedPos); udpc_initFifo(&fifo, net_config->blockSize); fifo.data = pc_makeProduconsum(fifo.dataBufSize, "receive"); client_config.isStarted = 0; if((net_config->flags & (FLAG_PASSIVE|FLAG_NOKBD))) { /* No console used */ client_config.console = NULL; } else { if(doWarn) udpc_flprintf("WARNING: This will overwrite the hard disk of this machine\n"); client_config.console = prepareConsole(0); atexit(fixConsole); } spawnNetReceiver(&fifo,&client_config, net_config, stats); writer(&fifo, pipedOutFile); if(pipePid) { close(pipedOutFile); } pthread_join(client_config.thread, NULL); /* if we have a pipe, now wait for that too */ if(pipePid) { udpc_waitForProcess(pipePid, "Pipe"); } #ifndef __MINGW32__ fsync(origOutFile); #endif /* __MINGW32__ */ displayReceiverStats(stats, 1); } fixConsole(); sendDisconnectWrapper(); global_client_config= NULL; return 0; }