[{"id":11686,"web_url":"https://patchwork.libcamera.org/comment/11686/","msgid":"<20200729075644.tn2jpgxsfgjf2avc@uno.localdomain>","date":"2020-07-29T07:56:44","subject":"Re: [libcamera-devel] [PATCH v3 2/5] libcamera: camera_sensor:\n\tGenerate a sensor ID","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Wed, Jul 29, 2020 at 01:42:22AM +0200, Niklas Söderlund wrote:\n> Generate a constant and unique string ID for the sensor. The ID is\n> generated from firmware information fetched from the hardware that backs\n> the sensor. The ID is unique and persistent across reboots of the\n\nnit: I would drop \"fetched from the hardwaware ...\" and replace it\nwith \"from the firwmare descritpion of the camera image sensor\".\n\n> system.\n>\n> For OF based systems the ID is the full path of the sensors in the\n> device tree description. For ACPI bases systems the ID is the ACPI\n\ns/bases/based/\n\n> firmware nodes path. Both ID sources are guaranteed to be unique and\n> persistent as long as the firmware of the system is not changed.\n>\n> A special case is needed to deal with the VIMC pipeline that implements\n> a virtual pipeline that is not backed by any hardware device and is\n> therefore not described in the device firmware.\n>\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  include/libcamera/internal/camera_sensor.h |  4 +\n>  src/libcamera/camera_sensor.cpp            | 85 ++++++++++++++++++++++\n>  2 files changed, 89 insertions(+)\n>\n> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\n> index 06c8292ca30129de..e0d2d9f63b47c2fe 100644\n> --- a/include/libcamera/internal/camera_sensor.h\n> +++ b/include/libcamera/internal/camera_sensor.h\n> @@ -47,6 +47,7 @@ public:\n>  \tint init();\n>\n>  \tconst std::string &model() const { return model_; }\n> +\tconst std::string &id() const { return id_; }\n>  \tconst MediaEntity *entity() const { return entity_; }\n>  \tconst std::vector<unsigned int> &mbusCodes() const { return mbusCodes_; }\n>  \tconst std::vector<Size> &sizes() const { return sizes_; }\n> @@ -67,11 +68,14 @@ protected:\n>  \tstd::string logPrefix() const override;\n>\n>  private:\n> +\tint generateID();\n> +\n>  \tconst MediaEntity *entity_;\n>  \tstd::unique_ptr<V4L2Subdevice> subdev_;\n>  \tunsigned int pad_;\n>\n>  \tstd::string model_;\n> +\tstd::string id_;\n>\n>  \tV4L2Subdevice::Formats formats_;\n>  \tSize resolution_;\n> diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp\n> index 350f49accad99c7b..a4339759bc847ff0 100644\n> --- a/src/libcamera/camera_sensor.cpp\n> +++ b/src/libcamera/camera_sensor.cpp\n> @@ -9,10 +9,12 @@\n>\n>  #include <algorithm>\n>  #include <float.h>\n> +#include <fstream>\n>  #include <iomanip>\n>  #include <limits.h>\n>  #include <math.h>\n>  #include <regex>\n> +#include <sys/stat.h>\n>\n>  #include <libcamera/property_ids.h>\n>\n> @@ -204,6 +206,11 @@ int CameraSensor::init()\n>  \tif (ret < 0)\n>  \t\treturn ret;\n>\n> +\t/* Generate a unique ID for the sensor. */\n> +\tret = generateID();\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n>  \t/* Retrieve and store the camera sensor properties. */\n>  \tconst ControlInfoMap &controls = subdev_->controls();\n>  \tint32_t propertyValue;\n> @@ -283,6 +290,17 @@ int CameraSensor::init()\n>   * \\return The sensor model name\n>   */\n>\n> +/**\n> + * \\fn CameraSensor::id()\n> + * \\brief Retrieve the sensor ID\n> + *\n> + * The sensor ID is a free-formed string that uniquely identifies the sensor in\n> + * the system. The ID is persisted between different instances of libcamera and\n\ns/persisted/persistent/\n\n> + * between resets of the system.\n\nYou know, I would copy part of the commit message here that tells how\na sensor ID is composed.\n\n> + *\n> + * \\return The sensor ID\n> + */\n> +\n>  /**\n>   * \\fn CameraSensor::entity()\n>   * \\brief Retrieve the sensor media entity\n> @@ -541,4 +559,71 @@ std::string CameraSensor::logPrefix() const\n>  \treturn \"'\" + entity_->name() + \"'\";\n>  }\n>\n> +int CameraSensor::generateID()\n> +{\n> +\tstd::string path, devPath = subdev_->devicePath();\n\nnit: can devPath be a const reference ?\n\n> +\tstruct stat statbuf;\n> +\n> +\t/* Try to generate ID from OF device tree path.  */\n> +\tpath = devPath + \"/of_node\";\n> +\tif (stat(path.c_str(), &statbuf) == 0) {\n> +\t\tchar ofPath[PATH_MAX];\n> +\n> +\t\tif (!realpath(path.c_str(), ofPath)) {\n> +\t\t\tLOG(CameraSensor, Error) << \"Failed to read sensor OF based ID\";\n> +\t\t\treturn -EINVAL;\n> +\t\t}\n> +\n> +\t\tid_ = ofPath;\n> +\t\tconst std::string dropStr = \"/sys/firmware/devicetree/\";\n\nHave you considered dropping '/base' too ?\n\n> +\t\tif (id_.find(dropStr) == 0)\n> +\t\t\tid_.erase(0, dropStr.length());\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\t/* Try to generate ID from ACPI path. */\n> +\tpath = devPath + \"/firmware_node/path\";\n> +\tif (stat(path.c_str(), &statbuf) == 0) {\n> +\t\tstd::ifstream file(path.c_str());\n> +\n> +\t\tif (!file.is_open()) {\n> +\t\t\tLOG(CameraSensor, Error) << \"Failed to read sensor ACPI based ID\";\n> +\t\t\treturn -EINVAL;\n> +\t\t}\n> +\n> +\t\tstd::getline(file, id_);\n> +\t\tfile.close();\n> +\n> +\t\treturn 0;\n> +\t}\n\nI'm now worried about file permission. Opening a file in RO mode would\nhelp avoiding permission issues ?\n\n> +\n> +\t/*\n> +\t * VIMC is a virtual video pipeline not backed hardware and have no OF\n> +\t * or ACPI firmware nodes. Handle this pipeline as a special case and\n> +\t * generate IDs based on the sensor model.\n> +\t */\n> +\tpath = devPath + \"/modalias\";\n> +\tif (stat(path.c_str(), &statbuf) == 0) {\n> +\t\tstd::ifstream file(path.c_str());\n> +\n> +\t\tif (!file.is_open()) {\n> +\t\t\tLOG(CameraSensor, Error) << \"Failed to read sensor ACPI based ID\";\n> +\t\t\treturn -EINVAL;\n> +\t\t}\n> +\n> +\t\tstd::string modalias;\n> +\t\tstd::getline(file, modalias);\n> +\t\tfile.close();\n> +\n> +\t\tif (modalias == \"platform:vimc\") {\n> +\t\t\tid_ = \"VIMC \" + model();\n> +\t\t\treturn 0;\n> +\t\t}\n> +\t}\n> +\n> +\tLOG(CameraSensor, Error) << \"Unknown sensor device type, can not generate ID\";\n\nI would however set id_ to a default. Maybe with an increasing counter\nappended.\n\nThis looks very nice to me and a really good way to address this\nthorny issue\n\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n> +\treturn -EINVAL;\n> +}\n> +\n>  } /* namespace libcamera */\n> --\n> 2.27.0\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 019E6BD86F\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Jul 2020 07:53:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 84097613C6;\n\tWed, 29 Jul 2020 09:53:06 +0200 (CEST)","from relay12.mail.gandi.net (relay12.mail.gandi.net\n\t[217.70.178.232])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 290C2605B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jul 2020 09:53:05 +0200 (CEST)","from uno.localdomain (93-34-118-233.ip49.fastwebnet.it\n\t[93.34.118.233]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay12.mail.gandi.net (Postfix) with ESMTPSA id 58F67200006;\n\tWed, 29 Jul 2020 07:53:03 +0000 (UTC)"],"Date":"Wed, 29 Jul 2020 09:56:44 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Message-ID":"<20200729075644.tn2jpgxsfgjf2avc@uno.localdomain>","References":"<20200728233744.3503740-1-niklas.soderlund@ragnatech.se>\n\t<20200728234225.3505868-1-niklas.soderlund@ragnatech.se>\n\t<20200728234225.3505868-2-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200728234225.3505868-2-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v3 2/5] libcamera: camera_sensor:\n\tGenerate a sensor ID","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11693,"web_url":"https://patchwork.libcamera.org/comment/11693/","msgid":"<20200729084913.GA273308@oden.dyn.berto.se>","date":"2020-07-29T08:49:13","subject":"Re: [libcamera-devel] [PATCH v3 2/5] libcamera: camera_sensor:\n\tGenerate a sensor ID","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Jacopo,\n\nThanks for your feedback.\n\nOn 2020-07-29 09:56:44 +0200, Jacopo Mondi wrote:\n> Hi Niklas,\n> \n> On Wed, Jul 29, 2020 at 01:42:22AM +0200, Niklas Söderlund wrote:\n> > Generate a constant and unique string ID for the sensor. The ID is\n> > generated from firmware information fetched from the hardware that backs\n> > the sensor. The ID is unique and persistent across reboots of the\n> \n> nit: I would drop \"fetched from the hardwaware ...\" and replace it\n> with \"from the firwmare descritpion of the camera image sensor\".\n> \n> > system.\n> >\n> > For OF based systems the ID is the full path of the sensors in the\n> > device tree description. For ACPI bases systems the ID is the ACPI\n> \n> s/bases/based/\n> \n> > firmware nodes path. Both ID sources are guaranteed to be unique and\n> > persistent as long as the firmware of the system is not changed.\n> >\n> > A special case is needed to deal with the VIMC pipeline that implements\n> > a virtual pipeline that is not backed by any hardware device and is\n> > therefore not described in the device firmware.\n> >\n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > ---\n> >  include/libcamera/internal/camera_sensor.h |  4 +\n> >  src/libcamera/camera_sensor.cpp            | 85 ++++++++++++++++++++++\n> >  2 files changed, 89 insertions(+)\n> >\n> > diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\n> > index 06c8292ca30129de..e0d2d9f63b47c2fe 100644\n> > --- a/include/libcamera/internal/camera_sensor.h\n> > +++ b/include/libcamera/internal/camera_sensor.h\n> > @@ -47,6 +47,7 @@ public:\n> >  \tint init();\n> >\n> >  \tconst std::string &model() const { return model_; }\n> > +\tconst std::string &id() const { return id_; }\n> >  \tconst MediaEntity *entity() const { return entity_; }\n> >  \tconst std::vector<unsigned int> &mbusCodes() const { return mbusCodes_; }\n> >  \tconst std::vector<Size> &sizes() const { return sizes_; }\n> > @@ -67,11 +68,14 @@ protected:\n> >  \tstd::string logPrefix() const override;\n> >\n> >  private:\n> > +\tint generateID();\n> > +\n> >  \tconst MediaEntity *entity_;\n> >  \tstd::unique_ptr<V4L2Subdevice> subdev_;\n> >  \tunsigned int pad_;\n> >\n> >  \tstd::string model_;\n> > +\tstd::string id_;\n> >\n> >  \tV4L2Subdevice::Formats formats_;\n> >  \tSize resolution_;\n> > diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp\n> > index 350f49accad99c7b..a4339759bc847ff0 100644\n> > --- a/src/libcamera/camera_sensor.cpp\n> > +++ b/src/libcamera/camera_sensor.cpp\n> > @@ -9,10 +9,12 @@\n> >\n> >  #include <algorithm>\n> >  #include <float.h>\n> > +#include <fstream>\n> >  #include <iomanip>\n> >  #include <limits.h>\n> >  #include <math.h>\n> >  #include <regex>\n> > +#include <sys/stat.h>\n> >\n> >  #include <libcamera/property_ids.h>\n> >\n> > @@ -204,6 +206,11 @@ int CameraSensor::init()\n> >  \tif (ret < 0)\n> >  \t\treturn ret;\n> >\n> > +\t/* Generate a unique ID for the sensor. */\n> > +\tret = generateID();\n> > +\tif (ret)\n> > +\t\treturn ret;\n> > +\n> >  \t/* Retrieve and store the camera sensor properties. */\n> >  \tconst ControlInfoMap &controls = subdev_->controls();\n> >  \tint32_t propertyValue;\n> > @@ -283,6 +290,17 @@ int CameraSensor::init()\n> >   * \\return The sensor model name\n> >   */\n> >\n> > +/**\n> > + * \\fn CameraSensor::id()\n> > + * \\brief Retrieve the sensor ID\n> > + *\n> > + * The sensor ID is a free-formed string that uniquely identifies the sensor in\n> > + * the system. The ID is persisted between different instances of libcamera and\n> \n> s/persisted/persistent/\n> \n> > + * between resets of the system.\n> \n> You know, I would copy part of the commit message here that tells how\n> a sensor ID is composed.\n> \n> > + *\n> > + * \\return The sensor ID\n> > + */\n> > +\n> >  /**\n> >   * \\fn CameraSensor::entity()\n> >   * \\brief Retrieve the sensor media entity\n> > @@ -541,4 +559,71 @@ std::string CameraSensor::logPrefix() const\n> >  \treturn \"'\" + entity_->name() + \"'\";\n> >  }\n> >\n> > +int CameraSensor::generateID()\n> > +{\n> > +\tstd::string path, devPath = subdev_->devicePath();\n> \n> nit: can devPath be a const reference ?\n\nNo, devicePath() returns a value and not a reference.\n\n> \n> > +\tstruct stat statbuf;\n> > +\n> > +\t/* Try to generate ID from OF device tree path.  */\n> > +\tpath = devPath + \"/of_node\";\n> > +\tif (stat(path.c_str(), &statbuf) == 0) {\n> > +\t\tchar ofPath[PATH_MAX];\n> > +\n> > +\t\tif (!realpath(path.c_str(), ofPath)) {\n> > +\t\t\tLOG(CameraSensor, Error) << \"Failed to read sensor OF based ID\";\n> > +\t\t\treturn -EINVAL;\n> > +\t\t}\n> > +\n> > +\t\tid_ = ofPath;\n> > +\t\tconst std::string dropStr = \"/sys/firmware/devicetree/\";\n> \n> Have you considered dropping '/base' too ?\n\nI thought about it but decided again it. If we ever get proper runtime \nDT overlay support which could used to add cameras at runtime we need to \nkeep the /base prefix to distinguish it as far as I understand it.\n\n> \n> > +\t\tif (id_.find(dropStr) == 0)\n> > +\t\t\tid_.erase(0, dropStr.length());\n> > +\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> > +\t/* Try to generate ID from ACPI path. */\n> > +\tpath = devPath + \"/firmware_node/path\";\n> > +\tif (stat(path.c_str(), &statbuf) == 0) {\n> > +\t\tstd::ifstream file(path.c_str());\n> > +\n> > +\t\tif (!file.is_open()) {\n> > +\t\t\tLOG(CameraSensor, Error) << \"Failed to read sensor ACPI based ID\";\n> > +\t\t\treturn -EINVAL;\n> > +\t\t}\n> > +\n> > +\t\tstd::getline(file, id_);\n> > +\t\tfile.close();\n> > +\n> > +\t\treturn 0;\n> > +\t}\n> \n> I'm now worried about file permission. Opening a file in RO mode would\n> help avoiding permission issues ?\n\nstd::ifstream is RO :-)\n\n> \n> > +\n> > +\t/*\n> > +\t * VIMC is a virtual video pipeline not backed hardware and have no OF\n> > +\t * or ACPI firmware nodes. Handle this pipeline as a special case and\n> > +\t * generate IDs based on the sensor model.\n> > +\t */\n> > +\tpath = devPath + \"/modalias\";\n> > +\tif (stat(path.c_str(), &statbuf) == 0) {\n> > +\t\tstd::ifstream file(path.c_str());\n> > +\n> > +\t\tif (!file.is_open()) {\n> > +\t\t\tLOG(CameraSensor, Error) << \"Failed to read sensor ACPI based ID\";\n> > +\t\t\treturn -EINVAL;\n> > +\t\t}\n> > +\n> > +\t\tstd::string modalias;\n> > +\t\tstd::getline(file, modalias);\n> > +\t\tfile.close();\n> > +\n> > +\t\tif (modalias == \"platform:vimc\") {\n> > +\t\t\tid_ = \"VIMC \" + model();\n> > +\t\t\treturn 0;\n> > +\t\t}\n> > +\t}\n> > +\n> > +\tLOG(CameraSensor, Error) << \"Unknown sensor device type, can not generate ID\";\n> \n> I would however set id_ to a default. Maybe with an increasing counter\n> appended.\n\nI think that is a bad idea, here we error out with -EINVAL and as this \nis a private function the only caller is CameraSensor::init() which will \npropagate the error.\n\nI don't think its a good idea to hide and try to recover if we encounter \na new device type, what would that even be? Maybe we should even make \nthe error fatal as it really should not happen.\n\n> \n> This looks very nice to me and a really good way to address this\n> thorny issue\n> \n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks!\n\n> \n> Thanks\n>   j\n> \n> > +\treturn -EINVAL;\n> > +}\n> > +\n> >  } /* namespace libcamera */\n> > --\n> > 2.27.0\n> >\n> > _______________________________________________\n> > libcamera-devel mailing list\n> > libcamera-devel@lists.libcamera.org\n> > https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B85EFBD878\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Jul 2020 08:49:17 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 46BDF617AF;\n\tWed, 29 Jul 2020 10:49:17 +0200 (CEST)","from mail-lj1-x229.google.com (mail-lj1-x229.google.com\n\t[IPv6:2a00:1450:4864:20::229])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CD542605B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jul 2020 10:49:15 +0200 (CEST)","by mail-lj1-x229.google.com with SMTP id g6so11536657ljn.11\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jul 2020 01:49:15 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tu10sm308788lfo.39.2020.07.29.01.49.13\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 29 Jul 2020 01:49:14 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"UOZDywMX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=ImjAhnBYQne5VrJCK0CDjVUgsIFvBHqQ81/+Eh2/xdc=;\n\tb=UOZDywMXPCRUBFdHGQQy6TkGZ+B9stgqcb5fMJROMVeYWEToLDqv5+v7mjcMqpneqK\n\t+iHyZOG9QshAETIOJN4kNbFsobtDRauuvuy6MYVg/WbqfgTdP/8fKi4t+KIn7gSb8L0Y\n\tGXXPF1uq3zOiROD0rcHZ41J9qAdhjtK/Box/tTBcgirsxsCejaW6d92HnG0eQmlBa1ec\n\tkRhFtLBHxmUX0DQGvt5dO7dHLR3dxMt1DxUKVTI4EMiG1uIHs6K72iOP8JGBjyZihteT\n\tbH+rk/AO+GAP3RnbMZgq5FX2udnIJDkBu5zOj9Jx1f59v+x0AgFq8NLMSMh1HFZAkPok\n\tqLqA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=ImjAhnBYQne5VrJCK0CDjVUgsIFvBHqQ81/+Eh2/xdc=;\n\tb=HydvdBlztnViYUd+rKn/ilqy09oWO6P5rKoqE3Rq/3yucGunmgSO4CNSdtP7YzdzBe\n\tO5xVM5B2BQxvrQ/vPQggQKc5xXdr0Pi/fquNwxn3SXt9skA9WGYJgbWwbKgr1gcd0nPG\n\tXHpJZuHKn+J0us0f1JUJ5btdMwAF2LseC2MHjORAihrzvsln7T3n7aWvoxB5/KsDaPWc\n\t/nKTUkYz0Bh8YJD99pmattuDCw/I3DKoyqQZxh7k81FSPvzpFe6pakuk/ZNYjTNykmWO\n\t+J1/xTbny7pRk7efMCbYGajNm21ZZZZEp2JxQoABdDC0wZVNtwyMgey4dkzBujnfK0YF\n\tZRsg==","X-Gm-Message-State":"AOAM533ubl6wPJ4/S3RuVkqTTwUqLQg2mE0FCFQLzwg8cX1z5/dCtQsb\n\tiEozRBZkJZwdrerMJkOjkHOUMQ==","X-Google-Smtp-Source":"ABdhPJxWDo5bOO/lptlYBhB3234yiDMF+u8csJMGTbRxWOeOKmOIP7ZIC7DxssEmVj39PkzfaJP6FA==","X-Received":"by 2002:a2e:503:: with SMTP id 3mr10716346ljf.225.1596012554662; \n\tWed, 29 Jul 2020 01:49:14 -0700 (PDT)","Date":"Wed, 29 Jul 2020 10:49:13 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20200729084913.GA273308@oden.dyn.berto.se>","References":"<20200728233744.3503740-1-niklas.soderlund@ragnatech.se>\n\t<20200728234225.3505868-1-niklas.soderlund@ragnatech.se>\n\t<20200728234225.3505868-2-niklas.soderlund@ragnatech.se>\n\t<20200729075644.tn2jpgxsfgjf2avc@uno.localdomain>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200729075644.tn2jpgxsfgjf2avc@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH v3 2/5] libcamera: camera_sensor:\n\tGenerate a sensor ID","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]