0

I'm using gdbus bindings. Here is part of my interface:

<node>
    <interface name="USB.Manager">
        <property name="Devices" type="ao" access="read">
             <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
        </property>
    </interface>
</node>

I failed to extract device list get from this interface to a string array. Can anyone tell the correct marshalling for dbus string array?

My assumption for dbus string array structure is as follows:

|--------|--------|--------|--------|
|         array length              |
|        pointer to first string    |
|       pointer to second string    |

And also internal structure for string is as follows:

|--------|--------|--------|--------|
|        string length              |
|   char |  char  |  char  | char   |
|            ......                 |
|  char  | '\0'   |        |        |

And below is my code:

static USBManager *pSkeletonManager = usbmanager_skeleton_new();

gchar* deviceList[2] = { "/dev/obj/usb1", "/dev/obj/usb2" };
gchar* aoList[255];
ConvertStringArrayToAo(deviceList, aoList, 2);

usbmanager_set_devices(pSkeletonManager, aoList);

void ConvertStringArrayToAo(char** stringArray, char** aoString, int length)
{
    if (length == 0)
    {
        return;
    }

    // Array - leading length
    aoString[0] = (char*)length;

    g_print("Length: %d, aoString[0]: %d\n", length, aoString[0]);

    // Array - content
    int i = 0;
    for (; i < length; i++)
    {
        char* string = stringArray[i];
        char* resultString = aoString[i+1];

        // 4 byte for leading length
        // 1 byte for terminating \0
        aoString[i+1] = (char*)malloc(strlen(string) + 5);
        memset(aoString[i+1], 0, strlen(string)+5);

        // length
        int j = 0;
        aoString[i+1][0] = (strlen(string) & 0xF000) >> 24;
        aoString[i+1][1] = (strlen(string) & 0x0F00) >> 16;
        aoString[i+1][2] = (strlen(string) & 0x00F0) >> 8;
        aoString[i+1][3] = (strlen(string) & 0x000F);

        // content
        strncpy(&aoString[i+1][4], string, strlen(string));

        // terminating
        aoString[i+1][strlen(string)+4] = '\0';

        g_print("%s\n", &aoString[i+1][4]);
    }
}

This piece of code runs into segmentation fault when calling "usbmanager_set_devices".

Peter
  • 331
  • 3
  • 11
  • Actually, my question goes the wrong way. I don't need to marshal dbus string array at all. By simply set `usbmanager_set_devices(pSkeletonManager, device_list);` would be OK. – Peter Aug 27 '14 at 06:33
  • Please close this question. – Peter Aug 27 '14 at 06:35

1 Answers1

-1

I tried to serialise your example with my node.js dbus-native client library

Here is my code:

var marshall = require('dnus-native/lib/marshall')
console.log( marshall('ao', [ ["/dev/obj/usb1", "/dev/obj/usb2"] ], 0) );

Output:

<Buffer 26 00 00 00 0d 00 00 00 2f 64 65 76 2f 6f 62 6a 2f 75 73 62 31 00 00 00 0d 00 00 00 2f 64 65 76 2f 6f 62 6a 2f 75 73 62 32 00>

Note that length prefixes need to be aligned to a 4 byte boundary ( string is padded with zeros if need so ). Try to compare your aoString with buffer in my example

Andrey Sidorov
  • 24,905
  • 4
  • 62
  • 75
  • Your marshalling example may not fit gdbus. The API "usbmanager_set_devices" accepts devices as "char**", which is an array of char pointers". – Peter Aug 27 '14 at 02:55
  • on wire level only basic types are serialised - ints/floats/strings. You can't send pointer to another process – Andrey Sidorov Aug 28 '14 at 09:48