I am trying to use zigbee protocol , to establish a communication between two vehicles as a part of Inter vehicle communication as in VANET. So , as i am very new to this I am wondering that :
a. Do i have to program my Zigbee interface to establish the communication?
b. Is it possible to program a zigbee interface?
c. Can anyone give me a general idea of how to establish (using programming language) communication between two zigbees.?
Any help would be appreciated.
a. To establish a connection and doing simple sending / receiving data (between 2 interface / module), you don't need to program your ZigBee interface (for example XBee). Just configure them with XCTU. But, if you want to make them to communicate to each other as you like (with your own rule), you have to program them.
b. If you have XBee module(s), then you can use xbee-api which is based on Java. For other module, please take a look to your module's documentation.
c. This sample is taken from xbee-api web page (sample code), which is using Java Programming language. What this code doing is searching all nearby module(s) (node discovering):
/**
* Copyright (c) 2008 Andrew Rapp. All rights reserved.
*
* This file is part of XBee-API.
*
* XBee-API is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* XBee-API is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBee-API. If not, see <http://www.gnu.org/licenses/>.
*/
package com.rapplogic.xbee.examples.zigbee;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import com.rapplogic.xbee.api.ApiId;
import com.rapplogic.xbee.api.AtCommand;
import com.rapplogic.xbee.api.AtCommandResponse;
import com.rapplogic.xbee.api.PacketListener;
import com.rapplogic.xbee.api.XBee;
import com.rapplogic.xbee.api.XBeeException;
import com.rapplogic.xbee.api.XBeeResponse;
import com.rapplogic.xbee.api.zigbee.ZBNodeDiscover;
import com.rapplogic.xbee.util.ByteUtils;
/**
* Example of performing a node discover for Series 2 XBees.
* You must connect to the coordinator to run this example and
* have one or more end device/routers that are associated.
*
* #author andrew
*
*/
public class ZBNodeDiscoverExample {
private final static Logger log = Logger.getLogger(ZBNodeDiscoverExample.class);
private XBee xbee = new XBee();
public ZBNodeDiscoverExample() throws XBeeException, InterruptedException {
try {
// replace with your serial port
xbee.open("/dev/tty.usbserial-A6005v5M", 9600);
// get the Node discovery timeout
xbee.sendAsynchronous(new AtCommand("NT"));
AtCommandResponse nodeTimeout = (AtCommandResponse) xbee.getResponse();
// default is 6 seconds
int nodeDiscoveryTimeout = ByteUtils.convertMultiByteToInt(nodeTimeout.getValue()) * 100;
log.info("Node discovery timeout is " + nodeDiscoveryTimeout + " milliseconds");
log.info("Sending Node Discover command");
xbee.sendAsynchronous(new AtCommand("ND"));
// NOTE: increase NT if you are not seeing all your nodes reported
List<? extends XBeeResponse> responses = xbee.collectResponses(nodeDiscoveryTimeout);
log.info("Time is up! You should have heard back from all nodes by now. If not make sure all nodes are associated and/or try increasing the node timeout (NT)");
for (XBeeResponse response : responses) {
if (response instanceof AtCommandResponse) {
AtCommandResponse atResponse = (AtCommandResponse) response;
if (atResponse.getCommand().equals("ND") && atResponse.getValue() != null && atResponse.getValue().length > 0) {
ZBNodeDiscover nd = ZBNodeDiscover.parse((AtCommandResponse)response);
log.info("Node Discover is " + nd);
}
}
}
} finally {
xbee.close();
}
}
public static void main(String[] args) throws XBeeException, InterruptedException {
PropertyConfigurator.configure("log4j.properties");
new ZBNodeDiscoverExample();
}
}
Related
I try to get an UART IP core in combination with the NIOS2 (softcore) running on the Cyclone 10 LP evaluation board.
So far everything works fine in polling mode. However, I cannot manage to get the interrupts running on the softcore.
The FPGA is configured in the following way.
From the picture it can be seen, that the interrupt line is connected to the NIOS2 softcore processor.
The following picture shows that the Altera UART driver is available.
The initalization code provided by Altera looks like the following.
/*
* Initialize the interrupt controller devices
* and then enable interrupts in the CPU.
* Called before alt_sys_init().
* The "base" parameter is ignored and only
* present for backwards-compatibility.
*/
void alt_irq_init ( const void* base )
{
ALTERA_NIOS2_GEN2_IRQ_INIT ( NIOS2E, nios2e);
alt_irq_cpu_enable_interrupts();
}
/*
* Initialize the non-interrupt controller devices.
* Called after alt_irq_init().
*/
void alt_sys_init( void )
{
ALTERA_AVALON_JTAG_UART_INIT ( JTAG_UART, jtag_uart);
ALTERA_AVALON_UART_INIT ( UART_0, uart_0);
ALTERA_REMOTE_UPDATE_INIT ( REMOTE_UPDATE_0, remote_update_0);
}
To enable interrupts you have to disable the reduced drivers in the BSP Editor of NIOS2. One might assume, that if you connect the interrupt line in Quartus Prime this will be considered in the NIOS2EDS Project. Unfortunately this is not the case.
I am using mpu6050 for my project but it shows following error -
Testing device connections...
MPU6050 connection failed
this error is showed only when iI am trying to use object of MPU6050
but when I don't use instance of MPU6050 and use Wire library instead (like follow) it works -
Wire.begin(); // Initialize communication
Wire.beginTransmission(MPU); // Start communication with MPU6050 // MPU=0x68
Wire.write(0x6B); // Talk to the register 6B
Wire.write(0x00); // Make reset - place a 0 into the 6B register
Wire.endTransmission(true); //end the transmission
but I want to use this code -
mpu.initialize(); //start MPU
Serial.println(F("Testing device connections...")); //debugging serial statement
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(0);
mpu.setYGyroOffset(0);
mpu.setZGyroOffset(0);
mpu.setZAccelOffset(1688);
please help me
I had the same problem.
The problem comes from those lines in the MPU6050.cpp file. You can find it in your sketchbook folder.
To do so: Open the Arduino IDE then File > Preferences > Sketchbook location.
//I2Cdev device library code is placed under the MIT license
//Copyright (c) 2012 Jeff Rowberg
/** Verify the I2C connection.
* Make sure the device is connected and responds as expected.
* #return True if connection is valid, false otherwise
*/
bool MPU6050::testConnection() {
return getDeviceID() == 0x34;
}
This is the getDeviceId function
//I2Cdev device library code is placed under the MIT license
//Copyright (c) 2012 Jeff Rowberg
/** Get Device ID.
* This register is used to verify the identity of the device (0b110100, 0x34).
* #return Device ID (6 bits only! should be 0x34)
* #see MPU6050_RA_WHO_AM_I
* #see MPU6050_WHO_AM_I_BIT
* #see MPU6050_WHO_AM_I_LENGTH
*/
uint8_t MPU6050::getDeviceID() {
I2Cdev::readBits(devAddr, MPU6050_RA_WHO_AM_I, MPU6050_WHO_AM_I_BIT, MPU6050_WHO_AM_I_LENGTH, buffer);
return buffer[0];
}
I just modified the testConnection function to return true, and it worked for me.
//I2Cdev device library code is placed under the MIT license
//Copyright (c) 2012 Jeff Rowberg
bool MPU6050::testConnection() {
return true;
}
The problem is that the device identifier is not 0x34 (in my case it is 0x39).
In order not to "cheat" I made the following change:
Comment out this line:
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
And inserted these lines:
Serial.print("DeviceID: ");
Serial.println(accelgyro.getDeviceID());
So the program will write the device identifier instead of giving a response that it didn't find device 0x34.
I implemented vimeo networking using vimeo networking library(https://github.com/vimeo/vimeo-networking-java), exoplayer and explained in this post https://stackoverflow.com/a/65737556/8814924
Now the problem is when I was checking with API 30 it was getting error
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.emergingit.emergingstudy/com.emergingit.emergingstudy.activities.course.ExoPlayerActivity}: java.lang.IllegalStateException: Unable to extract the trust manager on Android10Platform, sslSocketFactory is class com.android.org.conscrypt.OpenSSLSocketFactoryImpl
Caused by: java.lang.IllegalStateException: Unable to extract the trust manager on Android10Platform, sslSocketFactory is class com.android.org.conscrypt.OpenSSLSocketFactoryImpl
which indicates the error on
VimeoClient.initialize(configuration);
which issue is dicscussed here : https://github.com/square/okhttp/issues/5878 , issue discussion :
I assume you are calling the deprecated form of sslSocketFactory, which is broken on newer Android versions. https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/OkHttpClient.kt#L719
/**
* Sets the socket factory used to secure HTTPS connections. If unset, the system default will
* be used.
*
* #deprecated [SSLSocketFactory] does not expose its [X509TrustManager], which is a field that
* OkHttp needs to build a clean certificate chain. This method instead must use reflection
* to extract the trust manager. Applications should prefer to call
* `sslSocketFactory(SSLSocketFactory, X509TrustManager)`, which avoids such reflection.
*/
#Deprecated(
message = "Use the sslSocketFactory overload that accepts a X509TrustManager.",
level = DeprecationLevel.ERROR
)
fun sslSocketFactory(sslSocketFactory: SSLSocketFactory) = apply {
if (sslSocketFactory != this.sslSocketFactoryOrNull) {
this.routeDatabase = null
}
this.sslSocketFactoryOrNull = sslSocketFactory
this.certificateChainCleaner = Platform.get().buildCertificateChainCleaner(sslSocketFactory)
}
is there any solution possible with using the current version "1.1.3" of networking library for this or I have to wait till the library update ?
I primarily Solved the problem for Vimeo video streaming on the Android 10 platform using the Vimeo-Networking library (v1.1.3).
as the main problem is in the OkHttpClient build method
builder.sslSocketFactory(sSLSocketFactory);
//RetrofitClientBuilder.java#186
where with 1 parameter version is depricated and I needed to pass X509TTrustManager as 2nd parameter like this :
builder.sslSocketFactory(sSLSocketFactory, new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
});
So it solved my problem till this update comes in the stable version of this library. How I implemented this is described below :
Error was showing on VimeoClient.initialize(accessToken); line and I searched about the error and find out that it is caused because of this OkHttpClient method deprecation (with 1 parameter).
So I went into VimeoClient.java and saw in its constructor private Retrofit createRetrofit() was called and inside it private OkHttpClient createOkHttpClient() was called. and there public class RetrofitClientBuilder object was created and it's problemetic method was public OkHttpClient build() in which : if (sSLSocketFactory != null) { builder.sslSocketFactory(sSLSocketFactory); }
this deprecated method was called.
So I just had to create 2 new java file with name VimeoClientUpdated.java and RetrofitClientBuilderUpdated.java which is just a renamed copy of VimeoClient.java and RetrofitClientBuilder.java and now my RetrofitClientBuilderUpdated.java has no deprecated method rather the correct and VimeoClientUpdated.java is calling RetrofitClientBuilderUpdated.java
(I couldn't extend because of the final class and couldn't even wrap the class as to the gateway to that solution, I had to face the private method which wasn't possible to alter in wrapper class)
and finally just instead of calling VimeoClient.initialize(accessToken) I am calling my newly created VimeoClientUpdated(accessToken) which won't crash while playing Vimeo video on Android 10.
Suggest me if there is a better way of serving my purpose (solving deprecated library method calling from the android activity).
Cheers..!!
I want to read the values of some Cortex-A53 registers, such as
D_AA64ISAR0_EL1 (AArch64)
ID_ISAR5 (Aarch32)
ID_ISAR5_EL1 (Aarch64)
Unfortunately, I lack a little embedded/assembly experience. The documentation reveals
To access the ID_AA64ISAR0_EL1:
MRS , ID_AA64ISAR0_EL1 ; Read ID_AA64ISAR0_EL1 into Xt
ID_AA64ISAR0_EL1[31:0] can be accessed through the internal memory-mapped interface
and the external debug interface, offset 0xD30.
I decided to utilize devmem2 on my target (since busybox does not include the devmem applet). Is the following procecure correct to read the register?
devmem2 0xD30
The part which I am unsure about is using the "offset" as a direct physical address. If it is the actual address, why call if "offset" and not "address". If it's an offset, what is the base address? I am 99% certain this is not the correct procedure, but how do I know the base address to add the offset to? I have searched the Armv8 technical reference manual and A53 MPCore documents to no avail. The explain the register contents in detail but seem to assume you read them from ASM using the label ID_AA64ISAR0_EL1.
Update:
I found this:
Configuration Base Address Register, EL1
The CBAR_EL1 characteristics are:
Purpose Holds the physical base address of the memory-mapped GIC CPU
interface registers.
But it simply duplicates my problem, how to read this other register?
Update 2:
The first update seems relevant only for GIC and not for configuration registers I am trying to read (I misunderstood the information I think).
For the specific problem at hand (checking crypto extension availability) one may simply cat /proc/cpuinfo and look for aes/sha etc.
Update 3:
I am now investigating http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0176c/ar01s04s01.html, as well as the base address being SoC specific and thus may be found in the reference manual of the SoC.
Update 4:
Thanks to the great answer I seem to be able to read data via my kernel module:
[ 4943.461948] ID_AA64ISA_EL1 : 0x11120
[ 4943.465775] ID_ISAR5_EL1 : 0x11121
P.S.: This was very insightful, thank you again!
Update 5:
Source code as per request:
/******************************************************************************
*
* Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*****************************************************************************/
#include <linux/module.h>
#include <linux/types.h>
/*****************************************************************************/
// read system register value ID_AA64ISAR0_EL1 (s3_0_c0_c6_0).
static inline uint64_t system_read_ID_AA64ISAR0_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, ID_AA64ISAR0_EL1" : "=r" (val));
return val;
}
// read system register value ID_ISAR5_EL1 (s3_0_c0_c2_5).
static inline uint64_t system_read_ID_ISAR5_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, s3_0_c0_c2_5" : "=r" (val));
return val;
}
/*****************************************************************************/
int init_module(void)
{
printk("ramdump Hello World!\n");
printk("ID_AA64ISAR0_EL1 : 0x%llX\n", system_read_ID_AA64ISAR0_EL1());
printk("ID_ISAR5_EL1 : 0x%llX\n", system_read_ID_ISAR5_EL1());
return 0;
}
void cleanup_module(void)
{
printk("ramdump Goodbye Cruel World!\n");
}
MODULE_LICENSE("GPL");
Disclaimer: I am not an Aarch64 expert, but I am currently learning about the architecture and have read a bit.
You cannot read ID_AA64ISAR0_EL1, ID_ISAR5_EL1 nor ID_ISAR5 from a user-mode application running at EL0: the _EL1 suffix means than running at least at EL1 is required in order to be allowed to read those two registers.
You may find helpful to read the pseudo-code in the arm documentation here and here.
In the case of ID_ISAR5 for example, the pseudo-code is very explicit:
if PSTATE.EL == EL0 then
UNDEFINED;
elsif PSTATE.EL == EL1 then
if EL2Enabled() && !ELUsingAArch32(EL2) && HSTR_EL2.T0 == '1' then
AArch64.AArch32SystemAccessTrap(EL2, 0x03);
elsif EL2Enabled() && ELUsingAArch32(EL2) && HSTR.T0 == '1' then
AArch32.TakeHypTrapException(0x03);
elsif EL2Enabled() && !ELUsingAArch32(EL2) && HCR_EL2.TID3 == '1' then
AArch64.AArch32SystemAccessTrap(EL2, 0x03);
elsif EL2Enabled() && ELUsingAArch32(EL2) && HCR.TID3 == '1' then
AArch32.TakeHypTrapException(0x03);
else
return ID_ISAR5;
elsif PSTATE.EL == EL2 then
return ID_ISAR5;
elsif PSTATE.EL == EL3 then
return ID_ISAR5;
One easy way to read those register would be to write a tiny loadable kernel module you could call from your user-mode application: Since the Linux kernel is running at EL1, it is perfectly able to read those three registers.
See for example this article for a nice introduction to Linux loadable kernel modules.
And this is likely that an application running at EL0 cannot access memory-mapped registers accessible only from EL1, since this would obviously break the protection scheme.
The C code snippets required to read those registers in Aarch64 state would be (tested with gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu) :
#include <stdint.h>
// read system register value ID_AA64ISAR0_EL1 (s3_0_c0_c6_0).
static inline uint64_t system_read_ID_AA64ISAR0_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, s3_0_c0_c6_0" : "=r" (val));
return val;
}
// read system register value ID_ISAR5_EL1 (s3_0_c0_c2_5).
static inline uint64_t system_read_ID_ISAR5_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, s3_0_c0_c2_5" : "=r" (val));
return val;
}
Update #1:
The GCC toolchain does not understand all arm system register names, but can nevertheless properly encode system registers access instructions if specified which exact values of the coproc, opc1, CRn, CRm, and opc2 fields are associated to this register.
In the case of ID_AA64ISAR0_EL1, the values specified in the ArmĀ® Architecture Registers Armv8, for Armv8-A architecture profile document are:
coproc=0b11, opc1=0b000, CRn=0b0000, CRm=0b0110, opc2=0b000
The system register alias would then be s[coproc]_[opc1]_c[CRn]_c[CRm]_[opc2], that is s3_0_c0_c6_0 in the case of ID_AA64ISAR0_EL1.
I see this tool maybe meets your need:
system-register-tools
It just provides reading and writing system registers function for arm64, likes MSR-tools in x86.
I am trying to build an SRTP to RTP stream converter and I am having issues getting the Master Key from the WebRTC peerconnection I am creating.
From what I understand, with a DES exchange, the key is exchange via the SDP exchange and is shown in the a=crypto field. So, this situation seems pretty straight forward(please correct me if I am wrong), but ultimately useless as WebRTC standardization is now demanding that DES should not be used(only Chrome supports it now and it may be removed in the future).
For DTLS there is the fingerprint field in the SDP, is that a hash of the certificate desired to be utilized in the future exchange?[EDIT: After doing some reading, I am thinking that that is not the case] I would think with knowledge of the fingerprint along side the ability to parse through the DTLS packets in the exchange I should be able to grab the Master Key to decode the SRTP stream, but I am hitting a wall as I do not know where to look or even 100% sure if it is possible.
So, in short, is it even feasible(without getting into the lower C++ API and creating my own implementation of WebRTC) to decode the SRTP feed that is created with a WebRTC PeerConnection in Chrome and FireFox(possibly through packet sniffing with the information gleaned from the SDP exchange)?[EDIT: depressingly, it seems that access to the private part of the key(aka, the master key) is not possible...please correct if I am wrong]
tHere is some code using openssl and libsrtp native api
#define SRTP_MASTER_KEY_KEY_LEN 16
#define SRTP_MASTER_KEY_SALT_LEN 14
static void dtls_srtp_init( struct transport_dtls *dtls )
{
/*
When SRTP mode is in effect, different keys are used for ordinary
DTLS record protection and SRTP packet protection. These keys are
generated using a TLS exporter [RFC5705] to generate
2 * (SRTPSecurityParams.master_key_len +
SRTPSecurityParams.master_salt_len) bytes of data
which are assigned as shown below. The per-association context value
is empty.
client_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
server_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
client_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
server_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
*/
int code;
err_status_t err;
srtp_policy_t policy;
char dtls_buffer[SRTP_MASTER_KEY_KEY_LEN * 2 + SRTP_MASTER_KEY_SALT_LEN * 2];
char client_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
char server_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
size_t offset = 0;
/*
The exporter label for this usage is "EXTRACTOR-dtls_srtp". (The
"EXTRACTOR" prefix is for historical compatibility.)
RFC 5764 4.2. Key Derivation
*/
const char * label = "EXTRACTOR-dtls_srtp";
SRTP_PROTECTION_PROFILE * srtp_profile= SSL_get_selected_srtp_profile( dtls->ssl );
/* SSL_export_keying_material exports a value derived from the master secret,
* as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
* optional context. (Since a zero length context is allowed, the |use_context|
* flag controls whether a context is included.)
*
* It returns 1 on success and zero otherwise.
*/
code = SSL_export_keying_material(dtls->ssl,
dtls_buffer,
sizeof(dtls_buffer),
label,
strlen( label),
NULL,
0,
PJ_FALSE);
memcpy(&client_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
offset += SRTP_MASTER_KEY_KEY_LEN;
memcpy(&server_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
offset += SRTP_MASTER_KEY_KEY_LEN;
memcpy(&client_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
offset += SRTP_MASTER_KEY_SALT_LEN;
memcpy(&server_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
switch( srtp_profile->id )
{
case SRTP_AES128_CM_SHA1_80:
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
break;
case SRTP_AES128_CM_SHA1_32:
crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32,
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80
break;
default:
assert(0);
}
policy.ssrc.value = 0;
policy.next = NULL;
/* Init transmit direction */
policy.ssrc.type = ssrc_any_outbound;
policy.key = client_write_key;
err = srtp_create(&dtls->srtp_ctx_rx, &policy);
if (err != err_status_ok) {
printf("not working\n");
}
/* Init receive direction */
policy.ssrc.type = ssrc_any_inbound;
policy.key = server_write_key;
err = srtp_create(&dtls->srtp_ctx_tx, &policy);
if (err != err_status_ok) {
printf("not working\n");
}
}
I found 'SSL_export_keying_material'
Which can take a key from SSL mechanism (after DTLS handshake) and use it for SRTP.
I am not an expert, Just hitting the wall like you...
It's not clear if this is your case, but note it's not possible to access the audio/video from (i.e.:unencrypt) the SRTP merely being a passive observer - that's the whole point of having transport encryption.
The protocol (DTLS-SRTP) works roughly like this:
each browser has a unique keypair, usually generated on installation time
The fingerprint of the public part of the keypair of each side in included in the SDP, in the offer and answer.
Both ends negotiate a DTLS connection, through a ordinary DTLS handshake, thus deriving a kind of session key, which is used to secure the (DTLS) connection
The derived session key is used as the SRTP key
If you don't have access to at least one of the private parts of the keypairs, it's not possible at all to decrypt the connection. If the endpoints choose to use a Diffie-Hellman key exchange on the handshake, a passive attacker will not be able to get the derived key, even with access to both private keys. This property is called forward secrecy.
The only reliable way of accessing the SRTP contents is doing the handshake yourself, implementing a active MITM (changing the fingerprints on the SDP) or getting the private key from the browser and restricting DH key-exchange (which, AFAIK, is not possible at all)