Skip to main content
Home
for DLMS smart meters
Open source solutions for DLMS smart metering

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Forums
  3. Token Gateway Using Arduino Client

Token Gateway Using Arduino Client

Forum Rules

Before commenting read Forum rules

Don't comment the topic if you have a new question.

You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.

By elvandry13 , 18 August, 2021
Forums
Gurux.DLMS

Hi Mikko

I have question about token gateway. I want to transfer a token using Arduino client code. I tried with this :
gxTokenGateway objToken;
dlmsVARIANT params;
var_init(&params);
var_setString(&params, "48643202781314010686", 21);
cosem_init(BASE(objToken), DLMS_OBJECT_TYPE_TOKEN_GATEWAY, "0.0.19.40.0.255");
com_method(BASE(objToken), 1, &params);
obj_toString(BASE(objToken), &data);
GXTRACE(PSTR("Ori token : "), data);
obj_clear(BASE(objToken));
free(data);

but I got error code 12.

Actually how to implement a transfer token using your Arduino client code? Where should I put the token code? Can you give me an example code of transfer token?

Thank you.
BR,
Elvandry Ghiffary

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi Elvandry,

Hi Elvandry,

The token is octet-string and not an ASCII string. You can set it like this:

dlmsVARIANT params;
var_init(&params);
unsigned char token[10] = {0x48, 0x64, 0x32, 0x02, 0x78, 0x13, 0x14, 0x01, 0x06, 0x86};
var_addBytes(&params, token, sizeof(token));

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I have following your suggestion, now my code is like below:

gxTokenGateway objToken;
dlmsVARIANT params;
var_init(&params);
unsigned char token[10] = {0x04, 0x57, 0x22, 0x25, 0x33, 0x78, 0x37, 0x00, 0x00, 0x77};
var_addBytes(&params, token, sizeof(token));
cosem_init(BASE(objToken), DLMS_OBJECT_TYPE_TOKEN_GATEWAY, "0.0.19.40.0.255");
com_method(BASE(objToken), 1, &params);
obj_toString(BASE(objToken), &data);
GXTRACE(PSTR("Ori token : "), data);
obj_clear(BASE(objToken));
free(data);

but I still got the same error :

[DEBUG][TX] : 7E A0 37 2 47 9 76 EC E1 E6 E6 0 CB 28 30 0 0 0 B D4 3E F4 49 2E A3 35 A6 41 68 A9 5 74 6D F7 98 43 B8 AD A5 DE 30 F5 C4 29 94 88 23 E6 80 F1 76 F8 C3 2E 2A 31 7E
[DEBUG][RX] : 7E A0 25 9 2 47 96 82 87 E6 E7 0 CF 16 30 0 0 9 60 3A B1 8D E8 6A 55 4 93 60 9F D3 E3 7E 8 6D 46 4C DE 38 7E
:com_method failed. 12

I am using this token : 0457 2225 3378 3700 0077

I also try to modify token variable to :
unsigned char token[20] = {0x00, 0x04, 0x05, 0x07, 0x02, 0x02, 0x02, 0x05, 0x03, 0x03, 0x07, 0x08, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07};
but nothing changed, still got the same error.

I found the var_addOctetString function, do we need that function?

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

The message is encrypted so I can't check the bytes. Try to read the existing token and check what is the size of it. You can also try to write it back.

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I have tried to read the existing token using attributes no.2 (token) like below :

gxTokenGateway objToken;
cosem_init(BASE(objToken), DLMS_OBJECT_TYPE_TOKEN_GATEWAY, "0.0.19.40.0.255");
com_read(BASE(objToken), 2);
obj_toString(BASE(objToken), &data);
GXTRACE(PSTR("Ori token : "), data);
obj_clear(BASE(objToken));
free(data);

but I got return nothing :

[DEBUG][TX] : 7E A0 2D 2 47 9 54 14 1B E6 E6 0 C8 1E 30 0 0 0 2 E9 F1 77 DC 3B 13 F8 6A 86 9A C1 E3 94 5E 6F A2 B5 4D AF 8E 19 18 B3 E7 E0 A0 DD 7E
[DEBUG][RX] : 7E A0 3A 9 2 47 74 22 9D E6 E7 0 CC 2B 30 0 0 1 F3 3 CE 30 51 49 9D 84 D3 D4 A8 48 F0 C0 C1 3A 5D 7F 75 75 CE 5C 14 57 40 FD 82 29 BB 19 E 9A 96 6E CA EC E1 93 C4 C6 EF 7E
:Ori token : Index: 2 Value:

is there something I did wrong?

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

The message is encrypted so I can't check the bytes. I notest that obj_toString doesn't return values for the token. Can you use this code instead? Also, check the result of com_read and com_write.

com_read(BASE(objToken), 2);
data= bb_toHexString(&objToken->token);
GXTRACE(PSTR("Ori token : "), data);
obj_clear(BASE(objToken));
free(data);

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

Now I got the return values for the token, this is the result of com_read :

[DEBUG][TX] : 7E A0 2D 2 47 9 54 14 1B E6 E6 0 C8 1E 30 0 0 0 E 67 82 51 C2 88 F8 C2 E3 7D E 38 88 F 58 47 24 34 74 5 58 BB B7 57 36 BD E2 A9 7E
[DEBUG][RX] : 7E A0 3A 9 2 47 74 22 9D E6 E7 0 CC 2B 30 0 0 2 79 FD 61 D0 D0 CD 6E 1C FB 62 EB E4 D3 A7 C7 29 ED C5 C9 C7 82 3F 79 95 EE 20 B3 21 C2 23 B5 61 22 29 BD A4 EC E1 A1 C5 99 7E
:Ori token : 00 04 05 07 02 02 02 05 03 03 09 05 01 01 01 06 05 03 0C 05

The token I had entered before was : 0457 2225 3378 3700 0077 (I entered manually)

The token that I am using is for tamper, so I can use that token only once. Now I have made my meter in tamper conditions, so next I will enter with this new token : 1781 3034 3131 9155 8529.

So how to pass the token to com_method? Here is my code for enter the token:

gxTokenGateway objToken;
dlmsVARIANT params;
var_init(&params);
unsigned char token[10] = {0x17, 0x81, 0x30, 0x34, 0x31, 0x31, 0x91, 0x55, 0x85, 0x29};
var_addBytes(&params, token, sizeof(token));
cosem_init(BASE(objToken), DLMS_OBJECT_TYPE_TOKEN_GATEWAY, "0.0.19.40.0.255");
com_method(BASE(objToken), 1, &params);
com_read(BASE(objToken), 2);
data = bb_toHexString(&objToken.token);
GXTRACE(PSTR("Ori token : "), data);
Serial.println();
obj_clear(BASE(objToken));
free(data);

but I still failed to remove the tamper.

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

The size of your token on the meter is 20 bytes. You try to write a token that size is 10 bytes. I believe that is the reason. What is the result code of com_method? Is it succeeded?

int ret = com_method(BASE(objToken), 1, &params);

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

The token I'm using : 1781 3034 3131 9155 8529

I have tried with several experiment below :
- unsigned char token[10] = {0x17, 0x81, 0x30, 0x34, 0x31, 0x31, 0x91, 0x55, 0x85, 0x29};
- unsigned char token[20] = {0x17, 0x81, 0x30, 0x34, 0x31, 0x31, 0x91, 0x55, 0x85, 0x29};
- unsigned char token[10] = {17, 81, 30, 34, 31, 31, 91, 55, 85, 29};
- unsigned char token[20] = {0x01, 0x07, 0x08, 0x01, 0x03, 0x00, 0x03, 0x04, 0x03, 0x01, 0x03, 0x01, 0x09, 0x01, 0x05, 0x05, 0x08, 0x05, 0x02, 0x09};

try convert to octal digit :

- unsigned char token[20] = {001, 007, 010, 001, 003, 000, 003, 004, 003, 001, 003, 001, 011, 001, 005, 005, 010, 005, 002, 011};
- unsigned char token[20] = {0x01, 0x07, 0x10, 0x01, 0x03, 0x00, 0x03, 0x04, 0x03, 0x01, 0x03, 0x01, 0x11, 0x01, 0x05, 0x05, 0x10, 0x05, 0x02, 0x11};
- unsigned char token[20] = {01, 07, 10, 01, 03, 00, 03, 04, 03, 01, 03, 01, 11, 01, 05, 05, 10, 05, 02, 11};

All results of com_method are same :
:com_method failed. 12

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

If you connect with GXDLMSDirector what is your Method access right for the Enter? You can see this information if you select "Method Access Rights" bab after you have selected TokeGateway object?

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I can't find the information in "Method Access Rights" tab. Here I attached the screenshot pict of my access right tab.
I have succeeded to transfer token using GXDLMSDirector by passing the token in ASCII digits. I use HLS (HighGMAC) for authentication.

Image
Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

Update to the new version from GXDLMSDirector to show method access rights. Have you connected with HighGMAC when you are using ANSI C?

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I have updated my GXDLMSDirector to the newest version. Here I attached the method access rights.
I have connected with HighGMAC using your Arduino Client example code. I can read data (voltage, current, etc) and disconnect/reconnect relay's meter using HighGMAC auth.

Image
Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

Create gxDisconnetControl and then call com_method with index 1 and 2 in the same way as the token gateway.

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

Here is the code I used for disconnect relay meter :

gxDisconnectControl dc;
dlmsVARIANT params;
var_init(&params);
var_setInt8(&params, 0);
cosem_init(BASE(dc), DLMS_OBJECT_TYPE_DISCONNECT_CONTROL, "0.0.96.3.10.255");
com_method(BASE(dc), 1, &params);
obj_toString(BASE(dc), &data);
GXTRACE(PSTR("Disconnect : "), data);
obj_clear(BASE(dc));
free(data);

Sorry I dont understand how to adapt the disconnect control code to token gateway?

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

This will do the trick:

gxDisconnectControl dc;
dlmsVARIANT params;
var_init(&params);
var_setInt8(&params, 0);
cosem_init(BASE(dc), DLMS_OBJECT_TYPE_DISCONNECT_CONTROL, "0.0.96.3.10.255");
int ret = com_method(BASE(dc), 1, &params);
if (ret != 0)
{
//Show error.
}

obj_clear(BASE(dc));

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I have succeeded to disconnect relay using this code below with no error :

gxDisconnectControl dc;
dlmsVARIANT params;
var_init(&params);
var_setInt8(&params, 0);
cosem_init(BASE(dc), DLMS_OBJECT_TYPE_DISCONNECT_CONTROL, "0.0.96.3.10.255");
ret = com_method(BASE(dc), 1, &params);
if (ret != 0)
{
//Show error.
GXTRACE_INT("Error :", ret);
}
obj_clear(BASE(dc));
free(data);

So, what should I do next?
I'm sure the problem is not in authentication, because the auths in Arduino code are same as I use in GXDLMSDirector.

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

I'm sorry. What is the problem if you can successfully disconnect and re-connect?

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

As the title in this forum, my problem is can't transfer token gateway. I have following your suggestion for passing the token as params, but still didn't work. Then, you suggest me try to create gxDisconnetControl, but I don't know the relationship between disconnect/reconnect and token gateway. if you don't mind, please reread my question of the problem and our conversation again from first post in this forum. Thank you Mikko.

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

Did you try to read and write the same token back? Can you do that with GXDLMSDirector?
This should be quite easy. The token size must be correct, or the meter returns an error and I believe that this is the problem at the moment.

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I have tried to read and write back with the same token with GXDLMSDirector. Here is my step-by-step :
1. First, my meter in tamper status (relay is disconnected)
2. I opened GXDLMSDirector, go to TokenGateway, go to Transfer token, then I input my token in ASCII : 30 35 37 33 37 36 32 34 32 37 37 35 35 34 38 39 30 35 35 34 (My original token : 0573 7624 2775 5489 0554)
3. After that, the message "Action accomplished" appeared, and removing tamper status (so the relay is reconnected)
4. Next, I read the token : 00 05 07 03 07 06 02 04 02 07 09 00 02 04 07 03 04 08 00 06
5. I copy that token, go to Transfer token, then paste the token
6. After that, message "Action accomplished" appears again.

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

"Action accomplished" means that the meter has accepted the token and everything is OK. Have you tried to send this token with ANSI C example? Is the meter accepting the token if you modify it?

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I have already tried with your Arduino Client example, but the meter not accepting the token. Maybe I did something wrong in setting 20 bytes token in params before passing that to com_method function.

For example, the token I'm using is 1781 3034 3131 9155 8529

I have tried with several experiment:
- unsigned char token[20] = {0x01, 0x07, 0x08, 0x01, 0x03, 0x00, 0x03, 0x04, 0x03, 0x01, 0x03, 0x01, 0x09, 0x01, 0x05, 0x05, 0x08, 0x05, 0x02, 0x09};

I have tried to convert token bytes to octal digit :

- unsigned char token[20] = {001, 007, 010, 001, 003, 000, 003, 004, 003, 001, 003, 001, 011, 001, 005, 005, 010, 005, 002, 011};
- unsigned char token[20] = {0x01, 0x07, 0x10, 0x01, 0x03, 0x00, 0x03, 0x04, 0x03, 0x01, 0x03, 0x01, 0x11, 0x01, 0x05, 0x05, 0x10, 0x05, 0x02, 0x11};
- unsigned char token[20] = {01, 07, 10, 01, 03, 00, 03, 04, 03, 01, 03, 01, 11, 01, 05, 05, 10, 05, 02, 11};

All results of com_method are same :
:com_method failed. 12

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

Can you add a trace from the sent bytes so I can check what is wrong?
BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I'm trying with this token now : 0571 8854 5901 9721 1241

Here's my code :

gxTokenGateway objToken;
dlmsVARIANT params;
var_init(&params);
unsigned char token[20] = {0x00, 0x05, 0x07, 0x01, 0x08, 0x08, 0x05, 0x04, 0x05, 0x09, 0x00, 0x01, 0x09, 0x07, 0x02, 0x01, 0x01, 0x02, 0x04, 0x01};
var_addBytes(&params, token, sizeof(token));
cosem_init(BASE(objToken), DLMS_OBJECT_TYPE_TOKEN_GATEWAY, "0.0.19.40.0.255");
com_method(BASE(objToken), 1, &params);
com_read(BASE(objToken), 2);
data = bb_toHexString(&objToken.token);
GXTRACE(PSTR("Ori token : "), data);
Serial.println();
obj_clear(BASE(objToken));
free(data);

Here's trace from sent bytes :

[DEBUG][TX] : 7E A0 41 2 47 9 54 97 CD E6 E6 0 CB 32 30 0 0 0 2 EA F1 77 DC 3B 13 F8 6A 86 9A C1 E0 95 92 6E D2 7D 80 47 58 6F 99 9E D9 47 C7 BD 6A 84 2F 37 3 7A DC 26 AE 6D 6D C0 60 B5 46 BC 93 89 CE 44 7E
[DEBUG][RX] : 7E A0 25 9 2 47 74 9E 43 E6 E7 0 CF 16 30 0 0 0 75 CB AB 1C 3E 80 A BD 1C 97 20 D4 9E 32 3 C5 A5 63 AA 79 7E
:com_method failed. 12

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

The message is encrypted so I can't check the bytes. You need to share the block cipher and authentication keys if you want me to analyze the bytes.

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

I just sent the block cipher and authentication keys by email to [email removed] with subject "Credentials For Token Gateway Analysis" from me ([email removed])

Thank you very much for your help

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

Thank you for the hex trace. Now I know the reason. Data type and length are missing from the message and I didn't remember that you need to add them in ANSI C. This will work:

unsigned char token[20] = {0x00, 0x05, 0x07, 0x01, 0x08, 0x08, 0x05, 0x04, 0x05, 0x09, 0x00, 0x01, 0x09, 0x07, 0x02, 0x01, 0x01, 0x02, 0x04, 0x01};
gxByteBuffer b;
BYTE_BUFFER_INIT(bb);
if ((ret = bb_setUInt8(data.byteArr, DLMS_DATA_TYPE_OCTET_STRING)) == 0 &&
(ret = hlp_setObjectCount(sizeof(token), &bb)) == 0 &&
(ret = bb_set(&bb, token, sizeof(token))) == 0)
{
}

dlmsVARIANT params;
var_init(&params);
var_addOctetString(&params, &bb);

BR,
Mikko

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

The code bb_setUInt8(data.byteArr, DLMS_DATA_TYPE_OCTET_STRING) causing an error so I edited to bb_setUInt8(&bb, DLMS_DATA_TYPE_OCTET_STRING).

After I tried, the token still didn't work to remove the tamper, but at least com_method returns 0 and words "GAGAL" (in Bahasa Indonesia) or FAILED, appears in the LCD's meter. This is what we usually find if we fail to enter the token.

Here's the hex byte trace :

[DEBUG][TX] : 7E A0 43 2 47 9 54 1F DB E6 E6 0 CB 34 30 0 0 0 2 EA F1 77 DC 3B 13 F8 6A 86 9A C1 E0 95 9B 7F D5 79 8F 4E 55 63 99 93 DC 4F CE BB 61 82 2C 34 6 79 3E 9F 7E F D6 9C 27 EC 63 45 1 38 D9 D0 40 92 7E
[DEBUG][RX] : 7E A0 2E 9 2 47 74 72 4 E6 E7 0 CF 1F 30 0 0 0 88 6E A7 A2 FD E9 B1 72 65 6F 57 CC D1 9F CC 57 E3 88 C9 E5 79 22 85 50 89 36 E9 11 67 7E

would you like to analyze again the hex trace?
Thank you Mikko

Profile picture for user Kurumi

Kurumi

4 years 9 months ago

Hi,

Hi,

Now your data looks correct. Can you add GXDLMDirector trace from this? Only the method is enough.

BR,
Mikko

<ActionRequest>
<ActionRequestNormal>
# Priority: High, ServiceClass: UnConfirmed, Invoke ID: 1
<InvokeIdAndPriority Value="81" />
<MethodDescriptor>
# TokenGateway
<ClassId Value="0073" />
# 0.0.19.40.0.255
<InstanceId Value="0000132800FF" />
<MethodId Value="01" />
</MethodDescriptor>
<MethodInvocationParameters>
<OctetString Value="0005070108080504050900010907020101020401" />
</MethodInvocationParameters>
</ActionRequestNormal>
</ActionRequest>

elvandry13

4 years 9 months ago

Hi Mikko,

Hi Mikko,

This is solved after I convert the token to ASCII digit.
Thank you very much for your help!

  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Tue, 06/09/2026 - 11:16
    gurux.dlms.java 4.0.95
  • Tue, 06/09/2026 - 10:03
    Gurux.DLMS.Python 1.0.199
  • Mon, 06/08/2026 - 13:39
    gurux.dlms.cpp 9.0.2606.0801
  • Mon, 06/01/2026 - 10:15
    gurux.dlms.cpp 9.0.2606.0101
  • Thu, 05/28/2026 - 16:06
    gurux.dlms.java 4.0.94

New forum topics

  • Error reading L&G Meter
  • Pass a TCP Client to GXNet
  • Australian EDMI Mk10D (Essential Energy area)
  • Strange mix of data notificiation vs get response
  • DLMS Connection
More

Who's new

  • Tuanhgg
  • Adel
  • charnon
  • Paddles
  • Miguel Ángel
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin