/* * Timesynch functionality */ static PT_THREAD(timesynch(struct psock *p)) { PSOCK_BEGIN(p); printf("TIME: %d\n",clock_time()); static TimesynchSRMsg time_pkt; memset(&time_pkt,0,sizeof(time_pkt)); PSOCK_WAIT_UNTIL(p,PSOCK_NEWDATA(p)); if(PSOCK_NEWDATA(p)){ clock_time_t t2 = clock_time(); PSOCK_READBUF(p); memcpy(&time_pkt,buffer,sizeof(time_pkt)); time_pkt.t1 = time_pkt.t1; time_pkt.t2 = t2; time_pkt.t3 = clock_time(); printf("Clock print: %u\n",clock_time()); PSOCK_SEND(p,&time_pkt,sizeof(time_pkt)); printf("Clock print: %u\n",clock_time()); printf("T1: %u\n",time_pkt.t1); printf("T2: %u\n",time_pkt.t2); printf("T3: %u\n",time_pkt.t3); } else { printf("Timed out!\n"); PSOCK_CLOSE_EXIT(p); } state = 4; PSOCK_END(p); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(create_test_session(struct psock *p)) { /* * A protosocket's protothread must start with a PSOCK_BEGIN(), with * the protosocket as argument. */ PSOCK_BEGIN(p); /* * Here we define all the thread local variables that we need to * utilize. */ static RequestSession request; static AcceptSession accept; PSOCK_WAIT_UNTIL(p,PSOCK_NEWDATA(p)); if(PSOCK_NEWDATA(p)){ /* * We read data from the buffer now that it has arrived. * Using memcpy we store it in our local variable. */ PSOCK_READBUF(p); memcpy(&request,buffer,sizeof(request)); TEST_AMOUNT = (int) request.NumOfPackets; UDP_SENDER_PORT = (int) request.SenderPort; UDP_RECEIVER_PORT = (int) request.RecieverPort; /* * Prints for debugging. */ printf("Type: %"PRIu32"\n",request.Type); printf("SenderPort: %"PRIu32"\n",request.SenderPort); printf("ReceiverPort: %"PRIu32"\n",request.RecieverPort); printf("SenderAddress: %08x,%x\n",request.SenderAddress,request.SenderMBZ); printf("ReceiverAddress: %08x,%x\n",request.RecieverAddress,request.RecieverMBZ); printf("StartTime: %u\n",request.StartTime.Second); accept.Accept = 0; accept.Port = request.RecieverPort; PSOCK_SEND(p, &accept, sizeof(accept)); PSOCK_SEND(p, &accept, sizeof(accept)); } else { printf("Timed out!\n"); } state = 3; PSOCK_END(p); }
/* * In uip-server we have defined the UIP_APPCALL macro to * server_handle_connection so that this funcion is uIP's application * function. This function is called whenever an uIP event occurs * (e.g. when a new connection is established, new data arrives, sent * data is acknowledged, data needs to be retransmitted, etc.). */ void server_handle_connection() { /* * The uip_conn structure has a field called "appstate" that holds * the application state of the connection. We make a pointer to * this to access it easier. */ uip_tcp_appstate_t* s = &(uip_conn->appstate); /* * If a new connection was just established, we should initialize * the protosocket in our applications' state structure. */ if (uip_connected()) { PSOCK_INIT(&s->p, s->pwmRgb, sizeof(s->pwmRgb)); } /* * Finally, we run the protosocket function that actually handles * the communication. We pass it a pointer to the application state * of the current connection. */ PSOCK_BEGIN(&s->p); while (1) { PSOCK_READBUF(&s->p); TIM4->CCR2 = s->pwmRgb[0]; TIM4->CCR3 = s->pwmRgb[1]; TIM4->CCR4 = s->pwmRgb[2]; } PSOCK_CLOSE(&s->p); PSOCK_END(&s->p); }
/* * A protosocket always requires a protothread. The protothread * contains the code that uses the protosocket. We define the * protothread here. */ static PT_THREAD(connection_setup(struct psock *p)) { /* * A protosocket's protothread must start with a PSOCK_BEGIN(), with * the protosocket as argument. */ PSOCK_BEGIN(p); printf("TIME: %d\n",clock_time()); /* * Here we define all the thread local variables that we need to * utilize. */ static ServerGreeting greet; static SetupResponseUAuth setup; static ServerStartMsg start; static int i; static int acceptedMode = 1; /* * We configure the Server-Greeting that we want to send. Setting * the accepted modes to those we accept. The following modes are * meaningful: * 1 - Unauthenticated * 2 - Authenticated * 3 - Encrypted * 0 - Do not wish to communicate. */ memset(&greet, 0, sizeof(greet)); greet.Modes = 1; /* * We generate random sequence of octects for the challenge and * salt. */ for (i = 0; i < 16; i++){ greet.Challenge[i] = rand() % 16; } for (i = 0; i < 16; i++){ greet.Salt[i] = rand() % 16; } /* * Count must be a power of 2 and be at least 1024. */ //greet.Count = (1 << 12); /* * We set the MBZ octets to zero. */ for (i = 0; i < 12; i++){ greet.MBZ[i] = 0; } /* * Using PSOCK_SEND() we send the Server-Greeting to the connected * client. */ PSOCK_SEND(p, &greet, sizeof(greet)); /* * We wait until we receive a server greeting from the server. * PSOCK_NEWDATA(p) returns 1 when new data has arrived in * the protosocket. */ PSOCK_WAIT_UNTIL(p,PSOCK_NEWDATA(p)); if(PSOCK_NEWDATA(p)){ /* * We read data from the buffer now that it has arrived. * Using memcpy we store it in our local variable. */ PSOCK_READBUF(p); memcpy(&setup,buffer,sizeof(setup)); if(setup.Modes != acceptedMode){ printf("Client did not match our modes!\n"); PSOCK_CLOSE_EXIT(p); } else{ /* * We have agreed upon the mode. Now we send the Server-Start * message. */ memset(&start,0,sizeof(start)); /* * We set the MBZ octets to zero. */ for (i = 0; i < 15; i++){ start.MBZ1[i] = 0; } for (i = 0; i < 8; i++){ start.MBZ2[i] = 0; } /* * The accept field is set to zero if the server wishes to continue * communicating. A non-zero value is defined as in RFC 4656. */ start.Accept = 0; /* * Timestamp is set to the time the Server started. */ double temp; start.timestamp.Second = clock_seconds(); temp = (double) clock_time()/CLOCK_SECOND - start.timestamp.Second; start.timestamp.Fraction = temp*1000; /* * Using PSOCK_SEND() we send the Server-Start to the connected * client. */ PSOCK_SEND(p, &start, sizeof(start)); printf("Client agreed to mode: %d\n",setup.Modes); } } else { printf("Timed out!\n"); } state = 2; PSOCK_END(p); }
static PT_THREAD(handle_request(connection_state_t* conn_state)) { static int error; const char* content_len; PSOCK_BEGIN(&(conn_state->sin)); content_len = NULL; error = HTTP_NO_ERROR; /*always reinit static variables due to protothreads*/ PRINTF("Request--->\n"); //read method PSOCK_READTO(&(conn_state->sin), ' '); if (!is_method_handled(conn_state, conn_state->inputbuf)) { /*method not handled*/ http_set_status(&conn_state->response, SERVICE_UNAVAILABLE_503); conn_state->state = STATE_OUTPUT; } else { /*read until the end of url*/ PSOCK_READTO(&(conn_state->sin), ' '); /*-1 is needed since it also includes space char*/ if (conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] != ' ' ) { error = HTTP_URL_TOO_LONG; } conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0; PRINTF("Read URL:%s\n", conn_state->inputbuf); if (error == HTTP_NO_ERROR) { error = parse_url(conn_state, conn_state->inputbuf); } if (error != HTTP_NO_ERROR) { if (error == HTTP_URL_TOO_LONG) { http_set_status(&conn_state->response, REQUEST_URI_TOO_LONG_414); } else { http_set_status(&conn_state->response, BAD_REQUEST_400); } conn_state->state = STATE_OUTPUT; } else { /*read until the end of HTTP version - not used yet*/ PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR); PRINTF("After URL:%s\n", conn_state->inputbuf); /*FIXME : PSOCK_READTO takes just a single delimiter so I read till the end of line but now it may not fit in the buffer. If PSOCK_READTO would take two delimiters, we would have read until : and <CR> so it would not be blocked.*/ /*Read the headers and store the necessary ones*/ do { /*read the next line*/ PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR); conn_state->inputbuf[ PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0; /*if headers finished then stop the infinite loop*/ if (conn_state->inputbuf[0] == CARRIAGE_RETURN_CHAR || conn_state->inputbuf[0] == 0) { PRINTF("Finished Headers!\n\n"); break; } parse_header(conn_state, conn_state->inputbuf); } while(1); content_len = get_header(conn_state->request.headers, HTTP_HEADER_NAME_CONTENT_LENGTH); if (content_len) { conn_state->request.payload_len = atoi(content_len); PRINTF("Post Data Size string: %s int: %d\n", content_len, conn_state->request.payload_len); } if (conn_state->request.payload_len) { static uint16_t read_bytes = 0; /*init the static variable again*/ read_bytes = 0; conn_state->request.payload = allocate_buffer(conn_state->request.payload_len + 1); if (conn_state->request.payload) { do { PSOCK_READBUF(&(conn_state->sin)); /*null terminate the buffer in case it is a string.*/ conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin))] = 0; memcpy(conn_state->request.payload + read_bytes, conn_state->inputbuf, PSOCK_DATALEN(&(conn_state->sin))); read_bytes += PSOCK_DATALEN(&(conn_state->sin)); } while (read_bytes < conn_state->request.payload_len); conn_state->request.payload[read_bytes++] = 0; PRINTF("PostData => %s \n", conn_state->request.payload); } else { error = HTTP_MEMORY_ALLOC_ERR; } } if (error == HTTP_NO_ERROR) { if (service_cbk) { service_cbk(&conn_state->request, &conn_state->response); } } else { PRINTF("Error:%d\n",error); http_set_status(&conn_state->response, INTERNAL_SERVER_ERROR_500); } conn_state->state = STATE_OUTPUT; } } PSOCK_END(&(conn_state->sin)); }