Пример #1
0
bool Tree_Delete(TreeNode node)
{
    bool result = false;
    _treeNode _rootNode = (_treeNode) node;

    if (_rootNode)
    {
        _treeNode currentNode = _rootNode;
        while (currentNode)
        {
            // Find the end node of a branch
            while (currentNode->ChildCount)
            {
                uint32_t childIndex;

                for (childIndex = 0; childIndex < currentNode->ChildSlots; childIndex++)
                {
                    if (currentNode->Children && currentNode->Children[childIndex])
                    {
                        currentNode = (_treeNode) currentNode->Children[childIndex];
                        childIndex = currentNode->ChildSlots + 1; // Exit 'for' loop
                    }
                }
            }

            //
            // Should be at bottom of a branch
            // (next, free the node)

            // If the currentNode has a parent, break the parent's link to the node
            if (currentNode->Parent)
            {
                _treeNode parentNode = (_treeNode) currentNode->Parent;
                parentNode->Children[currentNode->ChildID-1] = NULL;
                if (((_treeNode) currentNode->Parent)->ChildCount > 0)
                    ((_treeNode) currentNode->Parent)->ChildCount--;
                 currentNode->ChildID = 0;  // The node is no longer a child-node
            }
            // else, must be the 'root' node
            
            // Free the curentNode's name, value & 'children' array
            if (currentNode->Name)
                Flow_MemFree((void **) &currentNode->Name);
            if (currentNode->Value)
                Flow_MemFree((void **) &currentNode->Value);
            if (currentNode->Children)
                Flow_MemFree((void **) &currentNode->Children);

             // Move currentNode up to its parent before freeing this node
            _treeNode tempNode = currentNode;
            currentNode = (_treeNode) currentNode->Parent;
            Flow_MemFree((void **) &tempNode);

            // Rinse and repeat, now that we're at the new end of the old branch
        }
        result = true;
    }

    return result;
}
static void FreeCmd(FlowInterfaceCmd *cmd)
{
	if (cmd->details)
	{
		Flow_MemFree((void **)&cmd->details);
	}
	Flow_MemFree((void **)&cmd);
}
/**
 * Send an event to controller thread on reception of any message.
 * data - Pointer to received message, should be copied for future usage.
 * sendorId - Pointer to user/device ID, should be copied for future usage.
 * datasize - Received message size.
 */
static bool PostControllerEventReceivedMessage(const FlowQueue* receiveMsgQueue, const char *data, const char *sendorId, const unsigned int datasize)
{
	bool success = false;
	ControllerEvent *event = NULL;
	ReceivedMessage *receivedMsg = NULL;

	event = (ControllerEvent *)Flow_MemAlloc(sizeof(ControllerEvent));

	if (event)
	{
		event->evtType = ControllerEvent_ReceivedMessage;
		receivedMsg = (ReceivedMessage *)Flow_MemAlloc(sizeof(ReceivedMessage));

		if (receivedMsg)
		{
			//Allocate one extra byte for data, as the datasize we got from
			//FlowMessagingMessage_GetContentLength() doesn't include null terminator
			receivedMsg->data = (char *)Flow_MemAlloc(datasize + 1);
			receivedMsg->sendorId = (char *)Flow_MemAlloc(strlen(sendorId) + 1);

			if (receivedMsg->data && receivedMsg->sendorId)
			{
				strncpy(receivedMsg->data, data, datasize);
				receivedMsg->data[datasize] = '\0';
				strcpy(receivedMsg->sendorId, sendorId);
				event->details = receivedMsg;
				success = FlowQueue_Enqueue(*receiveMsgQueue, event);
			}

			if (!success)
			{
				if (receivedMsg->data)
				{
					Flow_MemFree((void **)&receivedMsg->data);
				}

				if (receivedMsg->sendorId)
				{
					Flow_MemFree((void **)&receivedMsg->sendorId);
				}

				Flow_MemFree((void **)&receivedMsg);
			}
		}

		if (!success)
		{
			Flow_MemFree((void **)&event);
		}
	}

	return success;
}
/**
 * Send an event to controller thread for success/failure of reading KVS config
 * data - Device setting read from datastore.
 *        In case of any failure, user should free any memory allocated to it.
 *        Otherwise, would be freed by receiver if successfully added to queue.
 */
static bool PostControllerEventSetting(const FlowQueue* receiveMsgQueue, char *data)
{
	bool success = false;
	ControllerEvent *event = NULL;

	//Allocated memory should be freed by the receiver
	event = (ControllerEvent *)Flow_MemAlloc(sizeof(ControllerEvent));
	if (event)
	{
		if (data)
		{
			event->evtType = ControllerEvent_SettingSuccess;
		}
		else
		{
			event->evtType = ControllerEvent_SettingFailure;
		}

		event->details = data;
		success = FlowQueue_Enqueue(*receiveMsgQueue, event);

		if (!success)
		{
			Flow_MemFree((void **)&event);
		}
	}

	return success;
}
Пример #5
0
bool TreeNode_DeleteSingle(TreeNode node)
{
    // Not a recursive delete -- *only* deletes this node
    // Links to its children will be lost if they have not been
    // 'remembered' externally
    bool result = false;
    _treeNode _node = (_treeNode) node;
    if (_node)
    {
        if(_node->Name)
            Flow_MemFree((void **)&_node->Name);
        if(_node->Value)
            Flow_MemFree((void **)&_node->Value);

        if(_node->Children)
            Flow_MemFree((void **)&_node->Children);

        Flow_MemFree((void **)&_node);
        result = true;
    }
    return result;
}
Пример #6
0
bool TreeNode_AddChild(TreeNode node, TreeNode child)
{
    bool result = false;
    _treeNode _node = (_treeNode) node;
    if (_node && child)
    {
        // Check whether we need to resize the children list to add a new child
        if (_node->ChildSlots <= _node->ChildCount)
        {
            TreeNodeImpl **oldChildrenList = (TreeNodeImpl**) _node->Children;

            // Double list capacity
            uint32_t newChildrenListSize = sizeof(TreeNode) * (_node->ChildSlots * 2);
            _node->Children = (struct TreeNodeImpl**) Flow_MemAlloc(newChildrenListSize);
            if (_node->Children)
            {
                _node->ChildSlots = (_node->ChildSlots * 2);
                memset(_node->Children, 0, newChildrenListSize);
                memcpy(_node->Children, oldChildrenList, _node->ChildCount * sizeof(TreeNode));
                Flow_MemFree((void **) &oldChildrenList);
            }
            else
            {
                _node->Children = (struct TreeNodeImpl**) oldChildrenList;
                goto error;
            }

        }

        // Add the new child to the list        
        _node->Children[_node->ChildCount] = child;
        _node->ChildCount++;
        ((_treeNode)child)->ChildID = _node->ChildCount;

        // Make sure the Parent pointer is set so that
        // Tree_Delete will also free the root node.
        ((_treeNode)child)->Parent = (struct TreeNodeImpl *)_node;

        result = true;
    }
error:
    return result;
}
Пример #7
0
bool TreeNode_SetValue(const TreeNode node, const uint8_t* value, const uint32_t length)
{
    bool result = false;
    _treeNode _node = (_treeNode) node;
    if (_node && value)
    {
        if (_node->Value)
            Flow_MemFree((void **) &_node->Value);

        _node->Value = Flow_MemAlloc(sizeof(uint8_t) * (length+1));
        if (_node->Value)
        {
            if (length > 0)
                memcpy(_node->Value, value, length);
            
            _node->Value[length] = '\0';
            result = true;
        }
    }
    return result;
}
Пример #8
0
bool TreeNode_SetName(const TreeNode node, const char* name, const uint32_t length)
{
    bool result = false;
    _treeNode _node = (_treeNode) node;
    if (_node && name)
    {
        if (_node->Name)
            Flow_MemFree((void **) &_node->Name);

        _node->Name = Flow_MemAlloc(sizeof(char) * (length+1));
        if (_node->Name)
        {
            if (length > 0)
                memcpy(_node->Name, name, length);
            
            _node->Name[length] = '\0';
            result = true;
        }
    }
    return result;
}
/**
 * Flow interface thread :-
 * 1. Registers a message callback for any message received.
 * 2. Handles all the commands coming from controller thread.
 */
void FlowInterfaceThread(FlowThread thread, void *taskParameters)
{
	Controller *me = taskParameters;

	FlowInterfaceCmd *cmd = NULL;

	_receiveMsgQueue = &me->receiveMsgQueue;
	RegisterCallbackForReceivedMsg(MessageReceivedCallBack);

	for (;;)
	{
		cmd = FlowQueue_DequeueWaitFor(me->sendMsgQueue,QUEUE_WAITING_TIME);
		if (cmd != NULL)
		{
			switch (cmd->cmdType)
			{
				case FlowInterfaceCmd_SendMessageToUser:
				{
					SendMessage(me->userId, cmd->details,SendMessage_ToUser);
					FreeCmd(cmd);
					break;
				}
				case FlowInterfaceCmd_SendMessageToActuator:
				{
					if (me->actuatorConfig.actuatorId)
					{
						SendMessage(me->actuatorConfig.actuatorId, cmd->details,SendMessage_ToDevice);
						ControllerLog(ControllerLogLevel_Debug, DEBUG_PREFIX "Sending relay command to actuator" );
					}
					else
					{
						ControllerLog(ControllerLogLevel_Debug, DEBUG_PREFIX "Actuator id is NOT known to us" );
					}
					FreeCmd(cmd);
					break;
				}
				case FlowInterfaceCmd_SendMessageToSensor:
				{
					if (me->sensorConfig.sensorId)
					{
						SendMessage(me->sensorConfig.sensorId, cmd->details,SendMessage_ToDevice);
						ControllerLog(ControllerLogLevel_Debug, DEBUG_PREFIX "Sending update settings to sensor" );
					}
					else
					{
						ControllerLog(ControllerLogLevel_Debug, DEBUG_PREFIX "Sensor id is NOT known to us" );
					}
					FreeCmd(cmd);
					break;
				}
				case FlowInterfaceCmd_GetSetting:
				{
					char *data = NULL;

					if (GetSetting(CONTROLLER_CONFIG_NAME, &data))
					{
						if (!PostControllerEventSetting(&me->receiveMsgQueue, data))
						{
							Flow_MemFree((void **)&data);
							ControllerLog(ControllerLogLevel_Error, ERROR_PREFIX "Posting settings event to controller thread failed");
						}
					}
					else
					{
						if (!PostControllerEventSetting(&me->receiveMsgQueue, NULL))
						{
							ControllerLog(ControllerLogLevel_Error, ERROR_PREFIX "Posting settings event to controller thread failed");
						}
					}
					FreeCmd(cmd);
					break;
				}
				case FlowInterfaceCmd_SetSetting:
				{
					if (!SetSetting(CONTROLLER_CONFIG_NAME, cmd->details))
					{
						ControllerLog(ControllerLogLevel_Error, ERROR_PREFIX "Error in saving settings" );
					}
					FreeCmd(cmd);
					break;
				}
				default:
				{
					ControllerLog(ControllerLogLevel_Debug, DEBUG_PREFIX "Received unknown command" );
					FreeCmd(cmd);
					break;
				}
			}
		}
	}
}
/*********************************************************************
 * Function:        void SYS_ArduinoMonitorTask(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          Receive and monitor communications with the Arduino-shield serial comms channel
 *
 * Side Effects:    None
 *
 * Overview:        This function implements the task for monitoring comms from the Arduino shield.
 *
 * Note:            None
 ********************************************************************/
void SYS_ArduinoMonitorTask(FlowThread thread, void *taskParameters)
{
	char incomingChar = 0;

	#define ARDUINO_SERIAL_PORT 6
	#define ARDUINO_SERIAL_BAUD 115200

	// power the PMODRS232
	#if defined(MICROCHIP_PIC32)
    /*
     * UART 6 - Shield RS232 port
     * - u6Txd on pin RPB15
     * - u6RXd on pin RPC2
     */

    // TXd Pin setup.
	PLIB_PORTS_PinModePerPortSelect (PORTS_ID_0, PORT_CHANNEL_B, PORTS_BIT_POS_15, PORTS_PIN_MODE_DIGITAL);
    PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_B, PORTS_BIT_POS_15 );
    RPB15R = 0x04;

    // RXd Pin setup.
	PLIB_PORTS_PinModePerPortSelect (PORTS_ID_0, PORT_CHANNEL_C, PORTS_BIT_POS_2, PORTS_PIN_MODE_DIGITAL);
	PLIB_PORTS_PinDirectionInputSet( PORTS_ID_0, PORT_CHANNEL_C, PORTS_BIT_POS_2 );
    U6RXR = 0x0C;

	// RPG8 3V3 supply Digilent PMODRS232
    PLIB_PORTS_PinModePerPortSelect (PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_8, PORTS_PIN_MODE_DIGITAL);
	PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_8 );
	PLIB_PORTS_PinSet( PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_8 );

	// RPG7 0V supply to Digilent PMODRS232
    PLIB_PORTS_PinModePerPortSelect (PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_7, PORTS_PIN_MODE_DIGITAL);
	PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_7 );
	PLIB_PORTS_PinClear( PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_7 );
	#endif

	arduinoSerial = FlowSerial_Init(ARDUINO_SERIAL_PORT, ARDUINO_SERIAL_BAUD);

	#define ARDUINO_CMD_BUFFER_LENGTH 255
	char commandBuffer[ARDUINO_CMD_BUFFER_LENGTH+1];
	char* cursor = commandBuffer;
	unsigned int freeBufferSize = ARDUINO_CMD_BUFFER_LENGTH;
	bool processCommand = false;

	memset(commandBuffer, '\0', ARDUINO_CMD_BUFFER_LENGTH+1);

	while(1)
	{
		while (FlowSerial_Ready(arduinoSerial))
		{
			incomingChar = FlowSerial_Getc(arduinoSerial);

			if (freeBufferSize > 0 && incomingChar != '\n' && incomingChar != '\r')
			{
				*cursor = incomingChar;
				freeBufferSize--;
				cursor++;
			}
			else
			{
				*cursor = '\0';
				processCommand = true;
			}

			if (processCommand)
			{
				cmdRequestID++;
				
				// Create a request to send to device owner
				StringBuilder request = StringBuilder_New(256);

				// Response Header
				request = StringBuilder_Append(request, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
				request = StringBuilder_Append(request, "<command>");

				char* datetime = CommandHandlers_GetTimeString();
				request = StringBuilder_Append(request, "<sent type=\"datetime\">");
				request = StringBuilder_Append(request, datetime);
				request = StringBuilder_Append(request, "</sent>");
				Flow_MemFree((void **) &datetime);

				request = StringBuilder_Append(request, "<to>");
				request = StringBuilder_Append(request, g_OwnerAoR);
				request = StringBuilder_Append(request, "</to>");

				request = StringBuilder_Append(request, "<from>");
				request = StringBuilder_Append(request, g_DeviceAoR);
				request = StringBuilder_Append(request, "</from>");

				request = StringBuilder_Append(request, "<clientid type=\"integer\">");
				request = StringBuilder_Append(request, g_ClientID);
				request = StringBuilder_Append(request, "</clientid>");

				request = StringBuilder_Append(request, "<requestid type=\"integer\">");
				request = StringBuilder_AppendInt(request, cmdRequestID);
				request = StringBuilder_Append(request, "</requestid>");

				request = StringBuilder_Append(request, "<details>MIF DISPLAY ");
				request = StringBuilder_Append(request, commandBuffer);
				request = StringBuilder_Append(request, "</details>");
				
				request = StringBuilder_Append(request, "</command>");

				if (FlowMessaging_SendMessageToUser((FlowID) g_OwnerID, "text/plain", (char *)StringBuilder_GetCString(request), StringBuilder_GetLength(request), 60))
				{
					FlowConsole_Printf("\n\rSuccessfully forwarded command received from Arduino-shield comms interface ('%s').\n\r", commandBuffer);
				}
				else
				{
					FlowConsole_Puts("\n\rWarning: Could not forward command received from Arduino-shield comms interface.");
				}				

				// Clean up
				StringBuilder_Free(&request);
				processCommand = false;
				cursor = commandBuffer;
				freeBufferSize = ARDUINO_CMD_BUFFER_LENGTH;
			}
		}
        vTaskDelay( 100 / portTICK_RATE_MS );
	}
}
Пример #11
0
TreeNode TreeNode_Navigate(const TreeNode rootNode, const char* path)
{
    _treeNode currentNode = rootNode;
    _treeNode _node = (_treeNode) rootNode;

    // Validate inputs (Check rootNode & path are not null)
    // Assuming path is null-terminated 
    if (rootNode && path)
    {
        char* _path = (char*) Flow_MemAlloc(sizeof(char) * (strlen((const char*) path)+1) );
        if (_path)
        {
            // Design note: Need to make a copy of path ('_path') as Microchip's implementation
            // of strtok() appears to try to modify the string it's working on
            memset((void*)_path, 0, (sizeof(char) * (strlen((const char*) path)+1) ));
            memcpy((void*) _path, (void*) path, sizeof(char) * strlen((const char*) path) );

            // Check for path separator '/' character
            if (strchr((const char*) _path, '/') == NULL)
            {
                if (strcmp((const char*) _node->Name, (const char*) _path) != 0)
                    currentNode = NULL;
            }
            else
            {
                // Tokenise path and ensure first pathElement matches
                char *pathElement = strtok((char*) _path, (const char*) "/");
                if (pathElement)
                {
                    if (strcmp((const char*) currentNode->Name, (const char*) pathElement) == 0)
                    {
                        bool childFound = false;
                        bool pathError = false;
                        do
                        {
                            // Then, get next path-token and find a match for a child node's name
                            pathElement = strtok(0, "/");
                            if (pathElement)
                            {
                                childFound = false;
                                uint32_t childIndex = 0;
                                for (childIndex = 0; childIndex < currentNode->ChildCount; childIndex++)
                                {
                                    // For each token, check if a child's node name matches the next token in the path
                                    _treeNode thisChild = (_treeNode) currentNode->Children[childIndex];
                                    if (strcmp((const char*) thisChild->Name, pathElement) == 0)
                                    {
                                        currentNode = thisChild;
                                        childFound = true;
                                        break;
                                    }
                                }

                                if (!childFound)
                                {
                                    currentNode = NULL;
                                    pathError = true;
                                }
                            }
                        } while(pathElement && !pathError);
                        if (pathError)
                            currentNode = NULL;
                    }
                }
            }
            Flow_MemFree((void **) &_path);
        }
        else
        {
        }
    }
    return (TreeNode) currentNode;
}