From: mcc45tr Subject: [PATCH] libssc: accept fractional and integer mount matrices SSC implementations are allowed to describe the mount matrix with floating point values. Checking whether such a matrix is empty by accumulating its entries in an integer truncates every fractional coefficient. A valid matrix can therefore be mistaken for an all-zero matrix and silently replaced by the identity matrix. Some firmware also represents the usual -1/0/1 values as integer attributes. Parse both protobuf numeric variants, track whether every parsed coefficient is actually zero, and require all nine coefficients before using the matrix. This keeps the fallback for missing or malformed firmware data without discarding valid rotations. --- src/libssc-sensor.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/libssc-sensor.c b/src/libssc-sensor.c index 6a09b07..20c2665 100644 --- a/src/libssc-sensor.c +++ b/src/libssc-sensor.c @@ -408,0 +409,4 @@ report_received (SSCClient *self, guint32 msg_id, guint64 uid_high, guint64 uid_ + { + gboolean all_zero = TRUE; + gsize parsed_values = 0; + @@ -410,0 +415 @@ report_received (SSCClient *self, guint32 msg_id, guint64 uid_high, guint64 uid_ + memset (priv->mount_matrix, 0, sizeof (priv->mount_matrix)); @@ -412,3 +417,13 @@ report_received (SSCClient *self, guint32 msg_id, guint64 uid_high, guint64 uid_ - if (attr_msg->attr[i]->value_array->v[j]->has_f) { - priv->mount_matrix[j/3][j%3] = attr_msg->attr[i]->value_array->v[j]->f; - } + SscAttrValue *value = attr_msg->attr[i]->value_array->v[j]; + gfloat coefficient; + + if (value->has_f) + coefficient = value->f; + else if (value->has_i) + coefficient = value->i; + else + continue; + + priv->mount_matrix[j/3][j%3] = coefficient; + all_zero = all_zero && coefficient == 0.0f; + parsed_values++; @@ -417,6 +432,2 @@ report_received (SSCClient *self, guint32 msg_id, guint64 uid_high, guint64 uid_ - /* Fallback to identity matrix in case matrix is all 0 */ - gint sum = 0; - for (gsize k = 0; k < 9; k++) - sum += priv->mount_matrix[k/3][k%3]; - - if (sum == 0) { + if (parsed_values != 9 || all_zero) { + memset (priv->mount_matrix, 0, sizeof (priv->mount_matrix)); @@ -426 +437 @@ report_received (SSCClient *self, guint32 msg_id, guint64 uid_high, guint64 uid_ - g_warning ("Mount matrix provided by firmware is all 0, falling back to identity matrix!"); + g_warning ("Mount matrix provided by firmware is incomplete or all 0, falling back to identity matrix!"); @@ -428,0 +440 @@ report_received (SSCClient *self, guint32 msg_id, guint64 uid_high, guint64 uid_ + } -- 2.51.0