IPC API: Missing pin_function and pin_type fields in Pad protobuf message

Description

The IPC API's Pad protobuf message is missing the pin_function and pin_type fields, even though these fields are part of the internal PAD class and are saved in the PCB file format.

KiCad Version

Application: KiCad x86_64 on x86_64
Version: 9.0.6-9.0.6~ubuntu24.04.1, release build
Libraries:
    wxWidgets 3.2.4
    FreeType 2.13.2
    HarfBuzz 8.3.0
    FontConfig 2.15.0
    libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7
Platform: Linux Mint 22.2, 64 bit, Little endian, wxGTK, X11, cinnamon, x11
Build Info:
    Date: Oct 30 2025 16:53:42
    wxWidgets: 3.2.4 (wchar_t,wx containers) GTK+ 3.24
    Boost: 1.83.0
    OCC: 7.6.3
    Curl: 8.5.0
    ngspice: 42
    Compiler: GCC 13.3.0 with C++ ABI 1018
    KICAD_IPC_API=ON
Locale: 
    Lang: en_GB
    Enc: UTF-8
    Num: 1,234.5
    Encoded кΩ丈: D0BACEA9E4B888 (sys), D0BACEA9E4B888 (utf8)

Current Behavior

When accessing pads through the IPC API (e.g., using kipy), the pin function and pin type information is not available:

from kipy import KiCad
kicad = KiCad()
board = kicad.get_board()
footprints = board.get_footprints()
for fp in footprints:
    for pad in fp.definition.pads:
        print(pad.number)       # Available
        print(pad.net.name)     # Available
        # pad.pin_function - Not available
        # pad.pin_type - Not available

Expected Behavior

The IPC API should expose the same pad information that is available in:

  1. The internal C++ PAD class (m_pinFunction, m_pinType)
  2. The PCB file format ((pinfunction ...), (pintype ...))
  3. The pcbnew Python API (pad.GetPinFunction(), pad.GetPinType())
diff --git a/api/proto/board/board_types.proto b/api/proto/board/board_types.proto
index 00398ceadc..1b28636678 100644
--- a/api/proto/board/board_types.proto
+++ b/api/proto/board/board_types.proto
@@ -533,6 +533,14 @@ message Pad
 
   // Since: 10.0.0
   kiapi.common.types.Time pad_to_die_delay = 10;
+
+  // Pin function (pin name from schematic symbol)
+  // Since: 10.0.0
+  string pin_function = 11;
+
+  // Pin electrical type from schematic symbol (e.g., "input", "output", "bidirectional")
+  // Since: 10.0.0
+  string pin_type = 12;
 }
 
 enum ZoneType
diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp
index ff4d30cec0..4c197f4c00 100644
--- a/pcbnew/pad.cpp
+++ b/pcbnew/pad.cpp
@@ -167,6 +167,12 @@ void PAD::Serialize( google::protobuf::Any &aContainer ) const
     pad.mutable_pad_to_die_length()->set_value_nm( GetPadToDieLength() );
     pad.mutable_pad_to_die_delay()->set_value_as( GetPadToDieDelay() );
 
+    if( !GetPinFunction().IsEmpty() )
+        pad.set_pin_function( GetPinFunction().ToUTF8() );
+
+    if( !GetPinType().IsEmpty() )
+        pad.set_pin_type( GetPinType().ToUTF8() );
+
     google::protobuf::Any padStackMsg;
     m_padStack.Serialize( padStackMsg );
     padStackMsg.UnpackTo( pad.mutable_pad_stack() );
@@ -194,6 +200,12 @@ bool PAD::Deserialize( const google::protobuf::Any &aContainer )
     SetPadToDieLength( pad.pad_to_die_length().value_nm() );
     SetPadToDieDelay( pad.pad_to_die_delay().value_as() );
 
+    if( pad.has_pin_function() )
+        SetPinFunction( wxString::FromUTF8( pad.pin_function() ) );
+
+    if( pad.has_pin_type() )
+        SetPinType( wxString::FromUTF8( pad.pin_type() ) );
+
     google::protobuf::Any padStackWrapper;
     padStackWrapper.PackFrom( pad.pad_stack() );
     m_padStack.Deserialize( padStackWrapper );
Edited by Steffen Wittemeier