nes-proj/project/Giomba/status.c
giomba d7e3b0a70e [product + cart] single product / multiple cart
now when you press a button on the cart you notify the product launchpad about your presence;
then the product launchpad always sends packets to you;
this allows the use of multiple carts with only a single product
2019-05-08 18:47:58 +02:00

145 lines
5.3 KiB
C

#include "status.h"
#define MAX_PRODUCT 20
enum CartStatus status;
struct etimer broadcast_timer;
linkaddr_t assigner_address;
linkaddr_t cash_address;
uint32_t customer_id = 1234;
uint8_t nprod = 0;
uint8_t remaining = 0;
uint16_t totalPrice = 0;
uint8_t nprod_index = 0; //variable used to keep track of the index of the product to be sent
product_t list[MAX_PRODUCT];
void s_not_associated(process_event_t ev, process_data_t data) {
if (ev == PROCESS_EVENT_TIMER) {
/* at time expiration, send broadcast message to request association with assigner */
if (etimer_expired(&broadcast_timer)) {
printf("[I] Sending association request msg\n");
msg m;
m.msg_type = ASSOCIATION_REQUEST_MSG;
net_send(&m, sizeof(m), NULL);
etimer_reset(&broadcast_timer);
}
}
else /* if a msg is received from network and represents an association event, then associate */
if (ev == PROCESS_EVENT_MSG && event == CART_EVENT_ASSOCIATED) {
printf("[I] Associated with Assigner\n");
assigner_address = pkt.src;
nprod = 0;
status = ASSOCIATED;
}
}
void s_associated(process_event_t ev, process_data_t data) {
if (ev == PROCESS_EVENT_TIMER) {
/* now send battery level */
printf("[I] Sending battery level\n");
struct battery_msg m;
m.msg_type = BATTERY_STATUS_MSG;
m.battery_percentage = 77;
net_send(&m, sizeof(m), &assigner_address);
etimer_reset(&broadcast_timer);
}
if (ev == PROCESS_EVENT_MSG && event == CART_EVENT_ASSIGNED) {
/* cart has been assigned to a new customer */
customer_id = ((assign_msg*)pkt.data)->customer_id;
printf("[I] Assigned to customer id %d\n", (int)customer_id);
status = SHOPPING;
}
}
void s_shopping(process_event_t ev, process_data_t data) {
if (ev == PROCESS_EVENT_MSG) {
if (event == CART_EVENT_NEW_PRODUCT) {
/* add product to list */
if (nprod < MAX_PRODUCT) {
item_msg* m = (item_msg*)pkt.data;
memcpy(&list[nprod], &m->p, sizeof(product_t));
printf("[I] Adding item #%d, id %d, price %d to cart\n", nprod, (int)list[nprod].product_id, (int)list[nprod].price);
totalPrice+=list[nprod].price;
nprod++;
} else {
printf("[W] Too many products. Dropping.\n");
}
}
if (event == CART_EVENT_CASH_OUT) {
/* answer the cash if you are the one with that customer_id */
if (((cash_out_msg*)pkt.data)->customer_id == customer_id) {
printf("[I] It's me! I'm cashing out :-)\n");
cash_address = pkt.src;
basket_msg m;
m.msg_type = BASKET_MSG;
m.n_products = nprod;
m.customer_id = customer_id; /* this is needed to handle multiple customers at the cash register */
net_send(&m, sizeof(m), &cash_address);
status = CASH_OUT_WAIT4ACK;
}
else {
printf("[I] I am customer id %d; customer id %d is cashing out nearby\n", (int)customer_id, (int)((cash_out_msg*)pkt.data)->customer_id );
}
}
}
if (ev == button_hal_release_event) { /* any button will do */
/* ask product to send items to me */
msg m;
m.msg_type = START_SHOPPING_MSG;
net_send(&m, sizeof(m), NULL);
}
}
void s_cash_out_wait4ack(process_event_t ev, process_data_t data) {
/* Just wait for cash ack */
if (event == CART_EVENT_CASH_OUT_ACK) {
printf("[I] Acknoweledgment received from cash. Total price is %d. Now I'll send the list.\n", totalPrice);
remaining = nprod;
status = CASH_OUT_SEND_LIST;
/* this wakes up the process that otherwise would wait indefinitely for an event that will never occur */
process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL);
}
}
void s_cash_out_send_list(process_event_t ev, process_data_t data) {
/* Send list, then go back to initial state */
printf("[I] Remaining %d products\n", (int)remaining);
product_partial_list_msg m;
m.msg_type = PRODUCT_PARTIAL_LIST_MSG;
m.customer_id = customer_id;
m.array_len = (remaining < PRODUCT_ARRAY_MAX_LEN) ? remaining : PRODUCT_ARRAY_MAX_LEN;
uint8_t done = nprod - remaining;
for (uint8_t i = 0; i < ((remaining < PRODUCT_ARRAY_MAX_LEN) ? remaining : PRODUCT_ARRAY_MAX_LEN); ++i) {
printf("[I] Adding %d to the list\n", (int)i);
m.p[i] = list[done + i];
}
printf("[I] sending list right now\n");
net_send(&m, sizeof(m), &cash_address);
remaining -= (remaining < PRODUCT_ARRAY_MAX_LEN) ? remaining : PRODUCT_ARRAY_MAX_LEN;
printf("[I] and now remaining %d products\n", (int)remaining);
if (remaining == 0) {
printf("[I] it is the end, so now I reset the state\n");
/* reset everything */
nprod = 0;
nprod_index = 0;
customer_id = 1234;
totalPrice = 0;
memset(&cash_address, 0, sizeof(cash_address));
printf("[I] List END. Go back to ASSOCIATED status\n");
etimer_restart(&broadcast_timer);
// status = ASSOCIATED; // TODO DEBUG
status = SHOPPING;
}
}