static void MainL() { log_clear(PRIMARY_LOG_FILENAME); log_text(PRIMARY_LOG_FILENAME, "initializing"); logg("value is %d", 555); log_ctx(PRIMARY_LOG_FILENAME, "context test"); // Note that if our program does not run for at least five seconds // or so, the S60 auto launch mechanism will consider that an error, // and this may result in some error dialog popping up. We use // WaitWhile() to avoid that sort of thing where an intrusive error // report is not called for. Calling WaitWhile will hopefully also // ensure that the system is somewhat up and running even right after // boot, so that there are no problems with querying the installed // apps information or anything like that. WaitWhile(); RFs fs; User::LeaveIfError(fs.Connect()); CleanupClosePushL(fs); TBool magicFileExists = MagicFileExists(fs); if (!magicFileExists) { TBool isAppInstalled = IsAppInstalledL(); if (isAppInstalled) { MainLoopL(); } else { logt("program to launch not installed"); } } else { logt("magic file exists"); } CleanupStack::PopAndDestroy(); // fs }
bool Storage::TerminalCommandHandler(string commandName, vector<string> commandArgs){ if(commandName == "save"){ int slotNum = atoi(commandArgs[0].c_str()); int len = strlen(commandArgs[1].c_str()); if(len % 4 != 0) len = len +4 - (len%4); char data[len]; strcpy(data, commandArgs[1].c_str()); BufferedWrite((unsigned char*)data, slotNum, len); logt("STORAGE", "len: %d is saved in %d", len, slotNum); } else if (commandName == "load"){ int slotNum = atoi(commandArgs[0].c_str()); int len = atoi(commandArgs[1].c_str()); if(len % 4 != 0) len = len +4 - (len%4); u8 dest_data[len]; BufferedRead(dest_data, slotNum, len); logt("STORAGE", "%s (%d) has been loaded from %d", dest_data, len, slotNum); } else { return false; } return true; }
void ScanController::SetScanDutyCycle(u16 interval, u16 window){ u32 err; if (scanningState != SCAN_STATE_OFF) { err = sd_ble_gap_scan_stop(); if(err != NRF_SUCCESS){ //We'll just ignore NRF_ERROR_INVALID_STATE and hope that scanning is stopped } logt("C", "Scanning stopped"); } if(interval != 0){ currentScanParams.interval = interval; currentScanParams.window = window; err = sd_ble_gap_scan_start(¤tScanParams); if(err == NRF_SUCCESS){ logt("C", "Scanning started"); } else { //Ignore all errors, scanning could not be started scanningState = SCAN_STATE_OFF; } } }
int sendcontent(char *path[], FILE *newfp) { FILE *file; int fd; size_t f_size; size_t wbytes; char *buffer = malloc(sizeof(char) * SIZE); memset(buffer,0, SIZE); printf("File path: %s\n",path[0]); if(access(*path,F_OK)==0) { file = fopen(path[0], "r"); if (file) { while((f_size= fread(buffer,1,SIZE,file)) > 0) // while((f_size=read(file, wbytes=fwrite(buffer,1,f_size,newfp); } else { logt(level,"Error Opening File while sending content\n"); // perror("Error Opening File"); } fclose(file); } else logt(level,"Error accessing path while sending content\n"); //perror(NULL); free(buffer); //close(newfp); return 0; }
int startserver(int port) { int sockfd; struct sockaddr_in serv_addr; memset(&serv_addr, '0', sizeof(serv_addr)); sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd==ERROR) { logt(level,"Socket Creation Error\n"); //perror("Socket Creation Error"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); int bindreturn=bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if(bindreturn==ERROR) { logt(level,"Bind Error\n"); //perror(NULL); exit(EXIT_FAILURE); } int listenreturn=listen(sockfd, BACKLOG); if(listenreturn==ERROR) { logt(level,"Listen Error\n"); //perror("Listen Error:"); exit(EXIT_FAILURE); } return sockfd; }
void Storage::PstorageEventHandler(pstorage_handle_t* handle, u8 opCode, u32 result, u8* data, u32 dataLength) { logt("STORAGE", "Event: %u, result:%d, len:%d", opCode, result, dataLength); if(result != NRF_SUCCESS) logt("STORAGE", "%s", Logger::getInstance().getPstorageStatusErrorString(opCode)); //if it 's a clear, we do the write if(opCode == PSTORAGE_CLEAR_OP_CODE && result == NRF_SUCCESS) { taskitem* task = (taskitem*)Storage::getInstance().taskQueue->PeekNext().data; pstorage_store(&Storage::getInstance().block_handles[task->storageBlock], task->data, task->dataLength, 0); } //If its a write or a read, we drop the last item and execute the next one else if((opCode == PSTORAGE_STORE_OP_CODE || opCode == PSTORAGE_LOAD_OP_CODE) && result == NRF_SUCCESS) { //Remove item from queue because it was successful taskitem* task = (taskitem*)Storage::getInstance().taskQueue->GetNext().data; //Notify callback if(task->operation == OPERATION_READ) { task->callback->ConfigurationLoadedHandler(); } else if(task->operation == OPERATION_WRITE) {}; Storage::getInstance().bufferedOperationInProgress = false; Storage::getInstance().ProcessQueue(); } else if(result != NRF_SUCCESS) { Storage::getInstance().bufferedOperationInProgress = false; Storage::getInstance().ProcessQueue(); } }
void Connection::StartHandshake(void) { if (this->handshakeDone) { logt("HANDSHAKE", "Handshake for connId:%d is already finished", connectionId); return; } logt("HANDSHAKE", "############ Handshake starting ###############"); //After the Handles have been discovered, we start the Handshake connPacketClusterWelcome packet; packet.header.messageType = MESSAGE_TYPE_CLUSTER_WELCOME; packet.header.sender = node->persistentConfig.nodeId; packet.header.receiver = NODE_ID_HOPS_BASE + 1; //Node id is unknown, but this allows us to send the packet only 1 hop packet.payload.clusterId = node->clusterId; packet.payload.clusterSize = node->clusterSize; packet.payload.meshWriteHandle = GATTController::getMeshWriteHandle(); //Now we set the hop counter to the closest sink //If we are sink ourself, we set it to 1, otherwise we use our //shortest path to reach a sink and increment it by one. //If there is no known sink, we set it to 0. packet.payload.hopsToSink = connectionManager->GetHopsToShortestSink(this); logt("HANDSHAKE", "OUT => conn(%d) CLUSTER_WELCOME, cID:%d, cSize:%d", connectionId, packet.payload.clusterId, packet.payload.clusterSize); connectionManager->SendMessage(this, (u8*) &packet, SIZEOF_CONN_PACKET_CLUSTER_WELCOME, true); }
//Is called whenever a connection had been established and is now disconnected //due to a timeout, deliberate disconnection by the localhost, remote, etc,... void ConnectionManager::DisconnectionHandler(ble_evt_t* bleEvent) { ConnectionManager* cm = ConnectionManager::getInstance(); Connection* connection = cm->GetConnectionFromHandle(bleEvent->evt.gap_evt.conn_handle); if(connection == NULL) return; //Save disconnction reason connection->disconnectionReason = bleEvent->evt.gap_evt.params.disconnected.reason; //LOG disconnection reason Logger::getInstance().logError(Logger::errorTypes::HCI_ERROR, bleEvent->evt.gap_evt.params.disconnected.reason, cm->node->appTimerMs); logt("CM", "Connection %u to %u DISCONNECTED", connection->connectionId, connection->partnerId); //Check if the connection should be sustained (If it's been handshaked for more than 10 seconds and ran into a timeout) if( cm->node->appTimerMs - connection->connectionHandshakedTimestamp > 10 * 1000 && bleEvent->evt.gap_evt.params.disconnected.reason == BLE_HCI_CONNECTION_TIMEOUT && cm->node->currentDiscoveryState != discoveryState::HANDSHAKE && cm->node->currentDiscoveryState != discoveryState::REESTABLISHING_CONNECTION ){ logt("CM", "Connection should be sustained"); //TODO: implement /*connection->connectionState = Connection::REESTABLISHING; cm->node->ChangeState(discoveryState::REESTABLISHING_CONNECTION); //We assume the same role as before the connection loss if(connection->direction == Connection::ConnectionDirection::CONNECTION_DIRECTION_IN){ //We advertise AdvertisingController::SetAdvertisingState(advState::ADV_STATE_HIGH); } else { //We try to initiate the connection GAPController::connectToPeripheral(&connection->partnerAddress, Config->meshExtendedConnectionTimeout); }*/ } if (connection->direction == Connection::CONNECTION_DIRECTION_IN) cm->freeInConnections++; else cm->freeOutConnections++; //If this was the pending connection, we clear it if(cm->pendingConnection == connection) cm->pendingConnection = NULL; //Notify the connection itself connection->DisconnectionHandler(bleEvent); //Notify the callback of the disconnection (The Node probably) cm->connectionManagerCallback->DisconnectionHandler(bleEvent); //Reset connection variables connection->ResetValues(); }
void RSSIModule::ConnectionPacketReceivedEventHandler(connectionPacket* inPacket, Connection* connection, connPacketHeader* packetHeader, u16 dataLength) { //Must call superclass for handling Module::ConnectionPacketReceivedEventHandler(inPacket, connection, packetHeader, dataLength); connPacketModule* packet = (connPacketModule*) packetHeader; switch(packetHeader->messageType) { case MESSAGE_TYPE_MODULE_TRIGGER_ACTION: //Check if our module is meant and we should trigger an action if(packet->moduleId == moduleId) { switch(packet->actionType) { case RSSIModuleTriggerActionMessages::TRIGGER_PING: //Send PING_RESPONSE connPacketModule outPacket; outPacket.header.messageType = MESSAGE_TYPE_MODULE_ACTION_RESPONSE; outPacket.header.sender = node->persistentConfig.nodeId; outPacket.header.receiver = packetHeader->sender; outPacket.moduleId = moduleId; outPacket.actionType = RSSIModuleActionResponseMessages::PING_RESPONSE; outPacket.data[0] = packet->data[0]; outPacket.data[1] = packet->data[0]; cm->SendMessageToReceiver(NULL, (u8*)&outPacket, SIZEOF_CONN_PACKET_MODULE + 2, true); update_led_colour(); break; default: logt("PINGMOD", "RSSIModuleTriggerActionMessages::TRIGGER_PING: Unknown action: %d", packet->actionType); break; } } break; case MESSAGE_TYPE_MODULE_ACTION_RESPONSE: //Check if our module is meant and we should trigger an action if(packet->moduleId == moduleId) { switch(packet->actionType) { case RSSIModuleActionResponseMessages::PING_RESPONSE: break; default: logt("PINGMOD", "MESSAGE_TYPE_MODULE_ACTION_RESPONSE: Unknown action: %d", packet->actionType); break; } } break; } }
int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow w; int errCode = cl2GlobalInit(); if (errCode) { logt("global init failed"); return 1; } logg("compiled against Qt %s", QT_VERSION_STR); logg("running with Qt %s", qVersion()); GError* localError = NULL; kr_Controller* controller = kr_Controller_new(&localError); if (!controller) { logt("controller init failed"); gx_txtlog_error_free(localError); return 2; } if (!kr_Controller_start(controller, &localError)) { logt("controller start failed"); gx_txtlog_error_free(localError); return 3; } guilog(__APP_NAME__); guilogf("variant %s", __VARIANT_NAME__); guilogf("version %s", __VERSION_STRING__); #ifdef __CERT_NAME__ guilogf("capas %s", __CERT_NAME__); #endif guilogf("compiled against Qt %s", QT_VERSION_STR); guilogf("running with Qt %s", qVersion()); guilog("Welcome."); w.show(); // This invokation actually runs the controller in an event loop. try { errCode = qApp->exec(); logg("qApp->exec() returned with %d", errCode); } catch (const std::exception &ex) { logg("Qt error exception: %s", ex.what()); return 4; } kr_Controller_destroy(controller); // Deletes application context. cl2GlobalCleanup(); return 0; }
// Orderly shutdown. extern "C" void ShutdownApplication() { logt("ShutdownApplication"); if (globalLoop) { globalLoop->AsyncStop(); } else { logt("error, no scheduler"); ExitApplication(); } }
/*######## HANDLER ###################################*/ void Connection::ConnectionSuccessfulHandler(ble_evt_t* bleEvent) { this->handshakeStarted = node->appTimerMs; if (direction == CONNECTION_DIRECTION_IN) logt("CONN", "Incoming connection %d connected", connectionId); else logt("CONN", "Outgoing connection %d connected", connectionId); this->connectionHandle = bleEvent->evt.gap_evt.conn_handle; this->isConnected = true; }
void PingModule::ConnectionPacketReceivedEventHandler(connectionPacket* inPacket, Connection* connection, connPacketHeader* packetHeader, u16 dataLength) { //Must call superclass for handling Module::ConnectionPacketReceivedEventHandler(inPacket, connection, packetHeader, dataLength); //Filter trigger_action messages if(packetHeader->messageType == MESSAGE_TYPE_MODULE_TRIGGER_ACTION){ connPacketModuleAction* packet = (connPacketModuleAction*)packetHeader; //Check if our module is meant and we should trigger an action if(packet->moduleId == moduleId){ //It's a ping message if(packet->actionType == PingModuleTriggerActionMessages::TRIGGER_PING){ //Inform the user logt("PINGMOD", "Ping request received with data: %d", packet->data[0]); //Send PING_RESPONSE connPacketModuleAction outPacket; outPacket.header.messageType = MESSAGE_TYPE_MODULE_ACTION_RESPONSE; outPacket.header.sender = node->persistentConfig.nodeId; outPacket.header.receiver = packetHeader->sender; outPacket.moduleId = moduleId; outPacket.actionType = PingModuleActionResponseMessages::PING_RESPONSE; outPacket.data[0] = packet->data[0]; outPacket.data[1] = 111; cm->SendMessageToReceiver(NULL, (u8*)&outPacket, SIZEOF_CONN_PACKET_MODULE_ACTION + 2, true); } } } //Parse Module action_response messages if(packetHeader->messageType == MESSAGE_TYPE_MODULE_ACTION_RESPONSE){ connPacketModuleAction* packet = (connPacketModuleAction*)packetHeader; //Check if our module is meant and we should trigger an action if(packet->moduleId == moduleId) { //Somebody reported its connections back if(packet->actionType == PingModuleActionResponseMessages::PING_RESPONSE){ logt("PINGMOD", "Ping came back from %u with data %d, %d", packet->header.sender, packet->data[0], packet->data[1]); } } } }
// Immediate process exit. extern "C" void ExitApplication() { logt("ExitApplication"); // This should make sure that the process gets killed, assuming it // is the main process that calls this. User::Exit(KErrGeneral); }
sizedData PacketQueue::PeekNext() { u32 err = sd_mutex_acquire(&queueMutex); if (err != NRF_SUCCESS) { logt("ERROR", "THREADING ERROR"); } sizedData data; //If queue has been fully read, return empty data if (_numElements == 0) { data.length = 0; sd_mutex_release(&queueMutex); return data; } //Check if we reached the end and wrap if (readPointer[0] == 0 && writePointer < readPointer) readPointer = bufferStart; data.length = (this->readPointer[0]); data.data = this->readPointer + 1; sd_mutex_release(&queueMutex); return data; }
//Connect to a specific peripheral bool GAPController::connectToPeripheral(ble_gap_addr_t* address) { if(currentlyConnecting) return false; currentlyConnecting = true; u32 err = 0; ble_gap_scan_params_t scan_params; ble_gap_conn_params_t conn_params; scan_params.selective = 0; scan_params.active = 0; /* No active scanning */ scan_params.interval = Config->meshConnectingScanInterval; scan_params.window = Config->meshConnectingScanWindow; scan_params.timeout = Config->meshConnectingScanTimeout; conn_params.min_conn_interval = Config->meshMinConnectionInterval; conn_params.max_conn_interval = Config->meshMaxConnectionInterval; conn_params.slave_latency = Config->meshPeripheralSlaveLatency; conn_params.conn_sup_timeout = Config->meshConnectionSupervisionTimeout; //Connect to the peripheral err = sd_ble_gap_connect(address, &scan_params, &conn_params); APP_ERROR_CHECK(err); //Set scan state off. Connecting uses scan itself and deactivates the scan procedure ScanController::scanningState = SCAN_STATE_OFF; logt("CONN", "pairing"); return true; }
//When a connection changes to encrypted void ConnectionManager::ConnectionEncryptedHandler(ble_evt_t* bleEvent) { ConnectionManager* cm = ConnectionManager::getInstance(); Connection* c = cm->GetConnectionFromHandle(bleEvent->evt.gap_evt.conn_handle); logt("CM", "Connection id %u is now encrypted", c->connectionId); c->encryptionState = Connection::EncryptionState::ENCRYPTED; //We are peripheral if(c->direction == Connection::CONNECTION_DIRECTION_IN) { if(!cm->doHandshake){ c->connectionState = Connection::ConnectionState::HANDSHAKE_DONE; } } //We are central else if(c->direction == Connection::CONNECTION_DIRECTION_OUT) { if(cm->doHandshake) { c->StartHandshake(); } //If the handshake is disabled, we just set the variable else { c->connectionState = Connection::ConnectionState::HANDSHAKE_DONE; } } }
//Connects to a peripheral as Master, writecharacteristichandle can be BLE_GATT_HANDLE_INVALID Connection* ConnectionManager::ConnectAsMaster(nodeID partnerId, ble_gap_addr_t* address, u16 writeCharacteristicHandle) { //Only connect when not currently in another connection or when there are no more free connections if (freeOutConnections <= 0 || pendingConnection != NULL) return NULL; Connection* connection = GetFreeOutConnection(); //Disperse connection intervals over time, maybe this leads to less connection losses u16 connectionInterval = Config->meshMinConnectionInterval + connection->connectionId; //Tell the GAP Layer to connect, it will return if it is trying or if there was an error bool status = GAPController::connectToPeripheral(address, connectionInterval, Config->meshConnectingScanTimeout); if(status){ //Get a free connection and set it as pending pendingConnection = connection; //Put address and writeHandle into the connection pendingConnection->PrepareConnection(address, writeCharacteristicHandle); char addrString[20]; Logger::getInstance().convertBufferToHexString(pendingConnection->partnerAddress.addr, 6, addrString, 20); logt("CONN", "Connect as Master to %d (%s) %s", partnerId, addrString, status ? "true" : "false"); } return pendingConnection; }
Storage::Storage() { u32 err; //Register with Terminal Terminal::AddTerminalCommandListener(this); //Initialize queue for queueing store and load tasks taskQueue = new SimpleQueue(taskBuffer, TASK_BUFFER_LENGTH); //Initialize pstorage library pstorage_module_param_t param; u8 num_blocks = STORAGE_BLOCK_NUMBER; bufferedOperationInProgress = false; param.block_size = STORAGE_BLOCK_SIZE; //Multiple of 4 and divisor of page size (pagesize is usually 1024) in case total size is bigger than page size param.block_count = num_blocks; param.cb = PstorageEventHandler; err = pstorage_init(); APP_ERROR_CHECK(err); //Register a number of blocks if (pstorage_register(¶m, &handle) != NRF_SUCCESS){ logt("STORAGE", "Could not register storage"); } for (u32 i = 0; i < num_blocks; ++i){ pstorage_block_identifier_get(&handle, i, &block_handles[i]); } }
//If we wanted to connect but our connection timed out (only outgoing connections) void Node::ConnectionTimeoutHandler(ble_evt_t* bleEvent) { logt("NODE", "Connection Timeout"); //We are leaving the discoveryState::CONNECTING state ChangeState(discoveryState::DISCOVERY); }
bool PingModule::TerminalCommandHandler(string commandName, vector<string> commandArgs) { if(commandArgs.size() >= 2 && commandArgs[1] == moduleName) { //React on commands, return true if handled, false otherwise if(commandName == "pingmod"){ //Get the id of the target node nodeID targetNodeId = atoi(commandArgs[0].c_str()); logt("PINGMOD", "Trying to ping node %u", targetNodeId); //Send ping packet to that node connPacketModule packet; packet.header.messageType = MESSAGE_TYPE_MODULE_TRIGGER_ACTION; packet.header.sender = node->persistentConfig.nodeId; packet.header.receiver = targetNodeId; packet.moduleId = moduleId; packet.actionType = PingModuleTriggerActionMessages::TRIGGER_PING; packet.data[0] = 123; cm->SendMessageToReceiver(NULL, (u8*)&packet, SIZEOF_CONN_PACKET_MODULE + 1, true); return true; } } //Must be called to allow the module to get and set the config return Module::TerminalCommandHandler(commandName, commandArgs); }
//Start to broadcast our own clusterInfo, set ackID if we want to have an ack or an ack response void Node::UpdateJoinMePacket(joinMeBufferPacket* ackCluster) { //Build a JOIN_ME packet and set it in the advertisement data advPacketPayloadJoinMeV0 packet; packet.sender = this->persistentConfig.nodeId; packet.clusterId = this->clusterId; packet.clusterSize = this->clusterSize; packet.freeInConnections = cm->freeInConnections; packet.freeOutConnections = cm->freeOutConnections; packet.ackField = 0; packet.version = 0; packet.meshWriteHandle = GATTController::getMeshWriteHandle(); if (ackCluster != NULL) { packet.clusterSize = ackCluster->payload.clusterSize; packet.ackField = ackCluster->payload.sender; ackFieldDebugCopy = ackCluster->payload.ackField; } sizedData data; data.data = (u8*) &packet; data.length = SIZEOF_ADV_PACKET_PAYLOAD_JOIN_ME_V0; logt("JOIN", "JOIN_ME updated clusterId:%u, clusterSize:%d, freeIn:%u, freeOut:%u, handle:%u, ack:%u", packet.clusterId, packet.clusterSize, packet.freeInConnections, packet.freeOutConnections, packet.meshWriteHandle, packet.ackField); //Broadcast connectable advertisement if we have a free inConnection, otherwise, we can only act as master if (!cm->inConnection->isConnected) AdvertisingController::UpdateAdvertisingData(MESSAGE_TYPE_JOIN_ME, &data, true); else AdvertisingController::UpdateAdvertisingData(MESSAGE_TYPE_JOIN_ME, &data, false); }
//Is called after a connection has ended its handshake void Node::HandshakeDoneHandler(Connection* connection) { logt("NODE", "Handshake done"); //Go back to Discovery ChangeState(discoveryState::DISCOVERY); }
//Uses the testDevice array and copies the configured values to the node settings void Node::InitWithTestDeviceSettings() { u8 found = 0; //Find our testDevice for(u32 i=0; i<NUM_TEST_DEVICES; i++){ if(testDevices[i].chipID == NRF_FICR->DEVICEID[1]) { persistentConfig.nodeId = testDevices[i].id; persistentConfig.deviceType = testDevices[i].deviceType; memcpy(&persistentConfig.nodeAddress, &testDevices[i].addr, sizeof(ble_gap_addr_t)); found = 1; break; } } if(!found) { logt("ERROR", "ChipId:%u did not match any testDevice, assigning random one...", NRF_FICR->DEVICEID[1]); //Generate a "random" id between 1 and 15001 persistentConfig.nodeId = (nodeID)NRF_FICR->DEVICEID[1] % 15000 + 1; persistentConfig.deviceType = deviceTypes::DEVICE_TYPE_STATIC; sd_ble_gap_address_get(&persistentConfig.nodeAddress); } }
//TODO: read and write can only process data that is a multiple of 4 bytes //This involves problems when the data buffer has a different size bool Storage::BufferedRead(u8* data, u32 block, u32 len) { logt("STORAGE", "Reading len:%u from block:%u", len, block); pstorage_load(data, &block_handles[block], len, 0); return true; }
/***koog (lua-func config_set) ***/ static int f_config_set(lua_State* L) /***end***/ { const char* name = luaL_checklstring(L, 1, NULL); const char* value = luaL_checklstring(L, 2, NULL); logg("config set '%s' -> '%s'", name, value); GError* setError = NULL; gboolean success = ac_DYNAMIC_SET_ERR(name, value, &setError); lua_pop(L, 2); // name, value (perhaps unnecessary) if (!success) { logt("config set failed"); return lua_raise_gerror(L, setError); } else { logt("config set ok"); } return 0; }
//Generates a new clusterID by using connectionLoss and the unique id of the node clusterID Node::GenerateClusterID(void) { //Combine connection loss and nodeId to generate a unique cluster id clusterID newId = this->persistentConfig.nodeId + this->persistentConfig.connectionLossCounter << 16; logt("NODE", "New cluster id generated %u", newId); return newId; }
void ConnectionManager::QueuePacket(Connection* connection, u8* data, u16 dataLength, bool reliable){ //Print packet as hex char stringBuffer[400]; Logger::getInstance().convertBufferToHexString(data, dataLength, stringBuffer, 400); logt("CONN_DATA", "PUT_PACKET(%d):len:%d,type:%d, hex: %s",connection->connectionId, dataLength, data[0], stringBuffer); //Save packet bool putResult = connection->packetSendQueue->Put(data, dataLength, reliable); if(!putResult) { connection->droppedPackets++; //TODO: Error handling: What should happen when the queue is full? //Currently, additional packets are dropped logt("ERROR", "Send queue is already full"); } }
//Is called as soon as a connection is connected, before the handshake void Node::ConnectionSuccessfulHandler(ble_evt_t* bleEvent) { logt("NODE", "Connection initiated"); //We are leaving the discoveryState::CONNECTING state ChangeState(discoveryState::HANDSHAKE); //TODO: manage the timeout for the handshake }
void PingModule::TimerEventHandler(u16 passedTime, u32 appTimer) { if(configuration.pingInterval != 0 && node->appTimerMs - lastPingTimer > configuration.pingInterval) { logt("PINGMOD","Timer Tick"); lastPingTimer = node->appTimerMs; } }