/* scopes process */ PROCESS_THREAD(scopes_process, ev, data) { PROCESS_BEGIN(); LOG_L("scopes process started\n"); /* create and start an event timer */ static struct etimer scopes_timer; etimer_set(&scopes_timer, SCOPES_TIMER_DURATION * CLOCK_SECOND); do { /* wait till the timer expires and then reset it immediately */ PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&scopes_timer)); etimer_reset(&scopes_timer); struct scope *s; /* check memberships of dynamic scopes */ // LOG_L("checking dynamic scope memberships\n"); for (s = list_head(scopes); s != NULL; s = s->next) { /* only check scopes not created by the local node */ if (HAS_FLAG(s, SCOPES_FLAG_DYNAMIC) && !HAS_STATUS(s, SCOPES_STATUS_CREATOR)) { /* check membership */ int should_be_member = membership->check(s->specs, s->spec_len); /* decide action */ if (should_be_member && !HAS_STATUS(s, SCOPES_STATUS_MEMBER)) { /* join scope */ join_scope(s); } else if (!should_be_member && HAS_STATUS(s, SCOPES_STATUS_MEMBER)) { /* leave scope */ leave_scope(s); } } } // /* print scopes information */ // LOG_L("known scopes:\n"); // LOG_L("-------------\n"); // for (s = list_head(scopes); s != NULL; s = s->next) { // print_scope(s); // } // LOG_L("-------------\n"); }while(1); PROCESS_END(); }
static void reset_scope_timer(struct scope *scope) { clock_time_t timeout = CLOCK_SECOND * scope->ttl; if (HAS_STATUS(scope, SCOPES_STATUS_CREATOR)) { /* shorten the creator's timer so the scope is re-announced in time */ timeout = timeout * SCOPES_REANNOUNCE_FACTOR; } /* reset the timer */ ctimer_set(&(scope->ttl_timer), timeout, (void(*)(void *)) handle_scope_timeout, scope); }
static void handle_scope_timeout(struct scope *scope) { /* check if the node is the creator of the scope and if the owner is subscribed */ if (HAS_STATUS(scope, SCOPES_STATUS_CREATOR) && IS_SUBSCRIBED(scope->owner)) { /* re-announce the scope on the network */ announce_scope_open(scope); /* reset the timer to ensure periodic re-announcements */ reset_scope_timer(scope); } else { /* remove the expired scope */ remove_scope(scope); } }
void scopes_close(struct subscriber *subscriber, struct scope *scope) { /* check if the application is subscribed */ if (!IS_SUBSCRIBED(subscriber)) { return; } /* check if this scope may be deleted */ if (!HAS_STATUS(scope, SCOPES_STATUS_CREATOR) || !IS_OWNER(scope, subscriber)) { return; } /* announce the deletion of the scope on the network */ announce_scope_close(scope); /* remove the scope from the scopes list */ remove_scope(scope); }
static void remove_single_scope(struct scope *scope) { /* leave scope in case node is a member */ if (HAS_STATUS(scope, SCOPES_STATUS_MEMBER)) { leave_scope(scope); } /* inform the owner */ CALLBACK(scope->owner, remove(scope)); /* inform the routing process */ routing->remove(scope); /* remove the scope */ list_remove(scopes, scope); /* stop the scope's TTL timer */ ctimer_stop(&(scope->ttl_timer)); /* deallocate scope memory */ deallocate_scope(scope); }
void scopes_receive(struct scopes_msg_generic *gmsg) { #ifdef DEBUG_SCOPES printf("scope_id %d, type%d\n", gmsg->scope_id, gmsg->type); #endif DEBUG_SCOPES switch (gmsg->type) { case SCOPES_MSG_OPEN: { /* cast the message to the correct type */ struct scopes_msg_open *msg = (struct scopes_msg_open *) gmsg; struct scope *super_scope = lookup_scope_id(msg->scope_id); struct scope *new_scope = lookup_scope_id(msg->sub_scope_id); /* check if the super scope is known */ if (super_scope != NULL) { /* check if the node is a member in the super scope */ if (HAS_STATUS(super_scope, SCOPES_STATUS_MEMBER)) { /* check if the new scope is known */ if (new_scope != NULL) { /* check if the new scope is the super scope's sub scope */ if (ARE_LINKED(super_scope, new_scope) && !HAS_STATUS(new_scope, SCOPES_STATUS_CREATOR)) { /* calculate the position of the specification */ void *specs_msg_ptr = (void *) ((uint8_t *) gmsg + sizeof(struct scopes_msg_open)); /* check membership */ int should_be_member = membership->check(specs_msg_ptr, msg->spec_len); /* check if the timer should be reset */// XXX: added isforwarder for aggregation if (should_be_member || msg->flags & SCOPES_FLAG_DYNAMIC || is_forwarder( msg->sub_scope_id)) { /* reset the sub scope's TTL timer */ reset_scope_timer(new_scope); } else { /* remove the scope */ remove_scope(new_scope); } } } else { /* check if the owner exists on this node and is subscribed */ struct subscriber *owner = lookup_subscriber_id( msg->owner_sid); if (owner != NULL && IS_SUBSCRIBED(owner)) { /* calculate the position of the specification */ void *specs_msg_ptr = (void *) ((uint8_t *) packetbuf_dataptr() + sizeof(struct scopes_msg_open)); /* check membership */ int should_be_member = membership->check(specs_msg_ptr, msg->spec_len); /* add the scope if the node meets the membership criteria or if the scope is a dynamic scope */// XXX: added isforwarder for aggregation if (should_be_member || msg->flags & SCOPES_FLAG_DYNAMIC || is_forwarder( msg->sub_scope_id)) { /* try to get memory for the new scope */ new_scope = allocate_scope(msg->spec_len); /* check if memory could be obtained */ if (new_scope != NULL) { /* fill in the scope information */ new_scope->scope_id = msg->sub_scope_id; new_scope->super_scope_id = msg->scope_id; new_scope->owner = owner; new_scope->ttl = msg->ttl; new_scope->status = SCOPES_STATUS_NONE; new_scope->flags = msg->flags; new_scope->spec_len = msg->spec_len; /* copy the specification */ memcpy(new_scope->specs, specs_msg_ptr, msg->spec_len); /* add the scope to the scopes list */ add_scope(new_scope); /* join if the node should be a member */ if (should_be_member) { join_scope(new_scope); } } } } } } } } break; case SCOPES_MSG_CLOSE: { /* cast the message to the correct type */ struct scopes_msg_close *msg = (struct scopes_msg_close *) gmsg; struct scope *super_scope = lookup_scope_id(msg->scope_id); struct scope *sub_scope = lookup_scope_id(msg->sub_scope_id); /* check if the scope should be removed */ if (super_scope != NULL && sub_scope != NULL && ARE_LINKED(super_scope, sub_scope) && !HAS_STATUS(sub_scope, SCOPES_STATUS_CREATOR)) { /* remove the scope */ remove_scope(sub_scope); } } break; case SCOPES_MSG_DATA: { /* cast the message to the correct type */ struct scopes_msg_data *msg = (struct scopes_msg_data *) gmsg; struct scope *scope = lookup_scope_id(msg->scope_id); /* check if the scope is known */ if (scope != NULL) { /* check if the node is a member */ // if (HAS_STATUS(scope, SCOPES_STATUS_MEMBER)) { // XXX: removed for aggregation support /* check if the message should be delivered */ if ((msg->to_creator /*&& HAS_STATUS(scope, SCOPES_STATUS_CREATOR) // XXX: commented for AGGREGATION support*/) || (!(msg->to_creator) && !HAS_STATUS(scope, SCOPES_STATUS_CREATOR) && HAS_STATUS(scope, SCOPES_STATUS_MEMBER) /* // XXX: added for AGGREGATION support */)) { /* check if the owner is subscribed */ if (IS_SUBSCRIBED(scope->owner)) { /* calculate the position of the payload */ void *payload_ptr = (void *) ((uint8_t *) gmsg + sizeof(struct scopes_msg_data)); /* notify the owner */ CALLBACK(scope->owner, recv(scope, payload_ptr, msg->data_len)); } } // } } else { // with no scope entry it is a forwarder! or not :( // XXX: added for aggregation support if (is_forwarder(msg->scope_id) && msg->to_creator) { struct subscriber *s = lookup_subscriber_id(msg->target_sid); if (IS_SUBSCRIBED(s)) { // calculate the position of the payload void *payload_ptr = (void *) ((uint8_t *) packetbuf_dataptr() + sizeof(struct scopes_msg_data)); // artificial scope entry mockup.scope_id = msg->scope_id; mockup.super_scope_id = 0; mockup.owner = s; // notify the owner CALLBACK(s, recv(&mockup, payload_ptr, msg->data_len)); } } } } break; default: return; } }
void scopes_send(struct subscriber *subscriber, struct scope *scope, bool to_creator, void *data, data_len_t data_len) { #ifdef SCOPES_DEBUG printf("scopes::scopes_send() - function entered. subscriber id: %u, scope id: %u, , to_creator: %u, data_len: %u\n", subscriber->id, scope->scope_id, to_creator, data_len); #endif //SCOPES_DEBUG /* check if the application is subscribed */ if (!IS_SUBSCRIBED(subscriber)) { return; } /* check if a message may be sent to this scope */// XXX: added for aggregation support if (!HAS_STATUS(scope, SCOPES_STATUS_MEMBER) && !is_forwarder( scope->scope_id)) { return; } /* reset the contents of the packet buffer */ #ifdef FRAGMENTATION_ENABLED if (to_creator) routing->buffer_clear(); else packetbuf_clear(); #else packetbuf_clear(); #endif /* create the message */ struct scopes_msg_data *msg; #ifdef FRAGMENTATION_ENABLED if (to_creator) msg = (struct scopes_msg_data *) routing->buffer_ptr(); else msg = (struct scopes_msg_data *) packetbuf_dataptr(); #else msg = (struct scopes_msg_data *) packetbuf_dataptr(); #endif msg->scope_id = scope->scope_id; msg->type = SCOPES_MSG_DATA; msg->target_sid = subscriber->id; msg->to_creator = to_creator; // XXX: for TikiDB integration //HAS_STATUS(scope, SCOPES_STATUS_CREATOR) || IS_WORLD_SCOPE(scope) ? 0 : 1; msg->data_len = data_len; /* copy the payload in the packet buffer */ void *data_ptr; #ifdef FRAGMENTATION_ENABLED if (to_creator) { data_ptr = (void *) ((uint8_t *) routing->buffer_ptr() + sizeof(struct scopes_msg_data)); memcpy(data_ptr, data, data_len); } else { data_ptr = (void *) ((uint8_t *) packetbuf_dataptr() + sizeof(struct scopes_msg_data)); memcpy(data_ptr, data, data_len); } #else data_ptr = (void *) ((uint8_t *) packetbuf_dataptr() + sizeof(struct scopes_msg_data)); memcpy(data_ptr, data, data_len); #endif /* set the message length */ #ifdef FRAGMENTATION_ENABLED if (to_creator) routing->buffer_setlen(sizeof(struct scopes_msg_data) + data_len); else packetbuf_set_datalen(sizeof(struct scopes_msg_data) + data_len); #else packetbuf_set_datalen(sizeof(struct scopes_msg_data) + data_len); #endif /* tell the routing layer to send the packet */ routing->send(msg); #ifdef SCOPES_DEBUG LOG_L("Msg sent to routing.\n"); #endif //SCOPES_DEBUG }
int main_dice() { int money; /* 押金 */ int i; /* 亂數 */ char choice; /* 記錄選項 */ char dice[3]; /* 三個骰子的值 */ char total; /* 三個骰子的和 */ char buf[60]; if (HAS_STATUS(STATUS_COINLOCK)) { vmsg(msg_coinlock); return XEASY; } vs_bar("ㄒㄧ ㄅㄚ ㄌㄚ 下注"); outs("\n\n\n" "┌────────────────────────────────────┐\n" "│ 2倍 1. 大 2. 小 │\n" "│ 14倍 3. 三點 4. 四點 5. 五點 6. 六點 7. 七點 │\n" "│ 8倍 8. 八點 9. 九點 10. 十點 11. 十一點 12. 十二點 13. 十三點│\n" "│ 14倍 14. 十四點 15. 十五點 16. 十六點 17. 十七點 18. 十八點 │\n" "│216倍 19. 一一一 20. 二二二 21. 三三三 22. 四四四 23. 五五五 24. 六六六│\n" "└────────────────────────────────────┘\n"); #if 0 /* 擲骰子每 216 次各總數出現的次數機率 */ ┌──┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ │總數│3 │4 │5 │6 │7 │8 │9 │10│11│12│13│14│15│16│17│18│ ├──┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ │次數│1 │3 │6 │10│15│21│25│27│27│25│21│15│10│6 │3 │1 │ / 216 次 └──┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ #endif out_song(); while (1) { vget(2, 0, "請問要下注多少呢?(1 ~ 50000) ", buf, 6, DOECHO); money = atoi(buf); if (money < 1 || money > 50000 || money > cuser.money) break; /* 離開賭場 */ vget(12, 0, "要押哪一項呢?(請輸入號碼) ", buf, 3, DOECHO); choice = atoi(buf); if (choice < 1 || choice > 24) break; /* 離開賭場 */ outs("\n按任一鍵擲出骰子 \033[5m....\033[m\n"); igetch(); /* 決定三個骰子點數 */ total = 0; for (i = 0; i < 3; i++) { dice[i] = rnd(6) + 1; total += dice[i]; } /* 處理結果 */ if ((choice == 1 && total > 10) || (choice == 2 && total <= 10)) /* 處理大小 */ { sprintf(buf, "中了!得到2倍獎金 %d 元", money * 2); addmoney(money); } else if (choice <= 18 && total == choice) /* 處理總和 */ { if (choice >= 8 && choice <= 13) { sprintf(buf, "中了!得到8倍獎金 %d 元", money * 8); addmoney(money * 7); } else { sprintf(buf, "中了!得到14倍獎金 %d 元", money * 14); addmoney(money * 13); } } else if ((choice - 18) == dice[0] && (dice[0] == dice[1]) && (dice[1] == dice[2]))/* 處理三個一樣 */ { sprintf(buf, "中了!得到216倍獎金 %d 元", money * 216); addmoney(money * 215); } else /* 處理沒中 */ { strcpy(buf, "很可惜沒有押中!"); cuser.money -= money; } /* 印出骰子結果 */ outs("╭────╮╭────╮╭────╮\n"); for (i = 0; i < 3; i++) { prints("│%s││%s││%s│\n", pic[dice[0] - 1][i], pic[dice[1] - 1][i], pic[dice[2] - 1][i]); } outs("╰────╯╰────╯╰────╯\n\n"); out_song(); vmsg(buf); } return 0; }