error_t timer_start (timer_handle_t _handle, msecond_t _duration, expiry_callback_t _cb, void *_arg) { interrupt_level_t level; if (null == _cb) { return ERROR_T (ERROR_TIMER_ALLOC_INVCB); } level = global_interrupt_disable (); if (is_invalid_handle (_handle)) { global_interrupt_enable (level); return ERROR_T (ERROR_TIMER_START_INVHANDLE); } if (TIMER_STARTED == _handle->state_) { g_statistics.abnormal_ ++; global_interrupt_enable (level); return ERROR_T (ERROR_TIMER_START_INVSTATE); } _handle->ticks_ = _duration / CONFIG_TICK_DURATION_IN_MSEC; if (0 == _handle->ticks_) { _handle->ticks_ ++; } _handle->callback_ = _cb; _handle->arg_ = _arg; global_interrupt_enable (level); timer_insert (_handle); return 0; }
/** * @brief Ethernet end of transmission function * * This function is issued when all of the main memory output buffer * has been transferred to the FIFO. EEFCT disables further data * wakeups. */ static void f2_eefct_1(void) { /* start transmitting the packet */ PUT_ETH_OBUSY(eth.status, 1); PUT_ETH_OEOT(eth.status, 1); if (0 == eth.tx_id) eth.tx_id = timer_insert(TIME_US(5.44), tx_packet, 0, "tx packet"); eth_wakeup(); }
int do_init(int argc, char **argv) { int i; char *CONF_FILE = "conf/login.conf"; char *LANG_FILE = "conf/lang.conf"; char *INTER_FILE = "conf/inter.conf"; srand(gettick()); set_logfile("log/login.log"); set_dmpfile("log/login_dump.log"); for (i = 1; i < argc ; i++) { if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--h") == 0 || strcmp(argv[i], "--?") == 0 || strcmp(argv[i], "/?") == 0) help_screen(); else if (strcmp(argv[i], "--conf") == 0) CONF_FILE=argv[i+1]; else if (strcmp(argv[i],"--inter") == 0) INTER_FILE = argv[i+1]; else if (strcmp(argv[i],"--lang") == 0) LANG_FILE = argv[i+1]; } config_read(CONF_FILE); config_read(INTER_FILE); config_read("conf/char.conf"); sql_handle = Sql_Malloc(); if(sql_handle==NULL) { Sql_ShowDebug(sql_handle); exit(EXIT_FAILURE); } if( SQL_ERROR == Sql_Connect(sql_handle, sql_id, sql_pw, sql_ip, (uint16)sql_port, sql_db) ) { printf("id: %s pass: %s Port: %d\n",sql_id, sql_pw,sql_port); Sql_ShowDebug(sql_handle); Sql_Free(sql_handle); exit(EXIT_FAILURE); } //sql_init(); lang_read(LANG_FILE); set_termfunc(do_term); //zlib_init(); add_log(""); add_log("mYnexia Login Server Started.\n"); set_defaultaccept(clif_accept); set_defaultparse(clif_parse); login_fd = make_listen_port(login_port); timer_insert(10 * 60 * 1000, 10 * 60 * 1000, Remove_Throttle, 0, 0); //Lockout DB bf_lockout=uidb_alloc(DB_OPT_BASE); printf("mYnexia Login Server is \033[1;32mready\033[0m! Listening at %d.\n", login_port); add_log("Server Ready! Listening at %d.\n", login_port); return 0; }
/** * @brief HACK: pull the next word from the duckbreath in the fifo * * This is probably lacking the updates to one or more of * the status flip flops. */ static void rx_duckbreath(int id, int arg) { uint32_t data; if (arg == 0) { /* first word: set the IBUSY flip flop */ PUT_ETH_IBUSY(eth.status, 1); } data = duckbreath[arg++]; eth.rx_crc = f9401_7(eth.rx_crc, data); eth.fifo[eth.fifo_wr] = data; if (++eth.fifo_wr == ETHER_FIFO_SIZE) eth.fifo_wr = 0; PUT_ETH_WLF(eth.status, 1); if (ETHER_A49_BF == 0) { /* fifo is overrun: set input data late flip flop */ PUT_ETH_IDL(eth.status, 1); } if (arg == BREATHLEN) { /* * last word: reset the receiver CRC * * TODO: if data comes from some other source, * compare our CRC with the next word received * and set the CRC error flag if they differ. */ eth.rx_crc = 0; /* set the IGONE flip flop */ PUT_ETH_IGONE(eth.status, 1); ether_show_indicators(1); timer_insert(TIME_S(duckbreath_sec), rx_duckbreath, 0, "duckbreath"); } else { /* 5.44us per word (?) */ timer_insert(TIME_US(5.44), rx_duckbreath, arg, "duckbreath"); } eth_wakeup(); }
int setInvalidCount(unsigned int ip) { int c=uidb_get(bf_lockout,ip); if(!c) { timer_insert(10*60*1000,10*60*1000,login_clear_lockout,ip,0); } uidb_put(bf_lockout,ip,c+1); return c+1; }
/** * @brief transmit data from the FIFO to <nirvana for now> * * @param id timer id * @param arg word count if >= 0, -1 if CRC is to be transmitted (last word) */ static void tx_packet(int id, int arg) { uint32_t data; /* last word is the CRC */ if (arg == -1) { eth.tx_id = 0; /* TODO: send the CRC as final word of the packet */ dbg_printf(" CRC:%06o\n", eth.tx_crc); eth.tx_crc = 0; /* set the OGONE flip flop */ PUT_ETH_OGONE(eth.status, 1); eth_wakeup(); return; } data = eth.fifo[eth.fifo_rd]; eth.tx_crc = f9401_7(eth.tx_crc, data); if (eth.fifo_rd % 8) dbg_printf(" %06o", data); else dbg_printf("\n%06o: %06o", eth.tx_count, data); if (++eth.fifo_rd == ETHER_FIFO_SIZE) eth.fifo_rd = 0; eth.tx_count++; /* is the FIFO empty now? */ if (ETHER_A49_BE) { /* clear the OBUSY and WLF flip flops */ PUT_ETH_OBUSY(eth.status, 0); PUT_ETH_WLF(eth.status, 0); eth.tx_id = timer_insert(TIME_US(5.44), tx_packet, -1, "tx packet CRC"); eth_wakeup(); return; } /* next word */ eth.tx_id = timer_insert(TIME_US(5.44), tx_packet, arg + 1, "tx packet"); eth_wakeup(); }
/** * @brief Ethernet output data function * * Loads the FIFO from BUS[0-15], then increments the write * pointer at the end of the cycle. */ static void f2_eodfct_1(void) { LOG((0,3, " EODFCT<-; push %06o into FIFO[%02o]\n", cpu.bus, eth.fifo_wr)); eth.fifo[eth.fifo_wr] = cpu.bus; if (++eth.fifo_wr == ETHER_FIFO_SIZE) eth.fifo_wr = 0; PUT_ETH_WLF(eth.status, 1); PUT_ETH_OBUSY(eth.status, 1); /* if the FIFO is full */ if (ETHER_A49_BF == 0) { if (0 == eth.tx_id) eth.tx_id = timer_insert(TIME_US(5.44), tx_packet, 0, "tx packet"); } eth_wakeup(); }
error_t timer_restart (timer_handle_t _handle) { interrupt_level_t level; level = global_interrupt_disable (); if (is_invalid_handle (_handle)) { global_interrupt_enable (level); return ERROR_T (ERROR_TIMER_RESTART_INVHANDLE); } if (TIMER_STOPPED != _handle->state_) { g_statistics.abnormal_ ++; global_interrupt_enable (level); return ERROR_T (ERROR_TIMER_RESTART_INVSTATE); } global_interrupt_enable (level); timer_insert (_handle); return 0; }
/** * @brief pass command line switches down to the Ethernet code * * @param arg a pointer to a command line switch, like "-db" * @result returns 0 if arg was accepted, -1 otherwise */ int ether_args(const char *arg) { char *equ; int val; switch (arg[0]) { case '-': arg++; equ = strchr(arg, '='); if (equ) val = strtoull(equ+1,NULL,0); else val = 5; break; default: return -1; } if (!strncmp(arg, "ee", 2)) { ether_enable = 1; return 0; } if (!strncmp(arg, "db", 2)) { duckbreath_sec = val; if (duckbreath_sec > 0) timer_insert(TIME_S(duckbreath_sec), rx_duckbreath, 0, "duckbreath"); return 0; } if (!strncmp(arg, "eh", 2)) { if (val < 1 || val > 254) fatal(1, "Invalid Ether Host: %d\n", val); ether_id = val; return 0; } return -1; }
/* * Forward Rendezvous to Other Port */ SYSCALL ER _tk_fwd_por( ID porid, UINT calptn, RNO rdvno, void *msg, INT cmsgsz ) { PORCB *porcb; TCB *caltcb, *tcb; QUEUE *queue; RNO new_rdvno; ER ercd = E_OK; CHECK_PORID(porid); CHECK_PAR(calptn != 0); CHECK_RDVNO(rdvno); CHECK_PAR(cmsgsz >= 0); CHECK_INTSK(); porcb = get_porcb(porid); caltcb = get_tcb(get_tskid_rdvno(rdvno)); BEGIN_CRITICAL_SECTION; if ( porcb->porid == 0 ) { ercd = E_NOEXS; goto error_exit; } #if CHK_PAR if ( cmsgsz > porcb->maxcmsz ) { ercd = E_PAR; goto error_exit; } #endif if ( (caltcb->state & TS_WAIT) == 0 || caltcb->wspec != &wspec_rdv || rdvno != caltcb->winfo.rdv.rdvno ) { ercd = E_OBJ; goto error_exit; } if ( porcb->maxrmsz > caltcb->winfo.rdv.maxrmsz ) { ercd = E_OBJ; goto error_exit; } #if CHK_PAR if ( cmsgsz > caltcb->winfo.rdv.maxrmsz ) { ercd = E_PAR; goto error_exit; } #endif /* Search accept wait task */ queue = porcb->accept_queue.next; while ( queue != &porcb->accept_queue ) { tcb = (TCB*)queue; queue = queue->next; if ( (calptn & tcb->winfo.acp.acpptn) == 0 ) { continue; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_CAL) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Send message */ new_rdvno = gen_rdvno(caltcb); if ( cmsgsz > 0 ) { memcpy(tcb->winfo.acp.msg, msg, (UINT)cmsgsz); } *tcb->winfo.acp.p_rdvno = new_rdvno; *tcb->winfo.acp.p_cmsgsz = cmsgsz; wait_release_ok(tcb); /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_RDV) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Change rendezvous end wait of the other task */ caltcb->winfo.rdv.rdvno = new_rdvno; caltcb->winfo.rdv.msg = caltcb->winfo.cal.msg; caltcb->winfo.rdv.maxrmsz = porcb->maxrmsz; caltcb->winfo.rdv.p_rmsgsz = caltcb->winfo.cal.p_rmsgsz; caltcb->nodiswai = ( (porcb->poratr & TA_NODISWAI) != 0 )? TRUE: FALSE; goto error_exit; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_CAL) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Change the other task to rendezvous call wait */ caltcb->wspec = ( (porcb->poratr & TA_TPRI) != 0 )? &wspec_cal_tpri: &wspec_cal_tfifo; caltcb->wid = porid; caltcb->winfo.cal.calptn = calptn; caltcb->winfo.cal.msg = caltcb->winfo.rdv.msg; caltcb->winfo.cal.cmsgsz = cmsgsz; caltcb->winfo.cal.p_rmsgsz = caltcb->winfo.rdv.p_rmsgsz; caltcb->nodiswai = ( (porcb->poratr & TA_NODISWAI) != 0 )? TRUE: FALSE; timer_insert(&caltcb->wtmeb, TMO_FEVR, (CBACK)wait_release_tmout, caltcb); if ( (porcb->poratr & TA_TPRI) != 0 ) { queue_insert_tpri(caltcb, &porcb->call_queue); } else { QueInsert(&caltcb->tskque, &porcb->call_queue); } if ( cmsgsz > 0 ) { memcpy(caltcb->winfo.cal.msg, msg, (UINT)cmsgsz); } error_exit: END_CRITICAL_SECTION; return ercd; }
SYSCALL INT _tk_acp_por_u( ID porid, UINT acpptn, RNO *p_rdvno, void *msg, TMO_U tmout ) { PORCB *porcb; TCB *tcb; QUEUE *queue; RNO rdvno; INT cmsgsz; ER ercd = E_OK; CHECK_PORID(porid); CHECK_PAR(acpptn != 0); CHECK_TMOUT(tmout); CHECK_DISPATCH(); porcb = get_porcb(porid); BEGIN_CRITICAL_SECTION; if ( porcb->porid == 0 ) { ercd = E_NOEXS; goto error_exit; } /* Search call wait task */ queue = porcb->call_queue.next; while ( queue != &porcb->call_queue ) { tcb = (TCB*)queue; queue = queue->next; if ( (acpptn & tcb->winfo.cal.calptn) == 0 ) { continue; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) { ercd = E_DISWAI; goto error_exit; } /* Receive message */ *p_rdvno = rdvno = gen_rdvno(tcb); cmsgsz = tcb->winfo.cal.cmsgsz; if ( cmsgsz > 0 ) { memcpy(msg, tcb->winfo.cal.msg, (UINT)cmsgsz); } /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, tcb, TTW_RDV) ) { wait_release_ng(tcb, E_DISWAI); goto error_exit; } wait_cancel(tcb); /* Make the other task at rendezvous end wait state */ tcb->wspec = &wspec_rdv; tcb->wid = 0; tcb->winfo.rdv.rdvno = rdvno; tcb->winfo.rdv.msg = tcb->winfo.cal.msg; tcb->winfo.rdv.maxrmsz = porcb->maxrmsz; tcb->winfo.rdv.p_rmsgsz = tcb->winfo.cal.p_rmsgsz; timer_insert(&tcb->wtmeb, TMO_FEVR, (CBACK)wait_release_tmout, tcb); QueInit(&tcb->tskque); goto error_exit; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) { ercd = E_DISWAI; goto error_exit; } ercd = E_TMOUT; if ( tmout != TMO_POL ) { /* Ready for rendezvous accept wait */ ctxtsk->wspec = &wspec_acp; ctxtsk->wid = porid; ctxtsk->wercd = &ercd; ctxtsk->winfo.acp.acpptn = acpptn; ctxtsk->winfo.acp.msg = msg; ctxtsk->winfo.acp.p_rdvno = p_rdvno; ctxtsk->winfo.acp.p_cmsgsz = &cmsgsz; make_wait(tmout, porcb->poratr); QueInsert(&ctxtsk->tskque, &porcb->accept_queue); } error_exit: END_CRITICAL_SECTION; return ( ercd < E_OK )? ercd: cmsgsz; }