[cart + cash] partial product arrays

when you cash out, instead of sending many packets, you can aggregate multiple products in the same packet, doing an array; thus you have better power efficiency, and less delay; so both Anastasi and Marcelloni would be very proud of us
This commit is contained in:
giomba 2019-05-07 21:39:28 +02:00
parent a051841635
commit 35f5041b7f
6 changed files with 93 additions and 63 deletions

View File

@ -21,8 +21,8 @@ PROCESS_THREAD(cart_main_process, ev, data) {
/*** Variables initialization ***/ /*** Variables initialization ***/
// status = NOT_ASSOCIATED; // TODO DEBUG // status = NOT_ASSOCIATED; // TODO DEBUG
status = SHOPPING;
status = NOT_ASSOCIATED; // SHOPPING; // NOT_ASSOCIATED;
etimer_set(&broadcast_timer, 5 * CLOCK_SECOND); etimer_set(&broadcast_timer, 5 * CLOCK_SECOND);
/*** Subsystem initialization ***/ /*** Subsystem initialization ***/

View File

@ -6,7 +6,8 @@ enum CartEvent {
CART_EVENT_ASSIGNED, CART_EVENT_ASSIGNED,
CART_EVENT_CASH_OUT, CART_EVENT_CASH_OUT,
CART_EVENT_NEW_PRODUCT, CART_EVENT_NEW_PRODUCT,
CART_EVENT_CASH_OUT_ACK CART_EVENT_CASH_OUT_ACK,
CART_EVENT_CASH_OUT_PARTIAL_LIST_ACK
} event; } event;
#endif #endif

View File

@ -44,10 +44,13 @@ void net_recv(const void* data, uint16_t len, const linkaddr_t* src, const linka
process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL); process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL);
break; break;
case START_OF_LIST_PRODUCTS_MSG: case START_OF_LIST_PRODUCTS_MSG:
case PRODUCT_ACK:
event = CART_EVENT_CASH_OUT_ACK; event = CART_EVENT_CASH_OUT_ACK;
process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL); process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL);
break; break;
case PRODUCT_PARTIAL_LIST_ACK:
event = CART_EVENT_CASH_OUT_PARTIAL_LIST_ACK;
process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL);
break;
default: default:
LOG_INFO("[W] message type %d unknown\n", ((msg*)data)->msg_type); LOG_INFO("[W] message type %d unknown\n", ((msg*)data)->msg_type);
break; break;

View File

@ -8,6 +8,7 @@ linkaddr_t assigner_address;
linkaddr_t cash_address; linkaddr_t cash_address;
uint32_t customer_id = 1234; uint32_t customer_id = 1234;
uint8_t nprod = 0; uint8_t nprod = 0;
uint8_t remaining = 0;
uint16_t totalPrice = 0; uint16_t totalPrice = 0;
uint8_t nprod_index = 0; //variable used to keep track of the index of the product to be sent uint8_t nprod_index = 0; //variable used to keep track of the index of the product to be sent
product_t list[MAX_PRODUCT]; product_t list[MAX_PRODUCT];
@ -86,37 +87,52 @@ void s_shopping(process_event_t ev, process_data_t data) {
void s_cash_out_wait4ack(process_event_t ev, process_data_t data) { void s_cash_out_wait4ack(process_event_t ev, process_data_t data) {
/* Just wait for cash ack */ /* Just wait for cash ack */
if (event == CART_EVENT_CASH_OUT_ACK) { if (event == CART_EVENT_CASH_OUT_ACK) {
printf("[I] Acknoweledgment received fromc cash. Now I'll send the list.\n"); 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; status = CASH_OUT_SEND_LIST;
/* this wakes up the process that otherwise would wait indefinitely for an event that will never occurr */ /* 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); process_post(&cart_main_process, PROCESS_EVENT_MSG, NULL);
} }
} }
void s_cash_out_send_list(process_event_t ev, process_data_t data) { void s_cash_out_send_list(process_event_t ev, process_data_t data) {
/* Send list, then go back to initial state */ /* Send list, then go back to initial state */
printf("[I] Total price is %d\n", totalPrice);
if (nprod_index<nprod) { printf("[I] Remaining %d products\n", (int)remaining);
LOG_INFO("[I] Sending product %d of %d: id %d, price: %d\n", nprod_index, nprod - 1, (int)list[nprod_index].product_id, (int)list[nprod_index].price);
product_msg m;
m.msg_type = PRODUCT_MSG;
m.customer_id = customer_id;
m.product_id = list[nprod_index].product_id;
m.price = list[nprod_index].price;
net_send(&m, sizeof(m), &cash_address);
nprod_index++;
}
if (nprod_index == nprod) {
nprod = 0;
nprod_index = 0;
customer_id = 1234;
memset(&cash_address, 0, sizeof(cash_address));
printf("[I] END. Go back to ASSOCIATED status\n"); product_partial_list_msg m;
etimer_restart(&broadcast_timer); m.msg_type = PRODUCT_PARTIAL_LIST_MSG;
totalPrice = 0; m.customer_id = customer_id;
status = ASSOCIATED; 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;
}
} }

View File

@ -76,20 +76,20 @@ static void input_callback(const void* data, uint16_t len, const linkaddr_t* sou
LOG_INFO("type %d", ((msg*)data)->msg_type); LOG_INFO("type %d", ((msg*)data)->msg_type);
LOG_INFO("\n"); LOG_INFO("\n");
received_msg = (msg*) (&pkt.data); received_msg = (msg*) (&pkt.data);
//we need to receive an additional message to start the process of receiving the products because if we start receiving the products immediately //we need to receive an additional message to start the process of receiving the products because if we start receiving the products immediately
//in the case of parallel processes we wouldnt know to what client and what basket that product is assosiated with //in the case of parallel processes we wouldnt know to what client and what basket that product is associated with
if (received_msg->msg_type == BASKET_MSG) { if (received_msg->msg_type == BASKET_MSG) {
basket_msg *basket = (basket_msg*) (received_msg); basket_msg *basket = (basket_msg*) (received_msg);
uint8_t index = index_free_spot(invoices); uint8_t index = index_free_spot(invoices);
if (index != -1 ) { if (index != -1 ) {
printf("basket->n_products %d\n", basket->n_products); printf("basket->n_products %d\n", basket->n_products);
invoices[index].n_prods = basket->n_products; invoices[index].n_prods = basket->n_products;
invoices[index].total_sum = 0; invoices[index].total_sum = 0;
invoices[index].customer_id = basket->customer_id; invoices[index].customer_id = basket->customer_id;
memcpy(&invoices[index].address_basket, source_address, sizeof(linkaddr_t)); memcpy(&invoices[index].address_basket, source_address, sizeof(linkaddr_t));
msg start_sending_list; msg start_sending_list;
start_sending_list.msg_type = START_OF_LIST_PRODUCTS_MSG; start_sending_list.msg_type = START_OF_LIST_PRODUCTS_MSG;
@ -101,31 +101,40 @@ static void input_callback(const void* data, uint16_t len, const linkaddr_t* sou
NETSTACK_NETWORK.output(&(invoices[index].address_basket)); NETSTACK_NETWORK.output(&(invoices[index].address_basket));
} else } else
printf("Reached max number of customers\n"); printf("Reached max number of customers\n");
} else if (received_msg->msg_type == PRODUCT_MSG) { } else if (received_msg->msg_type == PRODUCT_PARTIAL_LIST_MSG) {
product_msg *product = (product_msg*)(received_msg); product_partial_list_msg* product_list = (product_partial_list_msg*)(received_msg);
printf("Received id: %d, price %d\n", (int)product->product_id, (int)product->price);
uint8_t index = invoice_index(product->customer_id, invoices);
if (index != -1) {
if (invoices[index].n_prods > 0) {
invoices[index].total_sum += product->price;
invoices[index].n_prods--;
//send an ack to the cart so that it knows the cassa has received the product and can send the next product
msg product_ack;
product_ack.msg_type = PRODUCT_ACK;
nullnet_buf = (uint8_t*)&product_ack;
LOG_INFO("Sending acknowledgment for the product\n "); uint8_t index = invoice_index(product_list->customer_id, invoices);
nullnet_len = sizeof(product_ack);
NETSTACK_NETWORK.output(&(invoices[index].address_basket)); printf("Receiving %d items from customer %d\n", ((int)product_list->array_len) & 0xff, (int)product_list->customer_id);
} for (uint8_t i = 0; i < product_list->array_len; ++i) {
if (invoices[index].n_prods == 0) { product_t p = product_list->p[i];
printf("Total sum for client %d is %d\n", (int)invoices[index].customer_id, (int)invoices[index].total_sum);
invoices[index].empty = 1; printf("Received id: %d, price %d\n", (int)p.product_id, (int)p.price);
}
}else if (index != -1) {
printf("Customer with that id is not associated to any basket!\n"); if (invoices[index].n_prods > 0) {
} invoices[index].total_sum += p.price;
invoices[index].n_prods--;
}
if (invoices[index].n_prods == 0) {
printf("Total sum for client %d is %d\n", (int)invoices[index].customer_id, (int)invoices[index].total_sum);
invoices[index].empty = 1;
}
} else
printf("Customer with that id is not associated to any basket!\n");
}
//send an ack to the cart so that it knows the cash register has received the partial product list and can send the next part
msg product_ack;
product_ack.msg_type = PRODUCT_PARTIAL_LIST_ACK;
nullnet_buf = (uint8_t*)&product_ack;
LOG_INFO("Sending acknowledgment for the partial product list\n ");
nullnet_len = sizeof(product_ack);
NETSTACK_NETWORK.output(&(invoices[index].address_basket));
}
} }
@ -137,7 +146,7 @@ PROCESS_THREAD(cassa_main_process, ev, data) {
serial_line_init(); serial_line_init();
//initialization of the message handler for receiving messages //initialization of the message handler for receiving messages
nullnet_set_input_callback(input_callback); nullnet_set_input_callback(input_callback);
while (true) { while (true) {
printf("Dear customer, insert your card id\n"); printf("Dear customer, insert your card id\n");
@ -146,7 +155,7 @@ PROCESS_THREAD(cassa_main_process, ev, data) {
uint32_t customer_id; uint32_t customer_id;
printf("[CASSA INFO] Customer's id: %s\n", (char*)data); printf("[CASSA INFO] Customer's id: %s\n", (char*)data);
customer_id = atoi(data); customer_id = atoi(data);
cash_out_msg m; cash_out_msg m;
m.msg_type = CASH_OUT_MSG; m.msg_type = CASH_OUT_MSG;
m.customer_id = customer_id; m.customer_id = customer_id;

View File

@ -3,6 +3,8 @@
#include "product.h" #include "product.h"
#define PRODUCT_ARRAY_MAX_LEN 5
enum message_type { enum message_type {
ASSOCIATION_REQUEST_MSG, ASSOCIATION_REQUEST_MSG,
ASSOCIATION_REPLY_MSG, ASSOCIATION_REPLY_MSG,
@ -10,10 +12,10 @@ enum message_type {
ASSIGNMENT_MSG, ASSIGNMENT_MSG,
CASH_OUT_MSG, CASH_OUT_MSG,
ITEM_MSG, /* from item to cart */ ITEM_MSG, /* from item to cart */
PRODUCT_MSG, /* from cart to cash */ PRODUCT_PARTIAL_LIST_MSG, /* from cart to cash */
BASKET_MSG, BASKET_MSG,
START_OF_LIST_PRODUCTS_MSG, START_OF_LIST_PRODUCTS_MSG,
PRODUCT_ACK //everytime the cassa receives a product message , it sends an ack to the cart so that the cart can send the next product message PRODUCT_PARTIAL_LIST_ACK /* everytime the cash register receives a product message, it sends an ack to the cart so that the cart can send the next product message */
}; };
typedef struct msg { typedef struct msg {
@ -68,14 +70,13 @@ typedef struct cash_out_msg
}cash_out_msg; }cash_out_msg;
typedef struct product_msg typedef struct product_partial_list_msg
{ {
enum message_type msg_type; enum message_type msg_type;
uint32_t customer_id; uint32_t customer_id;
uint32_t product_id; uint8_t array_len;
uint32_t price; product_t p[PRODUCT_ARRAY_MAX_LEN];
}product_partial_list_msg;
}product_msg;
#endif #endif