/* * File Name: main.c * Workflow: prepare serial port, create MQ, SHM, child threads, * register SIGINT to shutdown demo, recycle IPC waste. * Return Value: 0, normal exit. -1, erroneous exit. */ /* Header files */ #include #include #include #include #include #include #include #include #include #include #include "debug.h" #include "proto.h" #include "uart_api.h" /* external threads */ extern void *pthread_gprs(void *args); extern void *pthread_fan(void *args); extern void *pthread_dht11(void *args); /* global variables*/ pthread_t id_dht11, id_fan, id_gprs; pthread_mutex_t mutex_zigbee_coordinator, mutex_gprs; volatile sig_atomic_t should_exit = 0; /* functions */ static void cleanThreadsHandler(int signum); /* main */ int main(void) { int *p_coordinator_fd = malloc(sizeof(int)); int retVal; int *p_gprs_fd = malloc(sizeof(int)); key_t *p_shm_key = malloc(sizeof(key_t)); key_t *p_msg_key = malloc(sizeof(key_t)); int *p_shm_id = malloc(sizeof(int)); int *p_msg_id = malloc(sizeof(int)); ARG_STRUCT *p_dht11_resource_struct = malloc(sizeof(ARG_STRUCT)); ARG_STRUCT *p_fan_resource_struct = malloc(sizeof(ARG_STRUCT)); ARG_STRUCT *p_gprs_resource_struct = malloc(sizeof(ARG_STRUCT)); // prepare serial communication if ((*p_coordinator_fd = open_port("/dev/ttyUSB0")) == -1) { fprintf(stderr, "[%s:%d] open_port: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Get zigbee coordinator fd: %d.\n", __FUNCTION__, __LINE__, *p_coordinator_fd); if ((retVal = set_comfig(*p_coordinator_fd, 115200)) != 0) { fprintf(stderr, "[%s:%d] set_comfig: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Set Zigbee coordinator serial config with " "return value: %d.\n", __FUNCTION__, __LINE__, retVal); if ((*p_gprs_fd = open_port("/dev/ttyUSB1")) == -1) { fprintf(stderr, "[%s:%d] open_port: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Get GPRS fd : %d.\n", __FUNCTION__, __LINE__, *p_gprs_fd); if ((retVal = set_comfig(*p_gprs_fd, 9600)) != 0) { fprintf(stderr, "[%s:%d] set_comfig: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog( "[DEBUG-INFO %s:%d]: Set GPRS serial config with return value: %d.\n", __FUNCTION__, __LINE__, retVal); // prepare IPC if ((*p_shm_key = ftok("/usr/bin/boa", 'm')) == -1) { fprintf(stderr, "[%s:%d] ftok: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Generate shared memory key : %d.\n", __FUNCTION__, __LINE__, *p_shm_key); if ((*p_msg_key = ftok("/usr/bin/boa", 'q')) == -1) { fprintf(stderr, "[%s:%d] ftok: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Generate message queue key: %d.\n", __FUNCTION__, __LINE__, *p_msg_key); if ((*p_shm_id = shmget(*p_shm_key, sizeof(SHM_STRUCT), IPC_CREAT | IPC_EXCL | 0600)) == -1) { fprintf(stderr, "[%s:%d] shmget: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Generate shared memory id: %d.\n", __FUNCTION__, __LINE__, *p_shm_id); if ((*p_msg_id = msgget(*p_msg_key, IPC_CREAT | IPC_EXCL | 0600)) == -1) { fprintf(stderr, "[%s:%d] msgget: %s", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Generate message queue id: %d.\n", __FUNCTION__, __LINE__, *p_msg_id); // register SIGINT to cleanThreadsHandler function struct sigaction sa_struct; sa_struct.sa_handler = cleanThreadsHandler; sa_struct.sa_flags = 0; // except SIGINT all signals are blocked sigfillset(&sa_struct.sa_mask); sigdelset(&sa_struct.sa_mask, SIGINT); if ((retVal = sigaction(SIGINT, &sa_struct, NULL)) == -1) { fprintf(stderr, "[%s:%d] sigaction: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: sigaction with return value: %d.\n", __FUNCTION__, __LINE__, retVal); // prepare mutex if ((retVal = pthread_mutex_init(&mutex_zigbee_coordinator, NULL)) != 0) { fprintf(stderr, "[%s:%d] pthread_mutex_init: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } if ((retVal = pthread_mutex_init(&mutex_gprs, NULL)) != 0) { fprintf(stderr, "[%s:%d] pthread_mutex_init: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } // create child threads memset(p_dht11_resource_struct, '\0', sizeof(ARG_STRUCT)); p_dht11_resource_struct->rw_fd = *p_coordinator_fd; DebugLog( "[DEBUG-INFO %s:%d]: Pass to child thread dht11 read/write fd: %d.\n", __FUNCTION__, __LINE__, p_dht11_resource_struct->rw_fd); p_dht11_resource_struct->shm_id = *p_shm_id; DebugLog( "[DEBUG-INFO %s:%d]: Pass to child thread dht11 shared memory id: %d.\n", __FUNCTION__, __LINE__, p_dht11_resource_struct->shm_id); if ((retVal = pthread_create(&id_dht11, NULL, pthread_dht11, p_dht11_resource_struct)) != 0) { fprintf(stderr, "[%s:%d] pthread_create: %s", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog("[DEBUG-INFO %s:%d]: Create child thread pthread_dht11 with return " "value: %d.\n", __FUNCTION__, __LINE__, retVal); memset(p_fan_resource_struct, '\0', sizeof(ARG_STRUCT)); p_fan_resource_struct->rw_fd = *p_coordinator_fd; DebugLog( "[DEBUG-INFO %s:%d]: Pass to child thread pthread_fan read/write fd: " "%d.\n", __FUNCTION__, __LINE__, p_fan_resource_struct->rw_fd); p_fan_resource_struct->mq_id = *p_msg_id; DebugLog( "[DEBUG-INFO %s:%d]: Pass to child thread pthread_fan message queue id: " "%d.\n", __FUNCTION__, __LINE__, p_fan_resource_struct->mq_id); if ((retVal = pthread_create(&id_fan, NULL, pthread_fan, p_fan_resource_struct)) != 0) { fprintf(stderr, "[%s:%d] pthread_create: %s", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog( "[DEBUG-INFO %s:%d]: Create child thread pthread_fan with return value: " "%d\n", __FUNCTION__, __LINE__, retVal); memset(p_gprs_resource_struct, '\0', sizeof(ARG_STRUCT)); p_gprs_resource_struct->rw_fd = *p_gprs_fd; DebugLog("[DEBUG-INFO %s:%d]: Pass to child thread gprs read/write fd: %d.\n", __FUNCTION__, __LINE__, p_gprs_resource_struct->rw_fd); p_gprs_resource_struct->mq_id = *p_msg_id; DebugLog( "[DEBUG-INFO %s:%d]: Pass to child thread gprs message queue id: %d.\n", __FUNCTION__, __LINE__, p_gprs_resource_struct->mq_id); if ((retVal = pthread_create(&id_gprs, NULL, pthread_gprs, p_gprs_resource_struct)) != 0) { fprintf(stderr, "[%s:%d] pthread_create: %s", __FUNCTION__, __LINE__, strerror(errno)); exit(-1); } DebugLog( "[DEBUG-INFO %s:%d]: Create child thread pthread_gprs with return value: " "%d.\n", __FUNCTION__, __LINE__, retVal); // wait for child thread return pthread_join(id_dht11, NULL); pthread_join(id_fan, NULL); pthread_join(id_gprs, NULL); // destory mutex pthread_mutex_destroy(&mutex_zigbee_coordinator); pthread_mutex_destroy(&mutex_gprs); // remove IPC shmctl(*p_shm_id, IPC_RMID, NULL); msgctl(*p_msg_id, IPC_RMID, NULL); // close file describer close(*p_coordinator_fd); close(*p_gprs_fd); // free memory free(p_coordinator_fd); free(p_gprs_fd); free(p_shm_key); free(p_msg_key); free(p_shm_id); free(p_msg_id); free(p_dht11_resource_struct); free(p_fan_resource_struct); free(p_gprs_resource_struct); return 0; } static void cleanThreadsHandler(int signum) { if (signum == SIGINT) { should_exit = 1; } }