int main() { signal(SIGINT, keyboard_interrupt); char name[BUFSIZ]; printf("Enter a name for controller: "); fgets(name, BUFSIZ, stdin); msgid = msgget((key_t)1236, 0666 | IPC_CREAT); if (msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } pid_t new_pid; new_pid = fork(); if(new_pid == 0){ //child long int msg_to_receive = 1; struct device *devices = (struct device *)malloc(4*sizeof(struct device)); int numberOfDevices = 0; struct device device; struct device ackMessage; //(struct device *)malloc(sizeof(struct device)); char temp[256]; //create msg queue while(1){ //printf("ID: %d\n", msgid); if(msgrcv(msgid, (void *)&device, BUFSIZ, msg_to_receive, 0) == -1) { fprintf(stderr, "msgrcv failed with error: %d\n", errno); exit(EXIT_FAILURE); } //is message a command from cloud if(device.device_info.command == 1){ strcpy(name,device.device_info.name); if(!strncmp(name,"put AC\0",6)){ int index = getDeviceByType(actuatorAC, numberOfDevices, devices); if(index != -1){ ackMessage.msg_type = (long int)devices[index].device_info.pid; ackMessage.device_info.state = 1; if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } } }else if(!strncmp(name,"put Dehumidifier\0",16)){ int index = getDeviceByType(actuatorDehumidifier, numberOfDevices, devices); if(index != -1){ ackMessage.msg_type = (long int)devices[index].device_info.pid; ackMessage.device_info.state = 1; if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } } }else if(!strncmp(name,"get Thermometer\0",15)){ int index = getDeviceByType(sensorThermometer, numberOfDevices, devices); if(index != -1){ signalParent(devices[index]); } }else if(!strncmp(name,"get Hygrometer\0",14)){ int index = getDeviceByType(sensorHygrometer, numberOfDevices, devices); if(index != -1){ signalParent(devices[index]); } } continue; } //check if device is known and add new devices to array int i; int contains = 0; //printf("number of devices: %d\n", numberOfDevices); for(i = 0; i < numberOfDevices; i ++){ //printf("array pid: %d\n",(long int)devices[i].device_info.pid); //printf("pid of messenger: %d\n",(long int)device.device_info.pid); if(devices[i].device_info.pid == device.device_info.pid){ contains = 1; devices[i].device_info.current_value = device.device_info.current_value; //printf("already know the device\n"); break; } } if(!contains){ devices[numberOfDevices] = device; numberOfDevices +=1; //printf("new device\n"); /* send ACK*/ //printf("prep set msg type\n"); ackMessage.msg_type = (long int)device.device_info.pid; //printf("set msg type\n"); if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } //printf("sent ack\n"); continue; } ////////////////////////////////////////////////////// if(device.device_info.device_type == sensorHygrometer || device.device_info.device_type == sensorThermometer){ //readings below thresh if(device.device_info.current_value <= device.device_info.threshold){ //printf("Sensor reading is ok, turning off actuator.\n"); if(device.device_info.device_type == sensorHygrometer){ //turn off dehumidifier for(i = 0; i < numberOfDevices; i ++){ if(devices[i].device_info.device_type == actuatorDehumidifier){ //if(!devices[i].device_info.state){ // break; //} //devices[i].device_info.state = 0; ackMessage.msg_type = (long int)devices[i].device_info.pid; ackMessage.device_info.state = 0; if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } printf("PID: %d -> Sensor reading acceptable, turning off dehumidifier.\n",(long int)device.device_info.pid); break; } } }else{ //turn off AC for(i = 0; i < numberOfDevices; i ++){ if(devices[i].device_info.device_type == actuatorAC){ //if(!devices[i].device_info.state){ // break; //} //devices[i].device_info.state = 0; ackMessage.msg_type = (long int)devices[i].device_info.pid; ackMessage.device_info.state = 0; if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } printf("PID: %d -> Sensor reading acceptable, turning off dehumidifier.\n",(long int)device.device_info.pid); break; } } } continue; //no problem } //reading above thresh signalParent(device); if(device.device_info.device_type == sensorHygrometer){ //turn on dehumidifier printf("PID: %d -> Threshold (%d) crossed, turning on Dehumidifier. Current: %d\n",(long int)device.device_info.pid,device.device_info.threshold,device.device_info.current_value); for(i = 0; i < numberOfDevices; i ++){ if(devices[i].device_info.device_type == actuatorDehumidifier){ ackMessage.msg_type = (long int)devices[i].device_info.pid; ackMessage.device_info.state = 1; if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } break; } } }else{ //turn on AC printf("PID: %d -> Threshold (%d) crossed, turning on Dehumidifier. Current: %d\n", (long int)device.device_info.pid, device.device_info.threshold, device.device_info.current_value); for(i = 0; i < numberOfDevices; i ++){ if(devices[i].device_info.device_type == actuatorAC){ ackMessage.msg_type = (long int)devices[i].device_info.pid; ackMessage.device_info.state = 1; if(msgsnd(msgid, (void *)&ackMessage, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } break; } } } } else if(device.device_info.device_type == actuatorAC || device.device_info.device_type == actuatorDehumidifier){ //printf("actuator ack message\n"); } else{ fprintf(stderr, "invalid device type\n"); } //int j; //for(j = 0; j < numberOfDevices; j++){ // printf("PID: %d\n",(long int)devices[j].device_info.pid); // printf("Name: %s\n", devices[j].device_info.name); //} //printf("Name: %s\n", devices[0].device_info.name); //printf("Type: %c\n", devices[0].device_info.device_type); /*int contains = 0; int i; for(i = 0; i < numberOfDevices; i++){ if(devices[i].device_info.pid == device.device_info.pid){ contains = 1; break; } }*/ } if(msgctl(msgid, IPC_RMID, 0) == -1){ fprintf(stderr, "msgctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } } else{ //parent //printf("%d\n", new_pid); struct cloud_data cloud_data; pthread_t tid; cloud_fifo_fd = open(SERVER_FIFO_NAME, O_WRONLY); if (cloud_fifo_fd == -1) { fprintf(stderr, "Sorry, no server\n"); exit(EXIT_FAILURE); } cloud_data.client_pid = getpid(); sprintf(parent_fifo, CLIENT_FIFO_NAME, cloud_data.client_pid); if (mkfifo(parent_fifo, 0777) == -1) { fprintf(stderr, "Sorry, can't make %s\n", parent_fifo); exit(EXIT_FAILURE); } parent_msg_to_receive = (long int)getpid(); //set up thread for forwarding commands from cloud to child if(pthread_create(&tid, NULL, &forwardMessageToChild, NULL) != 0){ printf("can't create thread\n"); exit(EXIT_FAILURE); } //printf("thread created\n"); //subscribe to signal and set (void) signal(SIGALRM, signalListener); while(1){ //printf("wait for signal\n"); pause(); //printf("got signal\n"); cloud_data.device = parentDevice; write(cloud_fifo_fd, &cloud_data, sizeof(cloud_data)); } } exit(EXIT_SUCCESS); /* Get name and threshold of device */ /*if (msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1) { fprintf(stderr, "msgrcv failed with error: %d\n", errno); exit(EXIT_FAILURE); } printf("%s: %d",some_data.info.threshold, some_data.info.name); exit(EXIT_SUCCESS); while(running) { printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); some_data.my_msg_type = 1; strcpy(some_data.some_text, buffer); if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } if (strncmp(buffer, "end", 3) == 0) { running = 0; } } exit(EXIT_SUCCESS);*/ }
void run(int argc, char *argv[]) { int i, j; int array[16]; switch (testID) { case 0: if (processID == 0) { restart(); childWait(); for (i=0; i<1024; i++); ag2(-1,1); agDone(); } else { ag2(-1,2); parentSignal(); exit(0); } break; case 1: if (processID == 0) { for (i=0; i<16; i++) { array[i] = restart(); childWait(); } for (i=0; i<16; i++) for (j=0; j<16; j++) assert(i==j || array[i]!=array[j]); agDone(); } else { parentSignal(); exit(0); } break; case 2: if (processID == 0) { restart(); restart(); childWait(); exit(0); } else if (processID == 1) { parentSignal(); for (i=0; i<1024; i++); parentSignal(); exit(0); } else { childWait(); for (i=0; i<1024; i++); agDone(); } break; case 3: if (processID == 0) { i = restart(); assert(join(i, &j) == 1); assert(j == agLoad(valRandom)); agDone(); } else { exit(agLoad(valRandom)); } break; case 4: assert(exec("abcdefghijklmnopqrstuvwxyz", 0, null) == -1); agDone(); break; case 5: switch (processID) { case 0: restart(); childWait(); assert(join(agLoad(valChildProcessID), &j) == 1); assert(j == 0); agDone(); break; case 1: restart(); agStore(valChildProcessID, restart()); parentSignal(); break; case 2: exit(0); break; case 3: exit(agLoad(valRandom)); break; } break; case 6: if (processID == 0) { array[0] = (int) "this"; array[1] = (int) "is-dumb"; assert(exec(shellProgramName, 2, (char**) array) != -1); exit(0); } else { assert(argc == 2 && strcmp(argv[0], "this")==0 && strcmp(argv[1], "is-dumb")==0); agDone(); } break; case 7: for (i=0; i<8; i++) array[i] = (int) big; assert(exec(shellProgramName, 8, (char**) array) == -1); break; case 11: /* make lots of child processes */ if (processID == 0) { for (i=0; i<20; i++) { restart(); waitChild(); } agDone(); } else { signalParent(); exit(0); } break; } agFail(); }