Renault Zoe doesn't send SDP Request After SLAC Matching Process - embedded

We are trying to communicate with Renault Zoe according to DIN SPEC 70121.
We are successfully communciating with the Hyundai Kona and BMW i3 but fail to receive the SPD Request with Renault Zoe. We are passing the SLAC process with Renault Zoe but we don't recieve any UDP messages afterwards. We are sending the CM_SLAC_MATCH_CNF message as an ethernet unicast message according to DIN SPEC 70121:2014-12, 8.3.3.3.2, Table 2 (noted in Design Guide Combined Charging System V5 - Failures during SLAC - Interruption at SLAC match sequence).
Why can it be that we receive the SDP Request with Kona and i3 but fail to do so with Zoe? Has anyone experienced this behaviour before?
Sniffed SLAC messages with scapy:
(= '' means the field is filled with zeroes)
Received from Zoe:
###[ CM_SLAC_MATCH_REQ ]###
ApplicationType= 0
SecurityType= 0
MatchVariableFieldLen= 15872
\VariableField\
|###[ SLAC_varfield ]###
| EVID = ''
| EVMAC = 7c:bc:84:41:03:3b
| EVSEID = ''
| EVSEMAC = 3e:7e:f1:10:ab:3e
| RunID = '\xd3\xac;\x0f\x17-\xb7+'
| RSVD = ''
Send to Zoe:
###[ CM_SLAC_MATCH_CNF ]###
ApplicationType= 0
SecurityType= 0
MatchVariableFieldLen= 86
\VariableField\
|###[ SLAC_varfield ]###
| EVID = ''
| EVMAC = 7c:bc:84:41:03:3b
| EVSEID = ''
| EVSEMAC = 3e:7e:f1:10:ab:3e
| RunID = '\xd3\xac;\x0f\x17-\xb7+'
| RSVD = ''
| NetworkID = '$\x94\xc1\x0c\xbcO\xb5'
| Reserved = 0
| NMK = ''

The solution was to send the 2 byte field MatchVariableFieldLen in the CM_SLAC_MATCH_CNF message in little-endian byte order.
From the message that was send by the Renault Zoe, we can see that Zoe sends the CM_SLAC_MATCH_REQ with the MatchVariableFieldLen as 0x3e 0x00 (15872 == 0x3e00). Since this field should be 0x3e according to DIN SPEC 2014-12, we can see the byte order of this field is little-endian. So a reasonable guess was that it expects this field in little-endian in the response message.
Result: We received the SDP request and the messages after that.
The HomePlug GP Specification does not specify the endianness of this field in clause 11.5.58. But looking at the example in Table 11-316, one would say its big-endian.
It's clear that Zoe interpret this field as little-endian and doesn't accept 0x00 0x56 but accepts 0x56 0x00.
Kona and i3 either don't complain about this field and accept the message or Zoe's intepreting is false. Either way the cause of the problem has been identified.

Related

Defender KQL to show blocked Bluetooth Devices with all relevant fields

I'm trying to write a query to report on BlueToothPolicyTriggered events, that will return all the details to show when a device was blocked by policy AND the details of that device.
Our BT policy basically should allow everything but block file transfer over BT. That seems to be working as expected, but before rolling out wider, want a quick way to 'see' if any other devices are being blocked incorrectly or be able to refer to it if a user reports an issue so we can get all the details of the device blocked to add an exception etc.
However (and I'm new to kql) it seems once I filter a table using an 'ActionType' the columns available to report on are restricted, and in this case we lose details of the BT device that has been blocked
This shows all events that have triggered the policy and whether it was 'accepted' or 'blocked' but not the details of the device
search in (DeviceEvents) ActionType == "BluetoothPolicyTriggered"
| extend parsed=parse_json(AdditionalFields)
| extend Result = tostring(parsed.Accepted)
| extend BluetoothMACAddress = tostring(parsed.BluetoothMacAddress)
| extend PolicyName = tostring(parsed.PolicyName)
| extend PolicyPath = tostring(parsed.PolicyPath)
| summarize arg_max(Timestamp, *) by DeviceName, BluetoothMACAddress
| sort by Timestamp desc
| project Timestamp, DeviceName, DeviceId, Result, ActionType, BluetoothMACAddress, PolicyPath, PolicyName, ReportId
Then I have this which will show every BT connection, the device details im looking for, but not whether it was blocked or accepted
DeviceEvents
| extend parsed=parse_json(AdditionalFields)
| extend MediaClass = tostring(parsed.ClassName)
| extend MediaDeviceId = tostring(parsed.DeviceId)
| extend MediaDescription = tostring(parsed.DeviceDescription)
| extend MediaSerialNumber = tostring(parsed.SerialNumber)
| where MediaClass == "Bluetooth"
| project Timestamp, DeviceId, DeviceName, MediaClass, MediaDeviceId, MediaDescription, parsed
| order by Timestamp desc
Ive been trying to somehow join these together (despite being the same DeviceEvents table) with not much success. I don't trust the output as im seeing entries saying a device was blocked when I know it wasnt.
DeviceEvents
| where ActionType == "BluetoothPolicyTriggered"
| extend parsed=parse_json(AdditionalFields)
| extend Result = tostring(parsed.Accepted)
| extend BluetoothMACAddress = tostring(parsed.BluetoothMacAddress)
| extend PolicyName = tostring(parsed.PolicyName)
| extend PolicyPath = tostring(parsed.PolicyPath)
| project Timestamp, DeviceName, DeviceId, Result, ActionType, BluetoothMACAddress, PolicyPath, PolicyName, ReportId
| join kind =inner (DeviceEvents
| extend parsed=parse_json(AdditionalFields)
| extend MediaClass = tostring(parsed.ClassName)
| extend MediaDeviceId = tostring(parsed.DeviceId)
| extend MediaDescription = tostring(parsed.DeviceDescription)
| extend MediaSerialNumber = tostring(parsed.SerialNumber)
) on DeviceName
| where MediaClass == "Bluetooth"
| project Timestamp, DeviceName, Result, ActionType, MediaClass, MediaDeviceId, MediaDescription,BluetoothMACAddress
| sort by Timestamp desc
Am i going about this completely wrong ?

KQL - return entries not matching IP from watchlist (query optimization)

I want to receive a high severity alert in Sentinel when a user is added to a defined "high severity" group (via watchlist), however, I want to omit any users that are connected to a Zscaler IP address. The query below is working, however, I'm not sure this is the neatest/most optimized logic. Is there a shorter/better way to write this?
I'm only concerned about the lines beginning with asterisks (which are only added for clarity).
watchlist "aadgroups"
Group
Severity
Prod Owners
High
Prod Contributors
High
watchlist "ZSIPs"
zscaler_ip
location
165.225.0.0/23
Chicago
165.225.60.0/22
Chicago
165.225.56.0/22
Chicago
let HighSeverityGroups = (_GetWatchlist('aadgroups') | where severity == "High" | project group_name, severity);
let ZSIPs = (_GetWatchlist('zscaler_ip') | project zscaler_ip);
AuditLogs
| where ActivityDisplayName == "Add member to group"
| where parse_json(tostring(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue)) has_any (HighSeverityGroups)
| extend InitiatedByActor = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend GroupName = tostring(parse_json(tostring(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue)))
| extend Actor_ipv4 = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
| project-reorder TimeGenerated,SourceSystem,InitiatedBy,ActivityDisplayName,TargetUser,GroupName,InitiatedByActor,Actor_ipv4,Result
| where TargetUser <> ""
** | evaluate ipv4_lookup(ZSIPs, Actor_ipv4, zscaler_ip, return_unmatched = true)
** | where isempty(zscaler_ip)
A couple of things you can try to optimize the query:
This filter is quite costly: | where parse_json(tostring(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue)) has_any (HighSeverityGroups) - if TargetResources will rarely have strings from HighSeverityGroups, then before this filter, you can add a much more efficient filter, that will filter out most of the records: | where TargetResources has_any (HighSeverityGroups) - this way, the heavy parsing will be done only on a small amount of records
You're parsing some of the data more than once, for example tostring(parse_json(tostring(InitiatedBy.user)) - instead, you need to use the extend operator to parse them only once, and then use later on in the query

Create a SQL column based on list of values

I am trying to create a column dependent on whether a certain value exists in a list regardless of when it occurs.
In my table currently I have:
Attendee No - unique number for every attendance Tracking Activity -
Description of Activity Tracking Date/Time - Date & Time when
Activity took place Activity Type - <<<< I need to calculate this
column based on specific logic
[Attendee No] can have multiple [Tracking Activity] & associated [Tracking Date/Time]
Table example. Tracker
+-------------+-------------------+--------------------+---------------+
| Attendee_No | Tracking Activity | Tracking Date/Time | Activity Type |
+-------------+-------------------+--------------------+---------------+
| 3623 | Eat | 05/04/2020 16:28 | Physical |
| 3623 | Music | 05/04/2020 07:16 | Physical |
| 3623 | Run | 05/04/2020 03:52 | Physical |
| 3623 | Booked in | 05/04/2020 03:42 | Physical |
| 3624 | Sleep | 05/04/2020 15:47 | Physical |
| 3624 | Walk | 05/04/2020 11:55 | Physical |
| 3624 | TV | 05/04/2020 11:54 | Physical |
| 3624 | Booked in | 05/04/2020 11:52 | Physical |
+-------------+------------------+--------------------+----------------+
Using the example above what im looking to do is:
For every Attendee No if the Tracker Activity = "Run", "Walk", "Jog", "Gym" regardless when it occurred the Activity Type should = "Physical"
im a SQL noob so have no idea what im doing really so your help will be SOOOO GRATEFULLY appreciated!
For every Attendee No if the Tracker Activity = "Run", "Walk", "Jog", "Gym" regardless when it occurred the Activity Type should = "Physical"
SELECT
CASE
WHEN activity IN('Run','Walk','Jog','Gym') THEN 'Physical'
--WHEN .... other boolean test .. THEN ... other output value...
--ELSE .. catch all value...
END as ActivityType
FROM
...
The -- is commented out - i put these things in as comments to show you how to add more cases, and how to add an else. If you want to use them, uncomment them and modify them.
CASE WHEN has to perform X number of tests and return a single value. It cannot return multiple values
CASE WHEN can also be written like:
CASE activity
WHEN 'Walk' THEN 'Physical'
WHEN 'Jog' THEN 'Physical'
...
--ELSE ...
In this format, you can only supply a single value after the WHEN, and it is compared using =. You can't CASE column WHEN > 0 THEN.. or CASE column WHEN value AND othercolumn = blah THEN..
If you want those kinds of complexity you have to use the CASE WHEN column > 0 AND othercolumn = blah THEN.. form
If you get lots of variations, or you expect to be able to add more in the future without modifying the sql, create another table that has two columns:
Activity,ActivityType
------------
Run,Physical
Walk,Physical
Jog,Physical
Gym,Physical
Study,Mental
...
And join it in:
SELECT * FROM
table t
INNER JOIN activityTypes a ON a.Activity = t.Activity
YOu can have a CASE logic to calculate the Activity Type.
As a general best practice, when you are naming the columns, avoid
below things. They will lead to issues one or other way.
Names with spaces
Keywords
Names with -
types names
SELECT [Attendee No], [Tracking Activity],[Tracking Date/Time],
CASE WHEN [Tracking Activity] IN ( 'Run', 'Walk', 'Jog', 'Gym') THEN 'Physical'
ELSE 'NOT Physical' END AS [Activity Type]
FROM Tracker
I started off with the case statement but what im getting blanks when the Tracking Activity is not in the list. I need ALL the activity type to say "Physical" if the attendee has 'Run', 'Walk', 'Jog', 'Gym' at anytime in the Attendee_No
You can use SQL CASE syntax to achieve it.
See SQL CASE on W3SCHOOLS
Modify your SQL to something like the following and it should do the trick.
SQL
SELECT Attendance_No, Tracking_date,
CASE
WHEN Tracking_activity = 'Run' THEN 'Physical'
WHEN Tracking_ctivity = 'Walk' THEN 'Physical'
WHEN Tracking_ctivity = 'Jog' THEN 'Physical'
WHEN Tracking_ctivity = 'Gym' THEN 'Physical'
ELSE `Other`
END AS 'Activity-type'
FROM Tracker

Get the reply of an outgoing message in the same row in SQL?

I am trying to get the incoming message for an outgoing message in the same row as response? So, the data looks like below:
user_id message type
1 What's your name? outgoing
1 Nitin incoming
1 What's your age? outgoing
1 17 incoming
2 What's your name? outgoing
2 Aayush incoming
2 What's your age? outgoing
3 What's your name? outgoing
4 What's your name? outgoing
4 Shubham incoming
4 What's your age? outgoing
The output should look like:
user_id message type reply
1 What's your name? outgoing Nitin
1 Nitin incoming
1 What's your age? outgoing 17
1 17 incoming
2 What's your name? outgoing Aayush
2 Aayush incoming
2 What's your age? outgoing No-reply
3 What's your name? outgoing No-reply
4 What's your name? outgoing Shubham
4 Shubham incoming
4 What's your age? outgoing No-reply
The reply is an incoming message for an outgoing message for a user_id & if there is no reply for an outgoing message then the reply column should be filled by 'No-reply'. I have to do this in PSQL. I am currently able to do this in python after fetching data from DB.
Below is my current python code.
df['reply'] = np.where((df['user_id'] == df['user_id'].shift(-1))
& (df['type'].eq('Outgoing') & df['type'].shift(-1).eq('Incoming')),
df['message'].shift(-1), 'No-reply')
Assuming that you have a column that can be used to order the records (called id), you could use lead() as follows:
select
t.*,
case
when type = 'outgoing'
and lead(type) over(partition by user_id order by id) = 'incoming'
then lead(message) over(partition by user_id order by id)
when type = 'outgoing' then 'no reply'
end reply
from mytable
This query checks if the current record has type outgoing and if the next one (for the same user) is of type incoming: if both conditions are true, then it recovers the message on the next record and displays it as reply. If type is outgoing but the next message is not incoming, then it gives no reply. In other cases, nothing is printed.

WCF Duplex communication with InterSystems

Can someone point me to a sample of how to call a WCF service using wsDualHttpBinding? I created the classes using the SOAP Client Wizard and everything compiles. When I run the objectscript code, it hangs on the web service call for a while (it's hitting a timeout) and returns an exception:
| oref value: 4
| class name: %Exception.SystemException
| OID: ""
| reference count: 2 (system)
+----------------- attribute values ------------------
| Code = 64
| Data = ""
| InnerException = ""
| Location = "zInvokeClient+349^Service.WSDualHttpBindingIService.1"
| Name = ""
and %objlasterror gives:
0 3"%zRead+31^%Net.HttpRequest.1:SAMPLES
LOCATION is set to "http://localhost:8733/Design_Time_Addresses/PNServices/Service1/"
Any idea/clues?
Just a slight advice: Try using w ##class(%SYSTEM.Status).GetErrorText(status) where status is for example %objlasterror or sc. It is somewhat human readable unlike the status itself.