void net_loop(){ // main networking loop // this handles the user interface, but also repiles from couchdb switch(ui_state){ case UI_READY: serve(); handle_db_response(); break; case UI_TWILOCK: // we do not process new socket inputs, as we have to wait for the twi bus to become ready: if(twi_try_lock_bus()){ // we aquired the bus // now we have to do our access as fast as possible, as others might wait for bus access: // call command handler, who waits for access to the bus: twi_access_fun(); fputs_P(PSTR("% "), &sock_stream); sock_stream_flush(); // we again accept commands ui_state = UI_READY; twi_free_bus(); int16_t b; while((b=fgetc(&sock_stream)) != EOF){ if(b == '\n' || b == ';'){ break; } } // handle other already existing commands in the buffer //ui_handleCMD(stream_get_sock()); } break; } }
void dataAvailable(struct dummy_packet * received, uint8_t src_addr){ uint8_t i; for(i=0; i< MAX_SERVER_SOCK_NUM; i++){ // TODO: check if socket is still connected. if (data_request[i]){ stream_set_sock(i); fprintf(&sock_stream, "%u :: ", src_addr); send_result(received); } } sock_stream_flush(); }
void net_dataAvailable(struct dummy_packet * received, uint8_t src_addr){ // This function is called, everytime, a set o measurement results from // one collector board was successfully received. uint8_t i; // make a backup of currently active socket // as we have to switch socket to db socket uint8_t currSock = stream_get_sock(); // flush the active socket here? sock_stream_flush(); //puts_P(PSTR(".")); // send data to the database, if required: if(cfg.send_db){ net_sendResultToDB(received, src_addr); //puts_P(PSTR(",")); } // now send data to user intrefaces, if they requested so: for(i=0; i< MAX_SERVER_SOCK_NUM; i++){ if (data_request[i]){ if(W5100.readSnSR(i+FIRST_SERVER_SOCK) == SnSR::ESTABLISHED){ stream_set_sock(i+FIRST_SERVER_SOCK); fprintf_P(&sock_stream, PSTR("\n%u :: "), src_addr); send_result(received); sock_stream_flush(); }else{ // if no the requesting client is already disconnected, // remove him from the request list: data_request[i] = 0; } } } //puts_P(PSTR("-")); // restore socket: stream_set_sock(currSock); }
void handle_db_response(){ // Couchdb will send responses after receiving json documents. // we have to receive these in order for the w5100 receive buffer // not to overflow. // Alternatively we can just clear the whole receive queue, as // receiving the whole data will take a lot of time // // here both approaches are implemented, as it might be useful to see // the database response for debugging. In this case, the response // can be redirected to the TCP user interface (redirect_flag) uint8_t b; uint8_t index; uint8_t content_flag = 0; uint8_t redirect_flag = 0; for(index = 0; index< MAX_SERVER_SOCK_NUM; index++){ if(db_response_request[index]){ redirect_flag = 1; } } if(redirect_flag == 0){ // if no one wants to have the data, we can just clear the whole socket receive buffer. net_clear_rcv_buf(DB_CLIENT_SOCK); }else{ // if at leat one wants to have the DB response redirected, // we receive byte by byte and forward them to the apropriate user interface: // Do not need to backup the current socket here, because it is not in serve function while(recv(DB_CLIENT_SOCK, &b, 1) > 0){ content_flag = 1; for(index = 0; index< MAX_SERVER_SOCK_NUM; index++){ if(db_response_request[index]){ stream_set_sock(index+FIRST_SERVER_SOCK); fputc(b, &sock_stream); sock_stream_flush(); } } } if(!content_flag){ // no data was available: return; } } }
void ui_loop(){ switch(ui_state){ case UI_READY: serve(); break; case UI_TWILOCK: // we do not process new socket inputs, as we have to wait for the twi bus to become ready: if(twi_try_lock_bus()){ // we aquired the bus // now we have to do our access as fast as possible, as others might wait for bus access: // call command handler, who waits for access to the bus: twi_access_fun(); sock_stream_flush(); // we again accept commands ui_state = UI_READY; twi_free_bus(); // handle other already existing commands in the buffer handleCMD(stream_get_sock()); } break; } }
void net_sendResultToDB(struct dummy_packet *packets, uint8_t board_addr){ // Sends a set of 8 measurement results to the couchdb database int8_t sensor_index; int8_t comma_flag = 0; int16_t value; uint16_t len=0; PORTB &= ~(1<<PB1); PORTD &= ~(1<<PD5); if( W5100.readSnSR(DB_CLIENT_SOCK) != SnSR::ESTABLISHED ){ if(!connect_db(cfg.port+1)){ return; } } // Calculate length for the JSON header: for (sensor_index=0; sensor_index<8; sensor_index++){ if(packets[sensor_index].header.error && packets[sensor_index].header.connected){ // We do not send data, which might have an error continue; } if(packets[sensor_index].header.connected){ switch(packets[sensor_index].header.type){ case PACKET_TYPE_TSIC: len += JSON_TEMP_LEN; // length of "," or "}" at the end len++; break; case PACKET_TYPE_HYT: // There is no difference in temperature length // for HYT and TSIC. len += JSON_TEMP_LEN; len++; len += JSON_HUM_LEN; len++; break; default: break; } } } PORTB |= (1<<PB1); if(len==0){ return; } len+=JSON_PREFIX_LEN; // length of "}" at the end len++; // Now we start sending data to couchdb stream_set_sock(DB_CLIENT_SOCK); net_sendHeadToDB(len); #ifdef DEBUG printf_P(PSTR("Send Head \n\r")); #endif /* convert packet data to json format * {"type":"value","data",{"bdddsdTEMP":"ddd.dd","bdddsdHUM":"ddd.dd"}} */ fputs_P(PSTR(JSON_PREFIX), &sock_stream); #ifdef DEBUG printf_P(PSTR("Send PREFIX \n\r")); #endif comma_flag = 0; //puts_P(PSTR("+")); PORTB &= ~(1<<PB1); PORTD |= (1<<PD5); for (sensor_index=0;sensor_index<8;sensor_index++){ if(packets[sensor_index].header.error && packets[sensor_index].header.connected){ continue; } if(packets[sensor_index].header.connected){ switch(packets[sensor_index].header.type){ case PACKET_TYPE_TSIC: if(comma_flag){ fputc(',', &sock_stream); }else{ comma_flag = 1; } value = ((struct tsic_packet *)(packets))[sensor_index].temperature; fprintf_P(&sock_stream, PSTR(JSON_TEMP), JSON_OUTPUT); #ifdef DEBUG printf_P(PSTR("Send temperature \n\r")); #endif break; case PACKET_TYPE_HYT: if(comma_flag){ fputc(',', &sock_stream); }else{ comma_flag = 1; } value = ((struct hyt_packet *)(packets))[sensor_index].temperature; fprintf_P(&sock_stream, PSTR(JSON_TEMP), JSON_OUTPUT); value = ((struct hyt_packet *)(packets) )[sensor_index].humidity; fputc(',', &sock_stream); fprintf_P(&sock_stream, PSTR(JSON_HUM), JSON_OUTPUT); break; default: break; } } } fputc('}', &sock_stream); fputc('}', &sock_stream); #ifdef DEBUG printf_P(PSTR("Send finished \n\r")); #endif sock_stream_flush(); PORTB |= (1<<PB1); }