void vApplicationIdleHook(void) { static char sending=0; static char state=0; static char* sendData=NULL; OBD2HW_Header* pobd2hw; #ifdef APPLICATION_START_TIME if(xTaskGetTickCount()-ob_app_start<APPLICATION_START_TIME) { usb_stat.stat_time = ob_app_start + 2*APPLICATION_START_TIME; ob_int_mgmt.stat_time = ob_app_start + 2*APPLICATION_START_TIME + OPENBEACON_STATS_AUTO_SEND_TIME/2; return; } #endif // TODO: erforsche diesen Einfluss | nRFAPI_GetStatus()&STATUS_TX_DS if(xTaskGetTickCount()-ob_send_time > OPENBEACON_SEND_WIRELESS ) { AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_RED ); sending=0; ob_switchRXMode(); } #ifdef OPENBEACON_RECIVE_WIRELESS if( last_usb_sendmesg==NULL ) last_usb_sendmesg = pullFreeBlock(); if(sending==0 && last_usb_sendmesg!=NULL) { // Wirless Packete empfangen pobd2hw = (OBD2HW_Header*) last_usb_sendmesg->pValue; pobd2hw->length=recvBeacon( &recv_buffer ); if( pobd2hw->length>0 ) { sending=1; memcpy(last_usb_sendmesg->pValue+sizeof(OBD2HW_Header)+sizeof(Click2OBD_header)-OPENBEACON_MACSIZE, recv_buffer.payload, pobd2hw->length ); // TODO: auswerten der Daten (ggf. weiterleiten an Click) pobd2hw->type=PACKET_DATA; pobd2hw->length += sizeof(Click2OBD_header); Click2OBD_header* pclick2obd = (Click2OBD_header*) (last_usb_recvmesg->pValue+sizeof(OBD2HW_Header) ); pclick2obd->channel = ob_int_mgmt.TxChannel; pclick2obd->rate = ob_int_mgmt.TxRate; pclick2obd->power = ob_int_mgmt.TxPowerLevel; #ifdef OPENBEACON_TRANSMIT_WIRELESS_TO_USB vUSBSendPacket( last_usb_sendmesg, pobd2hw->length+sizeof(OBD2HW_Header) ); last_usb_sendmesg = NULL; #endif } } #endif #ifdef OPENBEACON_TEST_AUTO_SEND if(sending==0 && xTaskGetTickCount()-ob_send_time > OPENBEACON_SEND_WIRELESS) { if( ob_int_mgmt.test_hw_diff<255 && xTaskGetTickCount()-ob_send_time>ob_int_mgmt.test_hw_diff ) { // TODO: Testpacket einrichten HW_rxtx_Test *htestp = (HW_rxtx_Test *)send_buffer.payload; char i; for(i=0; i<OPENBEACON_MACSIZE; i++) htestp->openbeacon_smac[ i ] = 0xFF; htestp->prot_type[0] = ETHERNET_TEST_PROTOCOL_FIRST; htestp->prot_type[1] = ETHERNET_TEST_PROTOCOL_SECOND; increment(htestp->pID, 4); switch( sendBeacon( &send_buffer ) ) { case 0: sending=1; AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED_RED ); ob_send_time=xTaskGetTickCount(); break; case -1: break; } } } #endif // Sendet USB-Statistics #ifdef USB_STATS_AUTO_SEND #ifdef USB_STATS_AUTO_SEND_TIME sendUSBStat( USB_STATS_AUTO_SEND_TIME ); #else sendUSBStat( 1000 ); #endif #endif // Sendet Wirless-Statistics #ifdef OPENBEACON_STATS_AUTO_SEND #ifdef OPENBEACON_STATS_AUTO_SEND_TIME sendBeaconStat( OPENBEACON_STATS_AUTO_SEND_TIME ); #else sendBeaconStat( 1000 ); #endif #endif // Shelleingaben verarbeiten #ifdef APPLICATION_USBSHELL useShell(); #endif // verarbeiten der USB Packete ( Datenpackete ) #ifdef OPENBEACON_SEND_USB_PACKET_DATA if(last_usb_recvmesg==NULL) vUSBRecivePacket( &last_usb_recvmesg ); if(sending==0 && last_usb_recvmesg!=NULL && xTaskGetTickCount()-ob_send_time > OPENBEACON_SEND_WIRELESS) { OBD2HW_Header* pobd2hw = (OBD2HW_Header*) last_usb_recvmesg->pValue; if( pobd2hw->type==PACKET_DATA ) { Click2OBD_header* pclick2obd = (Click2OBD_header*) (last_usb_recvmesg->pValue+sizeof(OBD2HW_Header) ); ob_setChannel( pclick2obd->channel ); ob_setRate( pclick2obd->rate ); ob_setPower( pclick2obd->power ); ob_setNetID( pclick2obd->openbeacon_dmac ); // TODO: den Payload ob_data richtig festlegen memcpy(send_buffer.payload, last_usb_recvmesg->pValue+sizeof(OBD2HW_Header)+sizeof(Click2OBD_header)-OPENBEACON_MACSIZE, OPENBEACON_MAX_DATA); switch( sendBeacon( &send_buffer ) ) { case 0: sending=1; AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED_RED ); pushFreeBlock( last_usb_recvmesg ); last_usb_recvmesg=NULL; break; case -1: break; } ob_send_time=xTaskGetTickCount(); } else { pushFreeBlock( last_usb_recvmesg ); last_usb_recvmesg=NULL; } } #endif }
// //////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////// // Recv Messages. Get a message and dispatch to relevant function. bool recvMessage(void) { NETQUEUE queue; uint8_t type; while (NETrecvNet(&queue, &type) || NETrecvGame(&queue, &type)) // for all incoming messages. { bool processedMessage1 = false; bool processedMessage2 = false; if (queue.queueType == QUEUE_GAME) { syncDebug("Processing player %d, message %s", queue.index, messageTypeToString(type)); } // messages only in game. if(!ingame.localJoiningInProgress) { processedMessage1 = true; switch(type) { case GAME_DROIDINFO: //droid update info recvDroidInfo(queue); break; case NET_TEXTMSG: // simple text message recvTextMessage(queue); break; case NET_DATA_CHECK: recvDataCheck(queue); break; case NET_AITEXTMSG: //multiplayer AI text message recvTextMessageAI(queue); break; case NET_BEACONMSG: //beacon (blip) message recvBeacon(queue); break; case GAME_DROIDDISEMBARK: recvDroidDisEmbark(queue); //droid has disembarked from a Transporter break; case GAME_GIFT: // an alliance gift from one player to another. recvGift(queue); break; case GAME_LASSAT: recvLasSat(queue); break; case GAME_DEBUG_MODE: recvProcessDebugMappings(queue); break; case GAME_DEBUG_ADD_DROID: recvDroid(queue); break; case GAME_DEBUG_ADD_STRUCTURE: recvBuildFinished(queue); break; case GAME_DEBUG_ADD_FEATURE: recvMultiPlayerFeature(queue); break; case GAME_DEBUG_REMOVE_DROID: recvDestroyDroid(queue); break; case GAME_DEBUG_REMOVE_STRUCTURE: recvDestroyStructure(queue); break; case GAME_DEBUG_REMOVE_FEATURE: recvDestroyFeature(queue); break; case GAME_DEBUG_FINISH_RESEARCH: recvResearch(queue); break; default: processedMessage1 = false; break; } } // messages usable all the time processedMessage2 = true; switch(type) { case GAME_TEMPLATE: // new template recvTemplate(queue); break; case GAME_TEMPLATEDEST: // template destroy recvDestroyTemplate(queue); break; case NET_PING: // diagnostic ping msg. recvPing(queue); break; case NET_OPTIONS: recvOptions(queue); break; case NET_PLAYER_DROPPED: // remote player got disconnected { uint32_t player_id; NETbeginDecode(queue, NET_PLAYER_DROPPED); { NETuint32_t(&player_id); } NETend(); if (whosResponsible(player_id) != queue.index && queue.index != NET_HOST_ONLY) { HandleBadParam("NET_PLAYER_DROPPED given incorrect params.", player_id, queue.index); break; } debug(LOG_INFO,"** player %u has dropped!", player_id); if (NetPlay.players[player_id].allocated) { MultiPlayerLeave(player_id); // get rid of their stuff NET_InitPlayer(player_id, false); } NETsetPlayerConnectionStatus(CONNECTIONSTATUS_PLAYER_DROPPED, player_id); break; } case NET_PLAYERRESPONDING: // remote player is now playing { uint32_t player_id; resetReadyStatus(false); NETbeginDecode(queue, NET_PLAYERRESPONDING); // the player that has just responded NETuint32_t(&player_id); NETend(); if (player_id >= MAX_PLAYERS) { debug(LOG_ERROR, "Bad NET_PLAYERRESPONDING received, ID is %d", (int)player_id); break; } // This player is now with us! ingame.JoiningInProgress[player_id] = false; break; } // FIXME: the next 4 cases might not belong here --check (we got two loops for this) case NET_COLOURREQUEST: recvColourRequest(queue); break; case NET_POSITIONREQUEST: recvPositionRequest(queue); break; case NET_TEAMREQUEST: recvTeamRequest(queue); break; case NET_READY_REQUEST: recvReadyRequest(queue); // if hosting try to start the game if everyone is ready if(NetPlay.isHost && multiplayPlayersReady(false)) { startMultiplayerGame(); } break; case GAME_ALLIANCE: recvAlliance(queue, true); break; case NET_KICK: // in-game kick message { uint32_t player_id; char reason[MAX_KICK_REASON]; LOBBY_ERROR_TYPES KICK_TYPE = ERROR_NOERROR; NETbeginDecode(queue, NET_KICK); NETuint32_t(&player_id); NETstring(reason, MAX_KICK_REASON); NETenum(&KICK_TYPE); NETend(); if (player_id == NET_HOST_ONLY) { char buf[250]= {'\0'}; ssprintf(buf, "Player %d (%s : %s) tried to kick %u", (int) queue.index, NetPlay.players[queue.index].name, NetPlay.players[queue.index].IPtextAddress, player_id); NETlogEntry(buf, SYNC_FLAG, 0); debug(LOG_ERROR, "%s", buf); if (NetPlay.isHost) { NETplayerKicked((unsigned int) queue.index); } break; } else if (selectedPlayer == player_id) // we've been told to leave. { debug(LOG_ERROR, "You were kicked because %s", reason); setPlayerHasLost(true); } else { debug(LOG_NET, "Player %d was kicked: %s", player_id, reason); NETplayerKicked(player_id); } break; } case GAME_RESEARCHSTATUS: recvResearchStatus(queue); break; case GAME_STRUCTUREINFO: recvStructureInfo(queue); break; case NET_PLAYER_STATS: recvMultiStats(queue); break; case GAME_PLAYER_LEFT: recvPlayerLeft(queue); break; default: processedMessage2 = false; break; } if (processedMessage1 && processedMessage2) { debug(LOG_ERROR, "Processed %s message twice!", messageTypeToString(type)); } if (!processedMessage1 && !processedMessage2) { debug(LOG_ERROR, "Didn't handle %s message!", messageTypeToString(type)); } NETpop(queue); } return true; }