/** * \brief Routine for FIND_NEW_DEVICE * * \return void */ void CmdFindNewDevice(void) { QueueResponse((char *)"FIND-NEW-DEVICE\nPlease wait...\n"); // TODO: Generate new device address besed on table of current devices dLink newDevice = rfCreateDevice(); uint8_t Data[17] = {0x00, nRF24_HUB_addr[0], nRF24_HUB_addr[1], nRF24_HUB_addr[2], nRF24_HUB_addr[3], nRF24_HUB_addr[4], rfCMD_DISCOVER, nRF24_NET_TX_START_addr[0], nRF24_NET_TX_START_addr[1], nRF24_NET_TX_START_addr[2], (uint8_t)(newDevice->Address >> 8), (uint8_t)newDevice->Address, 0x01}; *((uint32_t *)(Data + 13)) = newDevice->Salt; nRF24_TXPacket(&hspi2, nRF24_DEVICE_CFG_addr, Data, 17); } /** * \brief Routine for PING * * \return void */ void CmdPING(void) { QueueResponse((char *)"PONG!\n"); }
void Connection::QueueTractorComponent(u8* packet, short &index, float *position, float tractor_speed, long player_id, long article_id, long effect_id, long timestamp) { ComponentPositionalUpdate update; memset(&update, 0, sizeof(update)); update.simple.GameID = article_id; if (timestamp) { update.simple.TimeStamp = timestamp; } else { update.simple.TimeStamp = GetNet7TickCount(); } update.simple.Position[0] = position[0]; update.simple.Position[1] = position[1]; update.simple.Position[2] = position[2]; update.simple.Orientation[0] = 1.0f; update.simple.Orientation[1] = 0.0f; update.simple.Orientation[2] = 0.0f; update.simple.Orientation[3] = 0.0f; update.ImpartedDecay = 9.8f; update.TractorSpeed = tractor_speed; update.TractorID = player_id; update.TractorEffectID = effect_id; QueueResponse(packet, index, ENB_OPCODE_0046_COMPONENT_POSITIONAL_UPDATE, (unsigned char *) &update, sizeof(update)); }
bool HttpServer::Connection::TryHandleResponse(InternalRequest* aRequest, InternalResponse* aResponse) { bool handledResponse = false; for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) { PendingRequest& pending = mPendingRequests[i]; if (pending.first() == aRequest) { MOZ_ASSERT(!handledResponse); MOZ_ASSERT(!pending.second()); pending.second() = aResponse; if (i != 0) { return true; } handledResponse = true; } if (handledResponse && !pending.second()) { // Shortcut if we've handled the response, and // we don't have more responses to send return true; } if (i == 0 && pending.second()) { RefPtr<InternalResponse> resp = pending.second().forget(); mPendingRequests.RemoveElementAt(0); QueueResponse(resp); --i; } } return handledResponse; }
/** * \brief Routine for CHECK_TX_STATUS and CHECK_RX_STATUS * * \param [in] Chip Selected chip, can be CHIP_Tx or CHIP_Rx * \return void */ void CmdCheckTxRxStatus(uint8_t Chip) { uint8_t Status = nRF24_GetStatus(&hspi2, Chip); char Buf[10]; sprintf(Buf, "Status: %x\n", Status); QueueResponse(Buf); }
void rfSendData(uint8_t Cmd, dLink Device, char *Parameters) { switch (Device->Type) { case rfDEVICE_TYPE_1: case rfDEVICE_TYPE_2: { int NewValue[21] = {0x00}; int readVals = sscanf(Parameters, rfCMD_DATA_MASK, &NewValue[0], &NewValue[1], &NewValue[2], &NewValue[3], &NewValue[4], &NewValue[5], &NewValue[6], &NewValue[7], &NewValue[8], &NewValue[9], &NewValue[10], &NewValue[11], &NewValue[12], &NewValue[13], &NewValue[14], &NewValue[15], &NewValue[16], &NewValue[17], &NewValue[18], &NewValue[19], &NewValue[20]); if (readVals > 0) { uint8_t Data[21] = {0x00}; for (int i = 0; i < readVals; i++) { Data[i] = (uint8_t)NewValue[i]; // dxprintf("NewValue: %03x\n", Data[i]); } // dxprintf("** Cmd: %x\n", Cmd); rfSendCommad(Cmd, Device->Address, Data, readVals, Device->Salt); } else { QueueResponse((char *)"Error: Device address not set!\n\n"); } } break; default: { char Buf[50]; sprintf(Buf, "Error: Device type %d not supported yet!\n\n", Device->Type); QueueResponse(&Buf[0]); } break; } }
/** * \brief Routine for CMD HANDLE_TX_STATUS and HANDLE_RX_STATUS * * \param [in] Chip Selected chip, can be CHIP_Tx or CHIP_Rx * \return void */ void CmdHandleTxRxStatus(uint8_t Chip) { nRF24_HandleStatus(&hspi2, Chip); uint8_t Status = nRF24_GetStatus(&hspi2, Chip); char Buf[17]; sprintf(Buf, "Done, status: %x\n", Status); QueueResponse(Buf); }
void Connection::QueueCameraControl(u8 *packet, short &index, long message, long game_id) { CameraControl data; data.Message = message; data.GameID = game_id; QueueResponse(packet, index, ENB_OPCODE_0092_CAMERA_CONTROL, (unsigned char *) &data, sizeof(data)); }
already_AddRefed<nsITransportProvider> HttpServer::Connection::HandleAcceptWebSocket(const Optional<nsAString>& aProtocol, ErrorResult& aRv) { MOZ_ASSERT(mPendingWebSocketRequest); RefPtr<InternalResponse> response = new InternalResponse(101, NS_LITERAL_CSTRING("Switching Protocols")); InternalHeaders* headers = response->Headers(); headers->Set(NS_LITERAL_CSTRING("Upgrade"), NS_LITERAL_CSTRING("websocket"), aRv); headers->Set(NS_LITERAL_CSTRING("Connection"), NS_LITERAL_CSTRING("Upgrade"), aRv); if (aProtocol.WasPassed()) { NS_ConvertUTF16toUTF8 protocol(aProtocol.Value()); nsAutoCString reqProtocols; mPendingWebSocketRequest->Headers()-> GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv); if (!ContainsToken(reqProtocols, protocol)) { // Should throw a better error here aRv.Throw(NS_ERROR_FAILURE); return nullptr; } headers->Set(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), protocol, aRv); } nsAutoCString key, hash; mPendingWebSocketRequest->Headers()-> GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Key"), key, aRv); nsresult rv = mozilla::net::CalculateWebSocketHashedSecret(key, hash); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } headers->Set(NS_LITERAL_CSTRING("Sec-WebSocket-Accept"), hash, aRv); nsAutoCString extensions, negotiatedExtensions; mPendingWebSocketRequest->Headers()-> GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions, aRv); mozilla::net::ProcessServerWebSocketExtensions(extensions, negotiatedExtensions); if (!negotiatedExtensions.IsEmpty()) { headers->Set(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), negotiatedExtensions, aRv); } RefPtr<TransportProvider> result = new TransportProvider(); mWebSocketTransportProvider = result; QueueResponse(response); return result.forget(); }
void Connection::QueueRelationship(u8* packet, short &index, long ObjectID, long Reaction, bool IsAttacking) { Relationship response; response.ObjectID = ntohl(ObjectID); response.Reaction = Reaction; response.IsAttacking = IsAttacking ? 1 : 0; //LogMessage("Sending Relationship packet\n"); QueueResponse(packet, index, ENB_OPCODE_0089_RELATIONSHIP, (unsigned char *) &response, sizeof(response)); }
void Connection::QueueStarbaseSet(u8* packet, short &index, long sector, char action, char exit_mode) { StarbaseSet starbase_set; memset(&starbase_set, 0, sizeof(starbase_set)); starbase_set.StarbaseID = sector; starbase_set.Action = action; starbase_set.ExitMode = exit_mode; QueueResponse(packet, index, ENB_OPCODE_004F_STARBASE_SET, (unsigned char *) &starbase_set, sizeof(starbase_set)); }
void HttpServer::Connection::HandleWebSocketResponse(InternalResponse* aResponse) { MOZ_ASSERT(mPendingWebSocketRequest); mState = eRequestLine; mPendingWebSocketRequest = nullptr; mInput->AsyncWait(this, 0, 0, GetCurrentThreadEventTarget()); QueueResponse(aResponse); }
void rfPingDevice(uint16_t Address) { dLink Device = rfGetDevice(Address); if (Device == NULL) { QueueResponse((char *)"Device not registered!"); return; } uint8_t Data[2] = {0x00, 0x01}; rfSendCommad(rfCMD_PING, Address, Data, 2, Device->Salt); }
void rfSaveDevices(void) { //0x4002 3C00 - 0x4002 3FFF // Unlock flash to erase and write if (rfDevices == NULL) { QueueResponse((char *)"Nothing to store\n"); return; } taskENTER_CRITICAL(); FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; while (FLASH->SR & FLASH_SR_BSY) { }; //Wait untill memory ready for erase FLASH->CR |= FLASH_CR_SER; //Erase one sector FLASH->CR |= (FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2); //Erase sector 7 FLASH->CR |= FLASH_CR_STRT; while (FLASH->SR & FLASH_SR_BSY) { }; //Wait untill memory ready FLASH->CR &= ~FLASH_CR_SER; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; //Allow flash programming while (FLASH->SR & FLASH_SR_BSY) { }; dLink Cur = rfDevices; uint32_t Address = 0x08060000; while (Cur != NULL) { if (Cur->Type == NULL) { Cur = Cur->Next; continue; } *(__IO uint32_t *)Address = ((uint32_t)Cur->Address) | ((uint32_t)Cur->Type << 16) | ((uint32_t)Cur->Config << 24); Address += 4; *(__IO uint32_t *)Address = (uint32_t)Cur->Salt; Address += 4; Cur = Cur->Next; }; while (FLASH->SR & FLASH_SR_BSY) { }; dxprintf("SR: %d\n", FLASH->SR); FLASH->CR &= ~(FLASH_CR_PG); taskEXIT_CRITICAL(); }
void Connection::QueueMessageString(u8* packet, short &index, char *msg, char color, bool log) { char buffer[512]; memset(buffer, 0, sizeof(buffer)); short length = strlen(msg) + 1; *((short *) &buffer[0]) = length; buffer[2] = color; strcpy(&buffer[3], msg); QueueResponse(packet, index, ENB_OPCODE_001D_MESSAGE_STRING, (unsigned char *) buffer, length + 3); }
void xprintf( /* Put a formatted string to the default device */ char *fmt, /* Pointer to the format string */ ... /* Optional arguments */ ) { va_list arp; char Buf[SAE_OUTPUT_DATA_LENGTH]; va_start(arp, fmt); vsnprintf(Buf, SAE_OUTPUT_DATA_LENGTH, fmt, arp); va_end(arp); QueueResponse(Buf, OUSART2); }
void rfListDevices(void) { dLink Cur = rfDevices; uint8_t cnt = 1; char Buf[100]; while (Cur != NULL) { sprintf(Buf, "%d, Device: Adr: %04x Type: %02x, Conf: %x, mA: %p, mP: %p, mN: %p\n", cnt, Cur->Address, Cur->Type, Cur->Config, Cur, Cur->Prev, Cur->Next); //sprintf(Buf, "%d, Device: Adr: 0x%x Type: 0x%x\n", cnt, Cur->Address, Cur->Type); QueueResponse(&Buf[0]); Cur = Cur->Next; cnt++; }; }
void Connection::QueueObjectCreate(u8 *packet, short &index, int game_id, float scale, short asset, int type, float h, float s, float v) { Create create; create.GameID = game_id; create.Scale = scale; create.BaseAsset = asset; create.Type = (char) type; create.HSV[0] = h; create.HSV[1] = s; create.HSV[2] = v; QueueResponse(packet, index, ENB_OPCODE_0004_CREATE, (unsigned char *) &create, sizeof(create)); }
void Connection::QueueResourceName(u8* packet, short &index, long resourceID, char *resource_name) { unsigned char aux_data[64]; memset(aux_data, 0, 64); short length = strlen(resource_name); *((long *) aux_data) = resourceID; *((short *) &aux_data[4]) = length + 4; *((short *) &aux_data[6]) = 0x1201; *((short *) &aux_data[8]) = length; strncpy((char*)&aux_data[10], resource_name, length); QueueResponse(packet, index, ENB_OPCODE_001B_AUX_DATA, aux_data, length+10); }
void rfPingAllDevices(void) { dLink Cur = rfDevices; if (Cur == NULL) { QueueResponse((char *)"Devices not found!\n"); return; } uint8_t Data[2] = {0x00, 0x01}; while (Cur != NULL) { // dxprintf("fd A: %x, P: %p, N: %p\n", Cur->Address, Cur->Prev, Cur->Next); rfSendCommad(rfCMD_PING, Cur->Address, Data, 2, Cur->Salt); osDelay(20); Cur = Cur->Next; } }
void Connection::QueueContrails(u8* packet, short &index, long player_id, bool contrails) { unsigned char aux_data[] = { 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (contrails == true) { *((long*) &aux_data[15]) = 1; } *((long *) aux_data) = player_id; QueueResponse(packet, index, ENB_OPCODE_001B_AUX_DATA, aux_data, sizeof(aux_data)); }
void xprintf( /* Put a formatted string to the default device */ char *fmt, /* Pointer to the format string */ ... /* Optional arguments */ ) { va_list arp; char Buf[SAE_OUTPUT_DATA_LENGTH]; va_start(arp, fmt); vsnprintf(Buf, SAE_OUTPUT_DATA_LENGTH, fmt, arp); va_end(arp); uint8_t i; for (i = 0; i < SAE_OUTPUT_DATA_LENGTH; i++) { if (Buf[i] == 0) { break; } } if (i == SAE_OUTPUT_DATA_LENGTH) Buf[SAE_OUTPUT_DATA_LENGTH-1] = 0; QueueResponse(Buf, OUSART1); }
//TODO: REMOVE THIS!! May interfere with cloaking void Connection::QueueProspectAUX(u8* packet, short &index, long value, int type) { switch (type) { case 0: { //non-parsemode AuxPlayer //sets prospect skill last activation time unsigned char aux_data[] = { 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x59, 0x0B, 0x00, 0x00, //always this for prospecting 0x64, 0x4C, 0x20, 0x25, //timestamp... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; *((long *) &aux_data[15]) = value; QueueResponse(packet, index, ENB_OPCODE_001B_AUX_DATA, aux_data, sizeof(aux_data)); } break; case 1: { //second type of AUX prospecting requires to be sent //diables the users cloak and advancd cloak abilities unsigned char aux_data[] = { 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF5, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //no idea what this does, but always the same for prospect. Maybe some effect? QueueResponse(packet, index, ENB_OPCODE_001B_AUX_DATA, aux_data, sizeof(aux_data)); } break; case 3: { //AuxShip Packet (most likely "disables" weapons) unsigned char aux_data[] = { 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, //inventory 0x02, 0x08, //equip inventory 0x22, 0x08, 0x00, //items 1 and 7 0x02, 0x00, 0x01, //equipitem flags 0x10, 0x20, 0x00, 0x00, //itemstats 0x02, 0x00, 0x01, //equipitem flags 0x10, 0x20, 0x00, 0x00 //itemstats }; *((long *) aux_data) = value; QueueResponse(packet, index, ENB_OPCODE_001B_AUX_DATA, aux_data, sizeof(aux_data)); } break; case 4: { //re-enables the users cloak and advancd cloak abilities unsigned char aux_data[] = { 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //no idea what this does, but always the same for prospect. Maybe some effect? QueueResponse(packet, index, ENB_OPCODE_001B_AUX_DATA, aux_data, sizeof(aux_data)); } break; } }
void Connection::QueueStart(u8* packet, short &index, long start_id) { QueueResponse(packet, index, ENB_OPCODE_0005_START, (unsigned char *) &start_id, sizeof(start_id)); }
void Connection::QueueObjectToObjectEffect(u8* packet, short &p_index, ObjectToObjectEffect *obj_effect) { unsigned char effect[128]; memset(effect,0,128); int index = 0; AddData(effect, obj_effect->Bitmask, index); AddData(effect, obj_effect->GameID, index); AddData(effect, obj_effect->TargetID, index); AddData(effect, obj_effect->EffectDescID, index); if (obj_effect->Message) { AddDataS(effect, obj_effect->Message, index); } else { AddData(effect, (char)0, index); } if (obj_effect->Bitmask & 0x01) { AddData(effect, obj_effect->EffectID, index); } if (obj_effect->Bitmask & 0x02) { if (obj_effect->TimeStamp == 0) { obj_effect->TimeStamp = GetNet7TickCount(); } AddData(effect, obj_effect->TimeStamp, index); } if (obj_effect->Bitmask & 0x04) { AddData(effect, obj_effect->Duration, index); } if (obj_effect->Bitmask & 0x08) { AddData(effect, obj_effect->TargetOffset[0], index); AddData(effect, obj_effect->TargetOffset[1], index); AddData(effect, obj_effect->TargetOffset[2], index); } if (obj_effect->Bitmask & 0x10) { AddData(effect, obj_effect->OutsideTargetRadius, index); } if (obj_effect->Bitmask & 0x20) //from here on isn't correct - packet struct in packetstructures.h is wrong... TODO: work out correct packet structure. { AddData(effect, obj_effect->unused, index); } if (obj_effect->Bitmask & 0x40) { AddData(effect, obj_effect->Scale, index); } if (obj_effect->Bitmask & 0x80) { AddData(effect, obj_effect->HSVShift[0], index); AddData(effect, obj_effect->HSVShift[1], index); AddData(effect, obj_effect->HSVShift[2], index); } if (obj_effect->Bitmask & 0x100) { AddData(effect, obj_effect->Speedup, index); } QueueResponse(packet, p_index, ENB_OPCODE_000B_OBJECT_TO_OBJECT_EFFECT, effect, index); }
/** * \brief Parse user entered command and process it * * \param [in] Data User entered command with parameters * \param [in] Length Length of command * \return void * */ void ProcessATCommand(char *Data, uint8_t Length) { char * Parameters = strchr(Data, ':'); uint8_t ParametersPos = 0x00; if (Parameters == NULL) { dxprintf("Len: %d, no params\n", Length); } else { ParametersPos = Parameters - Data; dxprintf("Len: %d, Params: %d\n", Length, ParametersPos); } int CommandProcessed = 0; /** * CMD: PING - ping myself */ if (strncmp(&Data[3], (char *)"PING", 4) == 0) { CmdPING(); CommandProcessed = 1; } /** * CMD: FIND_NEW_DEVICE or FIND - find new device. Device should be able to accept 'discover' command. */ if (strncmp(&Data[3], (char *)"FIND_NEW_DEVICE", 15) == 0 || strncmp(&Data[3], (char *)"FIND", 4) == 0) { CmdFindNewDevice(); CommandProcessed = 1; } /** * CMD: CHECK_TX_STATUS - Check current transmitter status */ if (strncmp(&Data[3], (char *)"CHECK_TX_STATUS", 15) == 0) { QueueResponse((char *)"<CHECK_TX_STATUS\n"); CmdCheckTxRxStatus(CHIP_Tx); CommandProcessed = 1; } /** * CMD: CHECK_RX_STATUS - Check current receiver status */ if (strncmp(&Data[3], (char *)"CHECK_RX_STATUS", 15) == 0) { QueueResponse((char *)"<CHECK_RX_STATUS\n"); CmdCheckTxRxStatus(CHIP_Rx); CommandProcessed = 1; } /** * CMD: HANDLE_TX_STATUS - Check and handle current transmitter status */ if (strncmp(&Data[3], (char *)"HANDLE_TX_STATUS", 16) == 0) { QueueResponse((char *)"<HANDLE_TX_STATUS\n"); CmdHandleTxRxStatus(CHIP_Tx); CommandProcessed = 1; } /** * CMD: HANDLE_RX_STATUS - Check and handle current receiver status */ if (strncmp(&Data[3], (char *)"HANDLE_RX_STATUS", 16) == 0) { QueueResponse((char *)"<HANDLE_RX_STATUS\n"); CmdHandleTxRxStatus(CHIP_Rx); CommandProcessed = 1; } /** * CMD: ADD_DEVICE - Add new device into device list. This command doesn't send any data to device. */ if (strncmp(&Data[3], (char *)"ADD_DEVICE", 10) == 0) { QueueResponse((char *)"<ADD_DEVICE\n"); rfCreateDevice(); CommandProcessed = 1; } /** * CMD: LIST_DEVICES - print loaded devices */ if (strncmp(&Data[3], (char *)"LIST_DEVICES", 12) == 0) { QueueResponse((char *)"<LIST_DEVICES\n"); rfListDevices(); CommandProcessed = 1; } /** * CMD: SAVE_DEVICES - save current devices */ if (strncmp(&Data[3], (char *)"SAVE_DEVICES", 12) == 0) { QueueResponse((char *)"<SAVE_DEVICES\n"); rfSaveDevices(); QueueResponse((char *)"<DONE\n"); CommandProcessed = 1; } /** * CMD: LOAD_DEVICES - load saved devices */ if (strncmp(&Data[3], (char *)"LOAD_DEVICES", 12) == 0) { QueueResponse((char *)"<LOAD_DEVICES\n"); rfLoadDevices(); rfListDevices(); QueueResponse((char *)"<DONE\n"); CommandProcessed = 1; } /** * CMD: PREPARE_TEST_DEVICES - generate list of dummy devices */ if (strncmp(&Data[3], (char *)"PREPARE_TEST_DEVICES", 20) == 0) { QueueResponse((char *)"<PREPARE_TEST_DEVICES\n"); rfPrepareTestDevices(); QueueResponse((char *)"<DONE\n"); CommandProcessed = 1; } /** * CMD: PING_DEVICE - ping one device */ if (strncmp(&Data[3], (char *)"PING_DEVICE", 11) == 0) { QueueResponse((char *)"***PING_DEVICE NOT IMPLEMENTED!!!***"); CommandProcessed = 1; } /** * CMD: PING_ALL_DEVICES - ping all loaded devices */ if (strncmp(&Data[3], (char *)"PING_ALL_DEVICES", 16) == 0) { QueueResponse((char *)"<PING_ALL_DEVICES\n"); rfPingAllDevices(); QueueResponse((char *)"<DONE\n"); CommandProcessed = 1; } /** * CMD: SELF_TEST - run self tests */ if (strncmp(&Data[3], (char *)"SELF_TEST", 9) == 0) { QueueResponse((char *)"***SELF_TEST NOT IMPLEMENTED!!!***"); CommandProcessed = 1; } /** * CMD: SEND_DATA - send data to given device */ if (strncmp(&Data[3], (char *)"SEND_DATA", 9) == 0) { QueueResponse((char *)"<SEND_DATA\n"); char Parameters[Length - ParametersPos + 1]; int DevAddress = 0x00; uint8_t ArgumentsLength = Length - ParametersPos - 6; char Arguments[ArgumentsLength]; strlcpy(Parameters, &Data[ParametersPos + 1], Length - ParametersPos); if (sscanf(Parameters, "%4x:%s", &DevAddress, Arguments) > 0) { dLink Device = rfGetDevice(DevAddress); if (Device == NULL) { QueueResponse((char *)">ERROR: Device with given address not linked!\n\n"); } else if (Device->Type == 0x00) { QueueResponse((char *)">ERROR: Device type not valid!\n\n"); } else { rfSendData(rfCMD_W_DATA, Device, Arguments); } } else { QueueResponse((char *)">ERROR: Device address not set!\n\n"); } CommandProcessed = 1; } if (CommandProcessed == 0) { QueueResponse((char *)">ERROR: Unknown command!\n\n"); } }