示例#1
0
文件: str.c 项目: amikoren/tnapy
char *strndup_null(char *s, int n)
{
    int len;
    char *str;
    
    if (!s)
	return strdup("");
    len = str_nlen(s, n);
    str = malloc_e(len+1);
    memcpy(str, s, len);
    str[len] = 0;
    return str;
}
示例#2
0
nec_data_t *nec_read( cerror_t **error, FILE *stream ) {
	cerror_t *err = NULL;
	// Read packet header
	nec_header_t header;
	fread_e(&err, &header, sizeof(header), 1, stream);
	if( err != NULL ) {
		cerr_propagate_error(error, err);
		return NULL;
	};
	
	// Read packet data
	uint8_t raw_data[header.data_length];
	fread_e(&err, raw_data, 1, header.data_length, stream);
	if( err != NULL ) {
		cerr_propagate_error(error, err);
		return NULL;
	};
	
	// Read checksum
	uint8_t expected_checksum;
	fread_e(&err, &expected_checksum, sizeof(uint8_t), 1, stream);
	if( err != NULL ) {
		cerr_propagate_error(error, err);
		return NULL;
	};
	
	// Check checksum
	uint8_t checksum = nec_checksum(&header, sizeof(header)) + nec_checksum(raw_data, header.data_length);
	if( checksum != expected_checksum ) {
		cerr_new_error(error, CERROR_ID_NEC, NEC_ERR_CHECKSUM, "Bad checksum", NULL);
		return NULL;
	}
	
	// Check for valid response
	if( !header.id.response.is_response ) {
		cerr_new_error(error, CERROR_ID_NEC, NEC_ERR_BAD_RESPONSE, "Bad response", NULL);
		return NULL;
	}

	// Check for ack
	if( !header.id.response.ack ) {
		cerror_t *proto_error;
		cerr_new_error(&proto_error, CERROR_ID_NEC, NEC_ERR_PROTOCOL, "Protocol error", NULL);
		nec_error_t *ret = realloc_e(&err, proto_error, sizeof(nec_error_t));
		if( ret != NULL ) {
			cerr_error_free(proto_error);
			cerr_propagate_error(error, err);
			return NULL;
		}
		nec_data_t *wire_error = (nec_data_t *) raw_data;
		const char *subtype_msg, *type_msg;
		switch( wire_error->error.type ) {
			case NEC_ERR_TYPE_NOT_SUPPORTED:
				type_msg = "Not supported";
				switch( wire_error->error.subtype.not_supported ) {
					case NEC_ERR_UNKNOWN_COMMAND:
						subtype_msg = "Unknown command";
						break;
					case NEC_ERR_FUNCTION_NOT_SUPPORTED:
						subtype_msg = "The current model does not support this function";
						break;
					default:
						subtype_msg = "Unknown error subtype";
				}
				break;
			case NEC_ERR_TYPE_PARAMETER_ERROR:
				type_msg = "Parameter error";
				switch( wire_error->error.subtype.parameter_error ) {
					case NEC_ERR_INVALID_VALUES:
						subtype_msg = "Invalid values specified";
						break;
					case NEC_ERR_TERMINAL_UNAVAILABLE:
						subtype_msg = "Specified terminal is unavailable or cannot be selected";
						break;
					default:
						subtype_msg = "Unknown error subtype";
				}
				break;
			default:
				type_msg = "Unknwon error type";
				subtype_msg = NULL;
		}
		ret->type.code = wire_error->error.type;
		ret->type.message = type_msg;
		ret->subtype.code = wire_error->error.subtype;
		ret->subtype.message = subtype_msg;
		cerr_propagate_error(error, (cerror_t *) ret);
		return NULL;
	}
	
	nec_data_t *data = malloc_e(&err, sizeof(nec_data_t));
	if( err != NULL ) {
		cerr_propagate_error(error, err);
		return NULL;
	}
	assert(header.data_length <= sizeof(nec_data_t));
	memcpy(data, raw_data, header.data_length);
	return data;
}