Exemple #1
0
/*!
 * @function pgm_load
 * Loads the pgm image at [filename] into a [width] x [height] unsigned char matrix,
 * and stores the pointer into [img].
 * @param img
 * A pointer to an unsigned char pointer where the image will be stored.
 * @param height
 * A pointer to an int where the n of rows of the image will be stored.
 * @param width
 * A pointer to an int where the n of cols of the image will be stored.
 * @param filename
 * The name of the file to be read.
 * @return
 * 0 on success, non-0 on failure.
 */
int pgm_load(unsigned char ** const img, int * const height, int * const width, const char * const filename)
{
	const char * const fname = "pgm_load";
	if (NULL == img) {
		Debug_out(DEBUG_PGM, "%s: NULL pointer argument.\n", fname);
		goto error1;
	}
	char **lines = parseLines(filename);
	int i = 0, j;
	int l_width, l_height;
	unsigned int tmp;
	/* parse all file lines */
	if (NULL == lines) {
		Debug_out(DEBUG_PGM, "%s: unable to read file '%s'.\n", fname, filename);
		goto error1;
	}
	/* check that first line says P2 */
	if (NULL == lines[i]) {
		Debug_out(DEBUG_PGM, "%s: image ended too early.\n", fname);
		goto error2;
	}
	if (!StringUtils_startsWith(lines[i], "P2")) {
		Debug_out(DEBUG_PGM, "%s: illegal image start: %s.\n", fname, lines[i]);
		goto error2;
	}
	++i;
	/* skip all comment lines */
	while ((NULL != lines[i]) && (StringUtils_startsWith(lines[i], "#"))) {
		/* Comment line */
		Debug_out(DEBUG_PGM, "%s: %s.\n", fname, lines[i]);
		++i;
	}
	if (NULL == lines[i]) {
		Debug_out(DEBUG_PGM, "%s: image ended too early.\n", fname);
		goto error2;
	}
	/* parse width and height */
	if (2 != sscanf(lines[i], "%d %d", &l_width, &l_height)) {
		Debug_out(DEBUG_PGM, "%s: error scanning line %d: %s.\n", fname, i, lines[i]);
		goto error2;
	}
	Debug_out(DEBUG_PGM, "%s: image size is %d x %d.\n", fname, l_width, l_height);
	++i;
	if (NULL == lines[i]) {
		Debug_out(DEBUG_PGM, "%s: image ended too early.\n", fname);
		goto error2;
	}
	/* skip image max value */
	Debug_out(DEBUG_PGM, "%s: image max value is %s.\n", fname, lines[i]);
	++i;
	if (NULL == lines[i]) {
		Debug_out(DEBUG_PGM, "%s: image ended too early.\n", fname);
		goto error2;
	}
	/* allocate image and parse it */
	*img = calloc(l_width * l_height, sizeof(unsigned char));
	if (NULL == img) {
		Debug_out(DEBUG_PGM, "%s: calloc failed.\n", fname);
		goto error2;
	}
	Debug_out(DEBUG_PGM, "%s: Result image buffer allocated.\n", fname);
	for (j = 0; j < l_width * l_height; ++j) {
		if (NULL == lines[i+j]) {
			Debug_out(DEBUG_PGM, "%s: image ended too early.\n", fname);
			goto error3;
		} else if (1 != sscanf(lines[i+j], "%u", &tmp)) {
			Debug_out(DEBUG_PGM, "%s: error scanning line %d: %s.\n", fname, i+j, lines[i+j]);
			goto error3;
		}
		Debug_out(DEBUG_PGM, "%s: Pixel %d is %d.\n", fname, j, tmp);
		(*img)[j] = tmp;
	}
	/* save width and height, and free parsed lines */
	if (NULL != width) {
		*width = l_width;
	}
	if (NULL != height) {
		*height = l_height;
	}
	Vector_free((void **) lines);
	return 0;

error3:
	free(img);
error2:
	Vector_free((void **) lines);
error1:
	return 1;
}
IedModel*
ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
{
    int bytesRead = 1;

    bool stateInModel = false;
    int indendation = 0;

    IedModel* model = NULL;
    LogicalDevice* currentLD = NULL;
    LogicalNode* currentLN = NULL;
    ModelNode* currentModelNode = NULL;
    DataSet* currentDataSet = NULL;
    GSEControlBlock* currentGoCB = NULL;

    char nameString[130];
    char nameString2[130];
    char nameString3[130];

    int currentLine = 0;

    while (bytesRead > 0) {
        bytesRead = readLine(fileHandle, lineBuffer, READ_BUFFER_MAX_SIZE);

        currentLine++;

        if (bytesRead > 0) {
            lineBuffer[bytesRead] = 0;

            if (stateInModel) {

                if (StringUtils_startsWith((char*) lineBuffer, "}")) {
                    if (indendation == 1) {
                        stateInModel = false;
                        indendation = 0;
                    }
                    else if (indendation == 2) {
                        indendation = 1;
                    }
                    else if (indendation == 3) {
                        indendation = 2;
                    }
                    else if (indendation == 4) {
                        indendation = 3;
                    }
                    else if (indendation > 4) {
                        currentModelNode = currentModelNode->parent;
                        indendation--;
                    }
                }

                else if (indendation == 1) {
                    if (StringUtils_startsWith((char*) lineBuffer, "LD")) {
                        indendation = 2;

                        if (sscanf((char*) lineBuffer, "LD(%s)", nameString) < 1)
                            goto exit_error;

                        terminateString(nameString, ')');

                        currentLD = LogicalDevice_create(nameString, model);
                    }
                    else
                        goto exit_error;
                }
                else if (indendation == 2) {
                    if (StringUtils_startsWith((char*) lineBuffer, "LN")) {
                        indendation = 3;

                        if (sscanf((char*) lineBuffer, "LN(%s)", nameString) < 1)
                            goto exit_error;

                        terminateString(nameString, ')');

                        currentLN = LogicalNode_create(nameString, currentLD);
                    }
                    else
                        goto exit_error;
                }
                else if (indendation == 3) {
                    if (StringUtils_startsWith((char*) lineBuffer, "DO")) {
                        indendation = 4;

                        int arrayElements = 0;

                        sscanf((char*) lineBuffer, "DO(%s %i)", nameString, &arrayElements);

                        currentModelNode = (ModelNode*)
                                DataObject_create(nameString, (ModelNode*) currentLN, arrayElements);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "DS")) {
                        indendation = 4;

                        sscanf((char*) lineBuffer, "DS(%s)", nameString);
                        terminateString(nameString, ')');

                        currentDataSet = DataSet_create(nameString, currentLN);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "RC")) {
                        int isBuffered;
                        uint32_t confRef;
                        int trgOps;
                        int options;
                        uint32_t bufTm;
                        uint32_t intgPd;

                        int matchedItems = sscanf((char*) lineBuffer, "RC(%s %s %i %s %u %i %i %u %u)",
                                nameString, nameString2, &isBuffered, nameString3, &confRef,
                                &trgOps, &options, &bufTm, &intgPd);

                        if (matchedItems < 9) goto exit_error;

                        char* rptId = NULL;

                        if (strcmp(nameString2, "-") != 0)
                            rptId = nameString2;

                        char* dataSetName = NULL;

                        if (strcmp(nameString3, "-") != 0)
                            dataSetName = nameString3;

                        ReportControlBlock_create(nameString, currentLN, rptId,
                                (bool) isBuffered, dataSetName, confRef, trgOps, options, bufTm, intgPd);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "LC")) {
                        uint32_t trgOps;
                        uint32_t intgPd;
                        int logEna;
                        int withReasonCode;

                        int matchedItems = sscanf((char*) lineBuffer, "LC(%s %s %s %u %u %i %i)",
                                nameString, nameString2, nameString3, &trgOps, &intgPd, &logEna, &withReasonCode);

                        if (matchedItems < 7) goto exit_error;

                        char* dataSet = NULL;
                        if (strcmp(nameString2, "-") != 0)
                            dataSet = nameString2;

                        char* logRef = NULL;
                        if (strcmp(nameString3, "-") != 0)
                            logRef = nameString3;

                        LogControlBlock_create(nameString, currentLN, dataSet, logRef, trgOps, intgPd, logEna, withReasonCode);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "LOG")) {
                        int matchedItems = sscanf((char*) lineBuffer, "LOG(%s)", nameString);

                        if (matchedItems < 1) goto exit_error;

                        /* remove trailing ')' character */
                        int nameLen = strlen(nameString);
                        nameString[nameLen - 1] = 0;

                        Log_create(nameString, currentLN);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "GC")) {
                        uint32_t confRef;
                        int fixedOffs;
                        int minTime = -1;
                        int maxTime = -1;

                        int matchedItems = sscanf((char*) lineBuffer, "GC(%s %s %s %u %i %i %i)",
                                nameString, nameString2, nameString3, &confRef, &fixedOffs, &minTime, &maxTime);

                        if (matchedItems < 5) goto exit_error;

                        currentGoCB = GSEControlBlock_create(nameString, currentLN, nameString2,
                                nameString3, confRef, fixedOffs, minTime, maxTime);

                        indendation = 4;

                    }
#if (CONFIG_IEC61850_SETTING_GROUPS == 1)
                    else if (StringUtils_startsWith((char*) lineBuffer, "SG")) {

                        if (strcmp(currentLN->name, "LLN0") != 0) {
                            if (DEBUG_IED_SERVER)
                                printf("Setting group control is not defined in LLN0\n");

                            goto exit_error;
                        }

                        int actSG;
                        int numOfSGs;

                        int matchedItems = sscanf((char*) lineBuffer, "SG(%i %i)", &actSG, &numOfSGs);

                        if (matchedItems < 2)
                            goto exit_error;

                        SettingGroupControlBlock_create(currentLN, actSG, numOfSGs);
                    }
#endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */

                    else {
                        if (DEBUG_IED_SERVER)
                            printf("IED_SERVER: Unknown identifier (%s)\n", lineBuffer);

                        goto exit_error;
                    }

                }
                else if (indendation > 3) {
                    if (StringUtils_startsWith((char*) lineBuffer, "DO")) {
                        indendation++;

                        int arrayElements = 0;

                        int matchedItems = sscanf((char*) lineBuffer, "DO(%s %i)", nameString, &arrayElements);

                        if (matchedItems != 2) goto exit_error;

                        currentModelNode = (ModelNode*) DataObject_create(nameString, currentModelNode, arrayElements);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "DA")) {

                        int arrayElements = 0;

                        int attributeType = 0;
                        int functionalConstraint = 0;
                        int triggerOptions = 0;
                        uint32_t sAddr = 0;

                        sscanf((char*) lineBuffer, "DA(%s %i %i %i %i %u)", nameString, &arrayElements,  &attributeType, &functionalConstraint, &triggerOptions, &sAddr);

                        DataAttribute* dataAttribute = DataAttribute_create(nameString, currentModelNode,
                                (DataAttributeType) attributeType, (FunctionalConstraint) functionalConstraint, triggerOptions, arrayElements, sAddr);

                        char* valueIndicator = strchr((char*) lineBuffer, '=');

                        if (valueIndicator != NULL) {
                            switch (dataAttribute->type) {
                            case IEC61850_UNICODE_STRING_255:
                                {
                                    char* stringStart = valueIndicator + 2;
                                    terminateString(stringStart, '"');
                                    dataAttribute->mmsValue = MmsValue_newMmsString(stringStart);
                                }
                                break;

                            case IEC61850_VISIBLE_STRING_255:
                            case IEC61850_VISIBLE_STRING_129:
                            case IEC61850_VISIBLE_STRING_65:
                            case IEC61850_VISIBLE_STRING_64:
                            case IEC61850_VISIBLE_STRING_32:
                                {
                                    char* stringStart = valueIndicator + 2;
                                    terminateString(stringStart, '"');
                                    dataAttribute->mmsValue = MmsValue_newVisibleString(stringStart);
                                }
                                break;

                            case IEC61850_INT8:
                            case IEC61850_INT16:
                            case IEC61850_INT32:
                            case IEC61850_INT64:
                            case IEC61850_INT128:
                            case IEC61850_ENUMERATED:
                                {
                                    int32_t intValue;
                                    if (sscanf(valueIndicator + 1, "%i", &intValue) != 1) goto exit_error;
                                    dataAttribute->mmsValue = MmsValue_newIntegerFromInt32(intValue);
                                }
                                break;

                            case IEC61850_INT8U:
                            case IEC61850_INT16U:
                            case IEC61850_INT24U:
                            case IEC61850_INT32U:
                                {
                                    uint32_t uintValue;
                                    if (sscanf(valueIndicator + 1, "%u", &uintValue) != 1) goto exit_error;
                                    dataAttribute->mmsValue = MmsValue_newUnsignedFromUint32(uintValue);
                                }
                                break;

                            case IEC61850_FLOAT32:
                                {
                                    float floatValue;
                                    if (sscanf(valueIndicator + 1, "%f", &floatValue) != 1) goto exit_error;
                                    dataAttribute->mmsValue = MmsValue_newFloat(floatValue);
                                }
                                break;

                            case IEC61850_FLOAT64:
                                {
                                    double doubleValue;
                                    if (sscanf(valueIndicator + 1, "%lf", &doubleValue) != 1) goto exit_error;
                                    dataAttribute->mmsValue = MmsValue_newDouble(doubleValue);
                                }
                                break;

                            case IEC61850_BOOLEAN:
                                {
                                    int boolean;
                                    if (sscanf(valueIndicator + 1, "%i", &boolean) != 1) goto exit_error;
                                    dataAttribute->mmsValue = MmsValue_newBoolean((bool) boolean);
                                }
                                break;

                            default:
                                break;

                            }
                        }

                        int lineLength = strlen((char*) lineBuffer);

                        if (lineBuffer[lineLength - 1] == '{') {
                            indendation++;
                            currentModelNode = (ModelNode*) dataAttribute;
                        }
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "DE")) {
                        sscanf((char*) lineBuffer, "DE(%s)", nameString);
                        terminateString(nameString, ')');

                        DataSetEntry_create(currentDataSet, nameString, -1, NULL);
                    }
                    else if (StringUtils_startsWith((char*) lineBuffer, "PA")) {
                        uint32_t vlanPrio;
                        uint32_t vlanId;
                        uint32_t appId;

                        int matchedItems = sscanf((char*) lineBuffer, "PA(%u %u %u %s)", &vlanPrio, &vlanId, &appId, nameString);

                        if ((matchedItems != 4) || (currentGoCB == NULL)) goto exit_error;

                        terminateString(nameString, ')');

                        if (strlen(nameString) != 12) goto exit_error;

                        if (StringUtils_createBufferFromHexString(nameString, (uint8_t*) nameString2) != 6)
                            goto exit_error;


                        PhyComAddress* dstAddress =
                                PhyComAddress_create((uint8_t) vlanPrio, (uint16_t) vlanId, (uint16_t) appId,
                                        (uint8_t*) nameString2);

                        GSEControlBlock_addPhyComAddress(currentGoCB, dstAddress);

                    }
                    else
                        goto exit_error;
                }


            }
            else {
                if (StringUtils_startsWith((char*) lineBuffer, "MODEL{")) {

                    model = IedModel_create("");
                    stateInModel = true;
                    indendation = 1;
                }
                else if (StringUtils_startsWith((char*) lineBuffer, "MODEL(")) {
                    sscanf((char*) lineBuffer, "MODEL(%s)", nameString);
                    terminateString(nameString, ')');
                    model = IedModel_create(nameString);
                    stateInModel = true;
                    indendation = 1;
                }
                else
                    goto exit_error;
            }
        }
    }

    return model;

exit_error:
    if (DEBUG_IED_SERVER)
        printf("IED_SERVER: error parsing line %i (indendation level = %i)\n", currentLine, indendation);
    IedModel_destroy(model);
    return NULL;
}