uint16 SensorTag_ProcessEvent(uint8 task_id, uint16 events) { VOID task_id; // OSAL required parameter that isn't used in this function /////////////////////////////////////////////////////////////////////// // system event handle // /////////////////////////////////////////////////////////////////////// if (events & SYS_EVENT_MSG) { uint8 *msg; if ((msg = osal_msg_receive(sensorTag_TaskID)) != NULL) { sensorTag_ProcessOSALMsg((osal_event_hdr_t *) msg); // release the OSAL message osal_msg_deallocate(msg); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } /////////////////////////////////////////////////////////////////////// // start device event // /////////////////////////////////////////////////////////////////////// if (events & EVT_START_DEVICE) { // start the device GAPRole_StartDevice(&sensorTag_PeripheralCBs); // start bond manager #if !defined(GAPBONDMGR_NO_SUPPORT) GAPBondMgr_Register(&sensorTag_BondMgrCBs); #endif // start peripheral device oled_init(); adxl345_softrst(); // adxl345_self_calibration(); steps = 0; BATCD_PXIFG = ~(BATCD_BV); BATCD_IEN |= BATCD_IENBIT; osal_start_reload_timer(sensorTag_TaskID, EVT_RTC, PERIOD_RTC); pwmgr_state_change(PWMGR_S0, 0); fmsg(("\033[40;32m\n[power on]\033[0m\n")); return (events ^ EVT_START_DEVICE); } /////////////////////////////////////////////////////////////////////// // key long press handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_MODE) { if (key1_press) { oled_clr_screen(); if ((opmode & 0xF0) == MODE_NORMAL) { opmode = MODE_WORKOUT | MODE_TIME; workout.steps = normal.steps; workout.time = osal_getClock(); fmsg(("\033[40;32m[workout mode]\033[0m\n")); } else { opmode = MODE_NORMAL | MODE_TIME; fmsg(("\033[40;32m[normal mode]\033[0m\n")); } pwmgr_state_change(pwmgr, TIME_OLED_OFF); } return (events ^ EVT_MODE); } if (events & EVT_SLEEP) { if (key1_press) { oled_clr_screen(); opmode = MODE_SLEEP; fmsg(("\033[40;32m[sleep mode]\033[0m\n")); pwmgr_state_change(pwmgr, TIME_OLED_OFF); } return (events ^ EVT_SLEEP); } if (events & EVT_SYSRST) { if (key1_press) { fmsg(("\033[40;32m[system reset]\033[0m\n")); HAL_SYSTEM_RESET(); // adxl345_self_calibration(); } return (events ^ EVT_SYSRST); } /////////////////////////////////////////////////////////////////////// // display handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_DISP) { if (pwmgr == PWMGR_S1) { sensorTag_HandleDisp(opmode, acc); } else { // display battery only sensorTag_BattDisp(batt_get_level()); } if (pwmgr != PWMGR_S6) { osal_start_timerEx(sensorTag_TaskID, EVT_DISP, PERIOD_DISP); } return (events ^ EVT_DISP); } /////////////////////////////////////////////////////////////////////// // g-sensor handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_GSNINT1) { adxl345_exit_sleep(); pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF); return (events ^ EVT_GSNINT1); } if (events & EVT_GSNINT2) { unsigned char sampling; unsigned char i; sampling = adxl345_chk_fifo(); for (i=0; i<sampling; i++) { adxl345_read(acc); #if (DEBUG_MESSAGE & MSG_STEPS) { unsigned long tmp = algo_step(acc); if (normal.steps != tmp) { stepmsg(("\033[1;33mstep=%0lu\n\033[0m", tmp)); } normal.steps = tmp; } #else normal.steps = algo_step(acc); #endif } normal.distance = calc_distance(normal.steps, pi.stride); workout.distance = calc_distance((normal.steps - workout.steps), pi.stride); normal.calorie = calc_calorie(normal.distance, pi.weight); workout.calorie = calc_calorie(workout.distance, pi.weight); return (events ^ EVT_GSNINT2); } if (events & EVT_GSENSOR) { adxl345_exit_sleep(); return (events ^ EVT_GSENSOR); } /////////////////////////////////////////////////////////////////////// // RTC handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_RTC) { // performed once per second // record data if ((pwmgr != PWMGR_S5) && (pwmgr != PWMGR_S6)) { #if defined(HAL_IMAGE_A) || defined(HAL_IMAGE_B) if ((osal_getClock() - mark.time) >= (12UL*60UL)) { #else if ((osal_getClock() - mark.time) >= (12UL)) { #endif if (!hash_is_full()) { unsigned short tmp = normal.steps - mark.steps; switch (opmode & 0xF0) { case MODE_WORKOUT: tmp |= 0x8000; break; case MODE_SLEEP: tmp |= 0x4000; break; } hash_put(&tmp); } mark.time = osal_getClock(); #if defined(HAL_IMAGE_A) || defined(HAL_IMAGE_B) if ((mark.time % (24UL*60UL*60UL)) <= (13UL*60UL)) { #else if ((mark.time % (24UL*60UL*60UL)) <= (13UL)) { #endif dmsg(("reset steps...\n")); normal.steps = 0; workout.steps = 0; STEPS = 0; } mark.steps = normal.steps; } } // power management switch (pwmgr) { case PWMGR_S0: pmsg(("\033[40;35mS0 (power on)\033[0m\n")); if (pwmgr_saving_timer()) { adxl345_enter_sleep(); osal_pwrmgr_device(PWRMGR_BATTERY); pwmgr_state_change(PWMGR_S4, 0); } break; case PWMGR_S1: pmsg(("\033[40;35mS1 (rtc+gsen+ble+oled)\033[0m\n")); if (pwmgr_saving_timer()) { oled_enter_sleep(); osal_stop_timerEx(sensorTag_TaskID, EVT_MODE); osal_stop_timerEx(sensorTag_TaskID, EVT_SLEEP); osal_stop_timerEx(sensorTag_TaskID, EVT_SYSRST); pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF); } break; case PWMGR_S2: pmsg(("\033[40;35mS2 (rtc+gsen+ble)\033[0m\n")); if (gapProfileState == GAPROLE_WAITING) { // enable key interrupt mode InitBoard(OB_READY); pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF); } break; case PWMGR_S3: pmsg(("\033[40;35mS3 (rtc+gsen)\033[0m\n")); if (steps == normal.steps) { if (pwmgr_saving_timer()) { adxl345_enter_sleep(); pwmgr_state_change(PWMGR_S4, 0); } } else { steps = normal.steps; pwmgr_state_change(pwmgr, TIME_GSEN_OFF); } break; case PWMGR_S4: pmsg(("\033[40;35mS4 (rtc)\033[0m\n")); dmsg(("$")); break; default: case PWMGR_S5: pmsg(("\033[40;35mS5 (shutdown)\033[0m\n")); adxl345_shutdown(); osal_stop_timerEx(sensorTag_TaskID, EVT_RTC); break; case PWMGR_S6: pmsg(("\033[40;35mS6 (rtc+oled)\033[0m\n")); if (pwmgr_saving_timer()) { oled_enter_sleep(); // enable key interrupt mode InitBoard(OB_READY); pwmgr_state_change(PWMGR_S5, 0); } break; } // battery measure if ((!batt_measure()) && (pwmgr != PWMGR_S6)) { pwmgr_state_change(PWMGR_S5, 0); } return (events ^ EVT_RTC); } /////////////////////////////////////////////////////////////////////// // battery charge detect handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_CHARGING) { if (pwmgr != PWMGR_S1) { if (!BATCD_SBIT) { dmsg(("[charging]\n")); oled_exit_sleep(); if ((pwmgr == PWMGR_S5) || (pwmgr == PWMGR_S6)) { osal_start_reload_timer(sensorTag_TaskID, EVT_RTC, PERIOD_RTC); pwmgr_state_change(PWMGR_S4, 0); } } else { dmsg(("[no charge]\n")); oled_enter_sleep(); } } return (events ^ EVT_CHARGING); } /////////////////////////////////////////////////////////////////////// // discard unknown events // /////////////////////////////////////////////////////////////////////// return 0; }
/* * Register a process or port (can't be registered twice). * Returns 0 if name, process or port is already registered. * * When smp support is enabled: * * Assumes that main lock is locked (and only main lock) * on c_p. * */ int erts_register_name(Process *c_p, Eterm name, Eterm id) { int res = 0; Process *proc = NULL; Port *port = NULL; RegProc r, *rp; ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p); if (is_not_atom(name) || name == am_undefined) return res; if (c_p->common.id == id) /* A very common case I think... */ proc = c_p; else { if (is_not_internal_pid(id) && is_not_internal_port(id)) return res; erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN); if (is_internal_port(id)) { port = erts_id2port(id); if (!port) goto done; } } #ifdef ERTS_SMP { ErtsProcLocks proc_locks = proc ? ERTS_PROC_LOCK_MAIN : 0; reg_safe_write_lock(proc, &proc_locks); if (proc && !proc_locks) erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN); } #endif if (is_internal_pid(id)) { if (!proc) proc = erts_pid2proc(NULL, 0, id, ERTS_PROC_LOCK_MAIN); r.p = proc; if (!proc) goto done; if (proc->common.u.alive.reg) goto done; r.pt = NULL; } else { ASSERT(!INVALID_PORT(port, id)); ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(port)); r.pt = port; if (r.pt->common.u.alive.reg) goto done; r.p = NULL; } r.name = name; rp = (RegProc*) hash_put(&process_reg, (void*) &r); if (proc && rp->p == proc) { if (IS_TRACED_FL(proc, F_TRACE_PROCS)) { trace_proc(proc, ERTS_PROC_LOCK_MAIN, proc, am_register, name); } proc->common.u.alive.reg = rp; } else if (port && rp->pt == port) { if (IS_TRACED_FL(port, F_TRACE_PORTS)) { trace_port(port, am_register, name); } port->common.u.alive.reg = rp; } if ((rp->p && rp->p->common.id == id) || (rp->pt && rp->pt->common.id == id)) { res = 1; } done: reg_write_unlock(); if (port) erts_port_release(port); if (c_p != proc) { if (proc) erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_MAIN); erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN); } return res; }
void erts_init_node_tables(int dd_sec) { erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER; HashFunctions f; if (dd_sec == ERTS_NODE_TAB_DELAY_GC_INFINITY) node_tab_delete_delay = (ErtsMonotonicTime) -1; else node_tab_delete_delay = ((ErtsMonotonicTime) dd_sec)*1000; orig_node_tab_delete_delay = node_tab_delete_delay; rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ; rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED; f.hash = (H_FUN) dist_table_hash; f.cmp = (HCMP_FUN) dist_table_cmp; f.alloc = (HALLOC_FUN) dist_table_alloc; f.free = (HFREE_FUN) dist_table_free; erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry)); dist_entries = 1; hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f); erts_hidden_dist_entries = NULL; erts_visible_dist_entries = NULL; erts_not_connected_dist_entries = NULL; erts_no_of_hidden_dist_entries = 0; erts_no_of_visible_dist_entries = 0; erts_no_of_not_connected_dist_entries = 0; erts_this_dist_entry->next = NULL; erts_this_dist_entry->prev = NULL; erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */ erts_smp_rwmtx_init_opt_x(&erts_this_dist_entry->rwmtx, &rwmtx_opt, "dist_entry", make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->sysname = am_Noname; erts_this_dist_entry->cid = NIL; erts_this_dist_entry->connection_id = 0; erts_this_dist_entry->status = 0; erts_this_dist_entry->flags = 0; erts_this_dist_entry->version = 0; erts_smp_mtx_init_x(&erts_this_dist_entry->lnk_mtx, "dist_entry_links", make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->node_links = NULL; erts_this_dist_entry->nlinks = NULL; erts_this_dist_entry->monitors = NULL; erts_smp_mtx_init_x(&erts_this_dist_entry->qlock, "dist_entry_out_queue", make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->qflgs = 0; erts_this_dist_entry->qsize = 0; erts_this_dist_entry->out_queue.first = NULL; erts_this_dist_entry->out_queue.last = NULL; erts_this_dist_entry->suspended = NULL; erts_this_dist_entry->finalized_out_queue.first = NULL; erts_this_dist_entry->finalized_out_queue.last = NULL; erts_smp_atomic_init_nob(&erts_this_dist_entry->dist_cmd_scheduled, 0); erts_port_task_handle_init(&erts_this_dist_entry->dist_cmd); erts_this_dist_entry->send = NULL; erts_this_dist_entry->cache = NULL; (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry); f.hash = (H_FUN) node_table_hash; f.cmp = (HCMP_FUN) node_table_cmp; f.alloc = (HALLOC_FUN) node_table_alloc; f.free = (HFREE_FUN) node_table_free; hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f); erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode)); node_entries = 1; erts_refc_init(&erts_this_node->refc, 1); /* The system itself */ erts_this_node->sysname = am_Noname; erts_this_node->creation = 0; erts_this_node->dist_entry = erts_this_dist_entry; erts_this_node_sysname = erts_this_node_sysname_BUFFER; erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER), "%T", erts_this_node->sysname); (void) hash_put(&erts_node_table, (void *) erts_this_node); erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table"); erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table"); references_atoms_need_init = 1; }
int main(int argc, char **argv) { int r, op = 'p', method = 'c'; const char *path; if (argc < 2) { fprintf(stderr, "usage: kv dbpath [put|get] [col|table|hash|pat|ql] [value_size]\n"); return -1; } path = *argv[1] ? argv[1] : NULL; if (argc > 2) { op = *argv[2]; } if (argc > 3) { method = *argv[3]; } if (argc > 4) { value_size = atoi(argv[4]); } if (argc > 5) { nloops = atoi(argv[5]); } if (grn_init()) { fprintf(stderr, "grn_init() failed\n"); return -1; } if (grn_ctx_init(&ctx, (method == 'q' ? GRN_CTX_USE_QL|GRN_CTX_BATCH_MODE : 0))) { fprintf(stderr, "grn_ctx_init() failed\n"); return -1; } srand(0); if (method == 'h' || method == 'p') { switch (method) { case 'h' : r = (op == 'p') ? hash_put(path) : hash_get(path); break; case 'p' : r = (op == 'p') ? pat_put(path) : pat_get(path); break; default : r = -1; fprintf(stderr, "invalid method\n"); break; } } else { if (path) { db = grn_db_open(&ctx, path); } if (!db) { db = grn_db_create(&ctx, path, NULL); } if (!db) { fprintf(stderr, "db initialize failed\n"); return -1; } value_type = grn_type_create(&ctx, "<value_type>", 12, 0, value_size); switch (method) { case 'q' : r = (op == 'p') ? ql_put() : ql_get(); break; case 'c' : r = (op == 'p') ? column_put() : column_get(); break; case 't' : r = (op == 'p') ? table_put() : table_get(); //r = (op == 'p') ? table_put_allocate() : table_get(); //r = (op == 'p') ? table_put2() : table_get(); break; default : r = -1; fprintf(stderr, "invalid method\n"); break; } if (grn_obj_close(&ctx, db)) { fprintf(stderr, "grn_obj_close() failed\n"); return -1; } } if (grn_ctx_fin(&ctx)) { fprintf(stderr, "grn_ctx_fin() failed\n"); return -1; } if (grn_fin()) { fprintf(stderr, "grn_fin() failed\n"); return -1; } return r; }
static int bdd_compact_r(bdd_node_t *cur, hash_t *h, bdd_t *outbdd, bdd_node_t **out) { if ((cur->iszero != NULL) && (cur->isone != NULL)) { char c0 = '0', c1 = '1', ce = 'r', *check; check = hash_get(h, cur->var); if ((check == NULL) || (*check == ce)) { /*printf("%s not yet set.\n", cur->var); * hash_dump(h);*/ hash_put(h, cur->var, &c1, sizeof(c1)); strlcpy((*out)->var, cur->var, sizeof((*out)->var)); /* do not append to nodelist yet! */ (*out)->iszero = bdd_init_node_ext(outbdd, *out, NULL, NULL, 0); (*out)->isone = bdd_init_node_ext(outbdd, *out, NULL, NULL, 0); bdd_compact_r(cur->isone, h, outbdd, &(*out)->isone); hash_put(h, cur->var, &c0, sizeof(c0)); bdd_compact_r(cur->iszero, h, outbdd, &(*out)->iszero); hash_put(h, cur->var, &ce, sizeof(ce)); if ( ((strcmp((*out)->iszero->var, no.var) == 0) || (strcmp((*out)->iszero->var, yes.var) == 0)) && (strcmp((*out)->iszero->var, (*out)->isone->var) == 0)) { /* * We check node for equality of both * descendants. We can remove them in this * case and push the value 1 position up. */ (*out)->var[0] = (*out)->iszero->var[0]; (*out)->var[1] = 0; mem_free((*out)->isone); mem_free((*out)->iszero); (*out)->iszero = NULL; (*out)->isone = NULL; /*printf("Contracted 2x %s.\n", (*out)->var);*/ } else { /* now fixup nodelist */ if (list_append(outbdd->nodelist, (*out)->iszero) < 0) return -1; if (list_append(outbdd->nodelist, (*out)->isone) < 0) return -1; } } else if (*check == c0) /*printf("Ignoring 1, because %s set.\n", cur->var); * hash_dump(h);*/ bdd_compact_r(cur->iszero, h, outbdd, out); else /*printf("Ignoring 0, because %s set.\n", cur->var); * hash_dump(h);*/ bdd_compact_r(cur->isone, h, outbdd, out); } else { strlcpy((*out)->var, cur->var, sizeof((*out)->var)); #ifdef VERBOSE printf("bdd_compact_r: %p <- %s[%p] \n", (*out)->parent, (*out)->var, *out); #endif } return 0; }
void tbl_bufif (syn_ctx * ctx, char *name, int width, Opdesc const *op) { char *buf = cell_name ("%s_%d", op->name, width); assert (width > 0); if (!name) { //create definition if (!exists (ctx, buf)) { int i; char *inv1 = NULL; char **inv_en = NULL; char **tris = NULL; if (op->buf_pol) { exprInv (ctx, NULL, width); } if (!op->en_pol) { exprInv (ctx, NULL, 1); } exprTri1 (ctx, NULL); o_p ("(cell %s (celltype GENERIC)\n", buf); i_i (); o_p ("(view netlist (viewtype NETLIST)\n"); i_i (); o_p ("(interface\n"); i_i (); for (i = 0; i < width; i++) o_p ("(port A_%d (direction INPUT))\n", i); //inputs for (i = 0; i < width; i++) o_p ("(port B_%d (direction INPUT))\n", i); //the enable for (i = 0; i < width; i++) o_p ("(port Q_%d (direction OUTPUT))\n", i); //outputs i_d (); o_p (")\n"); //interface o_p ("(contents\n"); i_i (); if (op->buf_pol) { inv1 = l_n (); exprInv (ctx, inv1, width); } if (!op->en_pol) { inv_en = calloc (width, sizeof (char *)); assert (inv_en); for (i = 0; i < width; i++) { inv_en[i] = l_n (); exprInv (ctx, inv_en[i], 1); } } tris = calloc (width, sizeof (char *)); assert (tris); for (i = 0; i < width; i++) { tris[i] = l_n (); exprTri1 (ctx, tris[i]); } if (op->buf_pol) { for (i = 0; i < width; i++) { n_n (); o_p ("(portref A_%d)\n", i); o_p ("(portref A_%d (instanceref %s))\n", i, inv1); n_e (); n_n (); o_p ("(portref Q_%d (instanceref %s))\n", i, inv1); o_p ("(portref A (instanceref %s))\n", tris[i]); n_e (); } } else { for (i = 0; i < width; i++) { n_n (); o_p ("(portref A_%d)\n", i); o_p ("(portref A (instanceref %s))\n", tris[i]); n_e (); } } if (!op->en_pol) { for (i = 0; i < width; i++) { n_n (); o_p ("(portref B_%d)\n"); o_p ("(portref A (instanceref %s))\n", inv_en[i]); n_e (); n_n (); o_p ("(portref Q (instanceref %s))\n", inv_en[i]); o_p ("(portref ENA (instanceref %s))\n", tris[i]); n_e (); } } else { for (i = 0; i < width; i++) { n_n (); o_p ("(portref B_%d)\n", i); o_p ("(portref ENA (instanceref %s))\n", tris[i]); n_e (); } } for (i = 0; i < width; i++) { n_n (); o_p ("(portref Q (instanceref %s))\n", tris[i]); o_p ("(portref Q_%d)\n", i); n_e (); } i_d (); o_p (")\n"); //contents i_d (); o_p (")\n"); //view i_d (); o_p (")\n"); //cell hash_put (ctx, buf); for (i = 0; i < width; i++) free (tris[i]); free (tris); if (!op->en_pol) { for (i = 0; i < width; i++) free (inv_en[i]); free (inv_en); } if (op->buf_pol) free (inv1); } } else { o_p ("(instance %s (viewref netlist (cellref %s (libraryref DESIGNS))))\n", name, buf); } free (buf); }
/** Hashtable test */ static int hash_test( long elements ) { long i; int res=1; hash_table_t h; hash_init( &h, hash_func, compare_func ); for( i=1; i< elements+1; i++ ) { hash_put( &h, (void*)i, (void*)100l-i ); } for( i=1; i< elements+1; i++ ) { if( (long)hash_get( &h, (void*)i ) != (100l-i) ) { err( L"Key %d gave data %d, expected data %d", i, (long)hash_get( &h, (void*)i ), 100l-i ); res = 0; break; } } if( hash_get_count( &h ) != elements ) { err( L"Table holds %d elements, should hold %d elements", hash_get_count( &h ), elements ); res = 0; } for( i=1; i<elements+1; i+=2 ) { hash_remove( &h, (void*)i, 0, 0 ); } if( hash_get_count( &h ) != ((elements)/2) ) { err( L"Table contains %d elements, should contain %d elements", hash_get_count( &h ), elements/2 ); res = 0; } for( i=1; i<elements+1; i++ ) { if( hash_contains( &h, (void*)i) != (i+1l)%2l ) { if( i%2 ) err( L"Key %d remains, should be deleted", i ); else err( L"Key %d does not exist", i ); res = 0; break; } } hash_destroy( &h ); return res; }
IpConn* IpConnTrack_track_pkt(IpConnTrack *self, struct netpkt *pkt, int track_flags) { IpConnAddr key; IpConn *conn=0; IpConnTcpQueue *queue=0; int tmp_port; //int err=-1; int i; int flags=0, local=0; hash_node_t *node=0; u32 tmp_addr; u32 *addr; netpkt_ip *ip=0; netpkt_tcp *tcp=0; netpkt_udp *udp=0; //netpkt_icmp *icmp=0; ip = pkt->pkt_ip; tcp = pkt->pkt_tcp; udp = pkt->pkt_udp; //icmp = pkt->pkt_icmp; if( !ip || (!tcp && !udp) ) { return 0; } do { /* check if this matches one of my local addresses */ local = 0; for(i=array_count(&self->m_local_addrs), addr=(u32*)array_get(&self->m_local_addrs, 0); i>0; i--, addr++) { if( ip->src == *addr ) { flags |= CONN_PKT_LOCAL_SRC; local = 1; } if( ip->dst == *addr ) { flags |= CONN_PKT_LOCAL_DST; local = 1; } } // ignore non-local packets if( (track_flags & IPCONN_TRACK_LOCAL) && !local ) { break; } /* The canonical hash key in self->conn_hash is client_ip/server_ip/client_port/server_port */ memset(&key, 0, sizeof(key)); /* see if this packet is from server to client. */ flags |= CONN_PKT_FROM_SERVER; key.proto = ip->p; key.client_addr = ip->dst; key.server_addr = ip->src; if( tcp ) { key.client_port = ntohs(tcp->dest); key.server_port = ntohs(tcp->source); } else if( udp ) { key.client_port = ntohs(udp->dest); key.server_port = ntohs(udp->source); } node = hash_get(&self->m_conn_hash, &key); if( node ) { //debug(("track_pkt: packet from server conn=%p\n", node->hash_val)); break; } /* otherwise, this packet is from client to server */ flags &= ~CONN_PKT_FROM_SERVER; flags |= CONN_PKT_FROM_CLIENT; SWAP(key.client_addr, key.server_addr, tmp_addr); SWAP(key.client_port, key.server_port, tmp_port); node = hash_get(&self->m_conn_hash, &key); if( node ) { //debug(("track_pkt: packet from client conn=%p\n", node->hash_val)); break; } // Only start connections on a pure TCP SYN, not a SYN,ACK //if( tcp && (!tcp_syn(tcp) || tcp_ack(tcp)) ) { // break; //} /* doesn't match anything, start a new connection */ flags |= CONN_PKT_FIRST; conn = (IpConn*)malloc(sizeof(*conn)); assertb(conn); IpConn_init(conn); conn->conn_addr = key; conn->conn_state = CONN_STATE_SYN; conn->conn_time_first = mstime(); if( flags & CONN_PKT_LOCAL_DST ) { conn->conn_flags |= CONN_LOCAL_SERVER; } if( flags & CONN_PKT_LOCAL_SRC ) { conn->conn_flags |= CONN_LOCAL_CLIENT; } //debug(("track_pkt: new connection conn=%p\n", conn)); node = hash_put(&self->m_conn_hash, conn, conn); //err = 0; } while(0); if( !node ) { return 0; } conn = (IpConn*)node->node_val; conn->conn_pkt_flags = flags; IpConnTrack_track_state(self, conn, pkt); // track the stream itself if( conn->conn_pkt_flags & CONN_PKT_FROM_SERVER ) { queue = &conn->queue_server; } else if( conn->conn_pkt_flags & CONN_PKT_FROM_CLIENT ) { queue = &conn->queue_client; } if( queue ) { IpConnTrack_track_stream(self, conn, queue, pkt, track_flags & IPCONN_TRACK_BUFFER); } return conn; }