int S3Epoll::Start(){ struct epoll_event event; struct epoll_event *events; Init(); event.data.ptr = server.get(); event.events = EPOLLIN | EPOLLET; EpollAdd(server->GetDescriptor(), &event); events = static_cast<epoll_event*>(calloc(MAXEVENTS, sizeof(event))); while(1){ int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))){ /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ log << "epoll error" ; //XXX Need to free it? (static_cast<S3Socket*>(events[i].data.ptr))->Close(); continue; } else { S3Socket *sock = static_cast<S3Socket*>(events[i].data.ptr); sock->Process(); } } } return 0; }
void Epoll::Startup() { Netbase::Startup(); try { epoll_events = new struct epoll_event[nevents]; } catch(const std::bad_alloc &ex) { global_logger.WriteLog(Logger::ERROR, -1, "Epoll allocate space failed"); } EpollCreate(); if(!EpollAdd(socket_fd)) { global_logger.WriteLog(Logger::ERROR, -1, "Epoll add event of listen socket failed"); } }
bool CLoveTcp::CreateSocket() { if((m_nSocket = socket(AF_INET,SOCK_STREAM,0))==-1) { LogErrorMsg("create socket error"); return false; } if (setnonblocking(m_nSocket) == -1) { LogErrorMsg("setnonblocking error"); } int nSock = 0; if (setsockopt(m_nSocket,SOL_SOCKET,SO_REUSEADDR,&nSock,sizeof(nSock)) < 0) { /* code */ LogErrorMsg("setsockopt failed"); } m_nEpoll = epoll_create1(EPOLL_CLOEXEC); if (EpollAdd(m_nSocket) == false) { return false; }; return true; }
int main() { struct epoll_event ev, events[MAX_EVENTS]; struct sockaddr_in client; struct sockaddr_in server; // const char* localhost = "127.0.0.1"; const char* localhost = "0.0.0.0"; int tcpfd, udpfd, nfds, confd; int servPort = 8888; socklen_t addrLen = sizeof(struct sockaddr); char line[MAX_LINE]; ssize_t n; MYSQL connection; pthread_t thread; pthread_attr_t attr; //create socket tcpfd = CreateSocket(TCP); //translate ip & port into sockaddr_in format Ip2SocketAddr(&server, localhost, servPort); //bind ip & port to socket BindSocketAddr(&server, tcpfd); //begin to listen listen(tcpfd, LISTEN_NUM); //create epoll epfd = CreateEpoll(MAX_EVENTS); //set fd nonblocking mode SetNonBlock(tcpfd); //register fd event to epoll EpollAdd(epfd, tcpfd, EPOLLIN|EPOLLET); //create thread pool InitPool(MAX_POOL_SIZE); //init a connection to MySql conn = mysql_init(NULL); if(mysql_real_connect(conn, "localhost", "root", "", "test_server", 0, NULL, 0) == NULL){ perror("no database connection...\n"); exit(1); } while(1){ if((nfds = EpollWait(epfd, events, 20, 500)) == -1){ perror("epoll_wait\n"); exit(-1); } for(int i = 0; i < nfds; i++) { if(events[i].data.fd == tcpfd) { confd = accept(tcpfd, (struct sockaddr *)&client, &addrLen); if(confd < 0) { perror("accept error \n"); exit(1); } else printf("connect %s:%d socket :%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port), confd); // SetNonBlock(confd); EpollAdd(epfd, confd, EPOLLIN|EPOLLET); if(IsRecvIn(&events[i])) AddTask2Pool(MessageHandlerThread, (void *)&confd); } }//for(0 to nfds) } }
/** GPIO 초기화. * * @param bInitialize 초기화 여부 (다수의 Process에서 호출할 경우 최초 1회만 초기화 하면 된다) * @param nMobileType MOBILE_TYPE_CDMA, MOBILE_TYPE_GSM */ BOOL CGpioControl::Initialize(BOOL bInitialize, const char* pMobileType, BOOL bMonitoring) { if(pMobileType != NULL && strlen(pMobileType)>0) { m_pMobileType = (char*)MALLOC(strlen(pMobileType)+1); strcpy(m_pMobileType, pMobileType); } /** 초기화기 필요 없으면 바로 Return 한다 */ if(bInitialize == FALSE) return TRUE; #ifdef __TI_AM335X__ /** GPIO Epoll 추가 **/ m_nEpfd = epoll_create(INPUT_GPIO_MAX); /*---- INPUT ----*/ XDEBUG("** GPIO Initialize Start\r\n"); XDEBUG(" GP_GSM_SYNC_INPUT ................ %d\r\n", GP_GSM_SYNC_INPUT); gpio_export(GP_GSM_SYNC_INPUT); if(!gpio_dir_in(GP_GSM_SYNC_INPUT)) { if(bMonitoring) EpollAdd(GP_GSM_SYNC_INPUT, 1, GPIO_ON); // GPIO 번호, 초기값, GPIO State( gpio, ADC ) } XDEBUG(" GP_LOW_BATT_INPUT ................ %d\r\n", GP_LOW_BATT_INPUT); gpio_export(GP_LOW_BATT_INPUT); gpio_dir_in(GP_LOW_BATT_INPUT); if(bMonitoring) EpollAdd(GP_LOW_BATT_INPUT,1,GPIO_ON); XDEBUG(" GP_CASE_OPEN_INPUT ............... %d\r\n", GP_CASE_OPEN_INPUT); gpio_export(GP_CASE_OPEN_INPUT); gpio_dir_in(GP_CASE_OPEN_INPUT); if(bMonitoring) EpollAdd(GP_CASE_OPEN_INPUT,0,GPIO_ON); XDEBUG(" GP_PWR_FAIL_INPUT ................ %d\r\n", GP_PWR_FAIL_INPUT); gpio_export(GP_PWR_FAIL_INPUT); gpio_dir_in(GP_PWR_FAIL_INPUT); if(bMonitoring) EpollAdd(GP_PWR_FAIL_INPUT,0,GPIO_ON); XDEBUG(" GP_BATT_CHG_STATUS_INPUT ......... %d\r\n", GP_BATT_CHG_STATUS_INPUT); gpio_export(GP_BATT_CHG_STATUS_INPUT); gpio_dir_in(GP_BATT_CHG_STATUS_INPUT); if(bMonitoring) EpollAdd(GP_BATT_CHG_STATUS_INPUT,0,GPIO_ON); if(bMonitoring) EpollAdd(ADC_BATT_VOL_INPUT,4095,ADC_ON); // GPIO 번호, 초기값, GPIO State( gpio, ADC ) if(bMonitoring) EpollAdd(ADC_MAIN_VOL_INPUT,4040,ADC_ON); /*---- OUTPUT ----*/ #if 0 /** GPIO 중 SW Reset은 사용하지 않는다 */ XDEBUG(" GP_SW_RESET_OUT ....... HIGH ..... %d\r\n", GP_SW_RESET_OUT); gpio_export(GP_SW_RESET_OUT); gpio_dir_out(GP_SW_RESET_OUT , GPIO_DIR_OUT_HIGH); gpio_set_value(GP_SW_RESET_OUT , GPIO_HIGH ); #endif XDEBUG(" GP_STA_GREEN_OUT ...... LOW ..... %d\r\n", GP_STA_GREEN_OUT); gpio_export(GP_STA_GREEN_OUT); gpio_dir_out(GP_STA_GREEN_OUT , GPIO_DIR_OUT_LOW); //GPIO_DIR_OUT gpio_set_value(GP_STA_GREEN_OUT , GPIO_LOW ); XDEBUG(" GP_CODI_PCTL_OUT ...... HIGH ..... %d\r\n", GP_CODI_PCTL_OUT); gpio_export(GP_CODI_PCTL_OUT); gpio_dir_out(GP_CODI_PCTL_OUT , GPIO_DIR_OUT_HIGH); gpio_set_value(GP_CODI_PCTL_OUT , GPIO_HIGH ); XDEBUG(" GP_CODI_RST_OUT ....... HIGH ..... %d\r\n", GP_CODI_RST_OUT); gpio_export(GP_CODI_RST_OUT); gpio_dir_out(GP_CODI_RST_OUT , GPIO_DIR_OUT_HIGH); gpio_set_value(GP_CODI_RST_OUT , GPIO_HIGH ); XDEBUG(" GP_NPLC_PCTL_OUT ...... HIGH ..... %d\r\n", GP_NPLC_PCTL_OUT); gpio_export(GP_NPLC_PCTL_OUT); gpio_dir_out(GP_NPLC_PCTL_OUT , GPIO_DIR_OUT_HIGH); gpio_set_value(GP_NPLC_PCTL_OUT , GPIO_HIGH ); XDEBUG(" GP_NPLC_RST_OUT ....... HIGH ..... %d\r\n", GP_NPLC_RST_OUT); gpio_export(GP_NPLC_RST_OUT); gpio_dir_out(GP_NPLC_RST_OUT , GPIO_DIR_OUT_HIGH); gpio_set_value(GP_NPLC_RST_OUT , GPIO_HIGH ); /** Mobile Module Power Setting. * * AMTelecom Module의 경우 GSM_PCTL_OUT 일 Low로 설정하여 전원을 Off 시킨 후 * GSM_INIT_PCTL_OUT 값을 조정해 주어야 한다. */ gpio_export(GP_GSM_PCTL_OUT); XDEBUG(" GP_GSM_PCTL_OUT ....... HIGH ..... %d\r\n", GP_GSM_PCTL_OUT); gpio_dir_out(GP_GSM_PCTL_OUT , GPIO_DIR_OUT_HIGH); //GPIO_DIR_OUT gpio_set_value(GP_GSM_PCTL_OUT, GPIO_HIGH); XDEBUG(" GP_GSM_RST_OUT ........ LOW ..... %d\r\n", GP_GSM_RST_OUT); gpio_export(GP_GSM_RST_OUT); gpio_dir_out(GP_GSM_RST_OUT , GPIO_DIR_OUT_LOW); //GPIO_DIR_OUT gpio_set_value(GP_GSM_RST_OUT , GPIO_LOW ); gpio_export(GP_GSM_INIT_PCTL_OUT); if(m_pMobileType != NULL) { /** TI AM335x는 DTSS800, MC55 를 지원하지 않는다 */ if(!strcasecmp(MOBILE_MODULE_TYPE_AME5210, m_pMobileType)) { // AM Telecom XDEBUG(" GP_GSM_INIT_PCTL_OUT .. LOW ..... %d\r\n", GP_GSM_INIT_PCTL_OUT); gpio_dir_out(GP_GSM_INIT_PCTL_OUT , GPIO_DIR_OUT_LOW); //GPIO_DIR_OUT XDEBUG(" GP_GSM_PCTL_OUT ....... HIGH ..... %d\r\n", GP_GSM_PCTL_OUT); gpio_dir_out(GP_GSM_PCTL_OUT , GPIO_DIR_OUT_HIGH); //GPIO_DIR_OUT #if 0 gpio_set_value(GP_GSM_PCTL_OUT, GPIO_HIGH); #endif } else if(!strcasecmp(MOBILE_MODULE_TYPE_GE910, m_pMobileType) || !strcasecmp(MOBILE_MODULE_TYPE_UE910, m_pMobileType)) { XDEBUG(" GP_GSM_INIT_PCTL_OUT .. LOW ..... %d\r\n", GP_GSM_INIT_PCTL_OUT); gpio_dir_out(GP_GSM_INIT_PCTL_OUT , GPIO_DIR_OUT_LOW); //GPIO_DIR_OUT #if 0 XDEBUG(" GP_GSM_INIT_PCTL_OUT .. HIGH ..... %d\r\n", GP_GSM_INIT_PCTL_OUT); gpio_set_value(GP_GSM_INIT_PCTL_OUT, GPIO_HIGH); usleep(5000000); XDEBUG(" GP_GSM_INIT_PCTL_OUT .. LOW ..... %d\r\n", GP_GSM_INIT_PCTL_OUT); gpio_set_value(GP_GSM_INIT_PCTL_OUT, GPIO_LOW); #endif } } XDEBUG(" GP_RF_SIG_OUT ......... LOW ..... %d\r\n", GP_RF_SIG_OUT); gpio_export(GP_RF_SIG_OUT); gpio_dir_out(GP_RF_SIG_OUT , GPIO_DIR_OUT_LOW); // //GPIO_DIR_OUT gpio_set_value(GP_RF_SIG_OUT , GPIO_LOW ); XDEBUG(" GP_BATT_CHG_EN_OUT .... LOW ..... %d\r\n", GP_BATT_CHG_EN_OUT); gpio_export(GP_BATT_CHG_EN_OUT); gpio_dir_out(GP_BATT_CHG_EN_OUT , GPIO_DIR_OUT_LOW); //GPIO_DIR_OUT // Battery Charging Reset gpio_set_value(GP_BATT_CHG_EN_OUT , GPIO_HIGH ); USLEEP(500000); gpio_set_value(GP_BATT_CHG_EN_OUT , GPIO_LOW ); XDEBUG(" GP_BATT_SW_OUT ........ HIGH ..... %d\r\n", GP_BATT_SW_OUT); gpio_export(GP_BATT_SW_OUT); gpio_dir_out(GP_BATT_SW_OUT , GPIO_DIR_OUT_HIGH); // gpio_set_value(GP_BATT_SW_OUT , GPIO_HIGH ); XDEBUG(" GP_485_TX_EN_OUT ...... HIGH ..... %d\r\n", GP_485_TX_EN_OUT); gpio_export(GP_485_TX_EN_OUT); if(!gpio_dir_out(GP_485_TX_EN_OUT , GPIO_DIR_OUT_HIGH)) { gpio_set_value(GP_485_TX_EN_OUT , GPIO_HIGH ); } XDEBUG(" GP_DEBUG_LED1_OUT ..... LOW ..... %d\r\n", GP_DEBUG_LED1_OUT); gpio_export(GP_DEBUG_LED1_OUT); gpio_dir_out(GP_DEBUG_LED1_OUT , GPIO_DIR_OUT_LOW); // gpio_set_value(GP_DEBUG_LED1_OUT , GPIO_LOW ); XDEBUG(" GP_DEBUG_LED2_OUT ..... LOW ..... %d\r\n", GP_DEBUG_LED2_OUT); gpio_export(GP_DEBUG_LED2_OUT); gpio_dir_out(GP_DEBUG_LED2_OUT , GPIO_DIR_OUT_LOW); // gpio_set_value(GP_DEBUG_LED2_OUT , GPIO_LOW ); XDEBUG(" GP_DEBUG_LED3_OUT ..... LOW ..... %d\r\n", GP_DEBUG_LED3_OUT); gpio_export(GP_DEBUG_LED3_OUT); gpio_dir_out(GP_DEBUG_LED3_OUT , GPIO_DIR_OUT_LOW); // gpio_set_value(GP_DEBUG_LED3_OUT , GPIO_LOW ); XDEBUG("** GPIO Initialize End\r\n"); #else if (m_nFD != -1) return FALSE; m_nFD = open("/dev/gpio", O_RDWR | O_NDELAY); if (m_nFD < 0) { printf(" -------- GPIO Devive Open Fail -------\n"); m_nFD = -1; return FALSE; } // GPIO 입력 다이렉션 ioctl(m_nFD, GPIO_IOCTL_DIR, GP_PWR_FAIL_INPUT); // PWR FAIL ioctl(m_nFD, GPIO_IOCTL_DIR, GP_LOW_BATT_INPUT); // LOW BATTERY ioctl(m_nFD, GPIO_IOCTL_DIR, GP_GSM_DCD_INPUT); // MOBILE DCD ioctl(m_nFD, GPIO_IOCTL_DIR, GP_GSM_SYNC_INPUT); // MOBILE SYNC ioctl(m_nFD, GPIO_IOCTL_DIR, GP_GSM_RI_INPUT); // MOBILE RI ioctl(m_nFD, GPIO_IOCTL_DIR, GP_DOOR_OPEN_INPUT); // DOOR OPEN/CLOSE ioctl(m_nFD, GPIO_IOCTL_DIR, GP_TEMP_OS_INPUT); // HEATER ON/OFF ioctl(m_nFD, GPIO_IOCTL_DIR, GP_BATT_CHG_STATUS_INPUT); // BATT CHG STS // GPIO 포트 초기값 설정 ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_SW_RST_OUT)); // PWR RESET ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_CODI_RST_OUT)); // COORDINATOR RESET // GPIO Output Direction Setting ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_SW_RST_OUT)); // SW RESET ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_CODI_RST_OUT)); // COORDINATOR RESET ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_BATT_SW_OUT)); // PWR CTRL ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_BATT_CHG_EN_OUT)); // BATT CHG EN if(m_pMobileType != NULL) { /** PXA는 GE910, UE910 를 지원하지 않는다 */ if(!strcasecmp(MOBILE_MODULE_TYPE_DTSS800, m_pMobileType)) { ioctl(m_nFD, GPIO_IOCTL_DIR, GP_GSM_IGT_OUT); // MOBILE RESET (IGT) } else if(!strcasecmp(MOBILE_MODULE_TYPE_MC55, m_pMobileType)) { ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_GSM_EMERGOFF_OUT)); // EMERGENCY OFF ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_GSM_IGT_OUT)); // MOBILE RESET (IGT) } } ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_GSM_PCTL_OUT)); // MOBILE POWER ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_GSM_DTR_OUT)); // MOBILE DTR ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_LED_READY_OUT)); // LED READY ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_STA_GREEN_OUT)); // STATUS GREEN LED ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_STA_RED_OUT)); // STATUS RED LED ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_DEBUG_LED1_OUT)); // LED DEBUG1 ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_DEBUG_LED2_OUT)); // LED DEBUG2 ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_DEBUG_LED3_OUT)); // LED DEBUG3 ioctl(m_nFD, GPIO_IOCTL_DIR, GPIOSET(GP_DEBUG_LED4_OUT)); // LED DEBUG4 // 신규 보드는 HIGH, 영국, 스웨덴은 LOW, 구형은 HIGH #if defined(__SUPPORT_NZC1__) ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_BATT_SW_OUT)); // BATTERY ENABLE/DISABLE CONTROL #elif defined(__SUPPORT_NZC2__) ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_BATT_SW_OUT)); // BATTERY ENABLE/DISABLE CONTROL #else assert(0); #endif if(m_pMobileType != NULL && !strcasecmp(MOBILE_MODULE_TYPE_MC55, m_pMobileType)) { ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_GSM_EMERGOFF_OUT)); // GSM RESET ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_GSM_IGT_OUT)); // GSM IGT } ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_LED_READY_OUT)); // READY LED OFF ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_STA_GREEN_OUT)); // GREEN LED OFF ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_STA_RED_OUT)); // RED LED OFF XDEBUG("** Mobile Power OFF\xd\xa"); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_BATT_CHG_EN_OUT)); // BATT CHARGE DISABLE ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_GSM_PCTL_OUT)); // GSM Power Off usleep(1000000); XDEBUG("** Mobile Power ON\xd\xa"); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_BATT_CHG_EN_OUT)); // BATT CHARGE ENABLE ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_GSM_PCTL_OUT)); usleep(1000000); if(m_pMobileType != NULL && !strcasecmp(MOBILE_MODULE_TYPE_MC55, m_pMobileType)) { XDEBUG("** Mobile IGT or Reset\xd\xa"); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_GSM_IGT_OUT)); // IGT HIGH usleep(1000000); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_GSM_IGT_OUT)); // IGT LOW usleep(1000000); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_GSM_IGT_OUT)); // IGT HIGH } XDEBUG("** Mobile DTR Control\xd\xa"); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOHIGH(GP_GSM_DTR_OUT)); // DTR HIGH usleep(1000000); ioctl(m_nFD, GPIO_IOCTL_OUT, GPIOLOW(GP_GSM_DTR_OUT)); // DTR LOW #endif /** Monitoring이 필요 없으면 바로 Return 한다 */ if(bMonitoring == FALSE) return TRUE; // 상태 모니터링 쓰레드 생성 m_bExitPending = FALSE; if (pthread_create(&m_gpioThreadID, NULL, gpioWatchThread, (void *)this) != 0) return FALSE; pthread_detach(m_gpioThreadID); return TRUE; }