M7350/wlan/tools/dsrc/dsrc_config.c
2024-09-09 08:57:42 +00:00

662 lines
24 KiB
C

/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**
* @file dsrc_config.c
* @brief Configuration commands for DSRC.
*
* Configuration commands are part of the 802.11p spec. This reads all the
* user parameters for a control command, process those into a format exposed
* by the dsrc_nl APIs and call nl80211 APIs that will do the actual
* communication with the host driver.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <time.h>
#include "dsrc_nl.h"
#define DCC_BITMAP_DEFAULT 0xff
#define TIME_ERROR_DEFAULT 0xff
#ifdef _ANDROID_
int getsubopt(char **optionp, char * const *tokens, char **valuep);
#endif
/**
* @brief UTC time conversion constant.
*
* Number of seconds from Jan 1st 1958 to Jan 2nd 1970
* This is needed to convert from the Linux UTC to 802.11
* definition of UTC time
*/
#define SEC_1958_1970 378691200
#define DEFAULT_CONTROL_CHANNEL 5860
#define DEFAULT_SERVICE_CHANNEL 5900
#define DEFAULT_CCH_GUARD_MS 4
#define DEFAULT_SCH_GUARD_MS 4
#define DEFAULT_CCH_DURATION_MS 50
#define DEFAULT_SCH_DURATION_MS 50
#define DEFAULT_CCH_TX_POWER 17
#define DEFAULT_SCH_TX_POWER 17
#define DEFAULR_QOS_BE_AIFSN 6
#define DEFAULT_QOS_BE_CWMIN 4
#define DEFAULT_QOS_BE_CWMAX 10
#define DEFAULT_QOS_BK_AIFSN 9
#define DEFAULT_QOS_BK_CWMAX 10
#define DEFAULT_QOS_BK_CWMIN 4
#define DEFAULT_QOS_VI_AIFSN 3
#define DEFAULT_QOS_VI_CWMAX 4
#define DEFAULT_QOS_VI_CWMIN 3
#define DEFAULT_QOS_VO_AIFSN 2
#define DEFAULT_QOS_VO_CWMAX 4
#define DEFAULT_QOS_VO_CWMIN 2
struct dsrc_channel {
uint32_t frequency;
uint32_t bandwidth;
uint32_t tx_power;
uint32_t sched_duration;
uint32_t sched_guard;
uint16_t flags;
struct dsrc_ocb_qos_params qos_params[DSRC_OCB_NUM_AC];
};
struct dsrc_config_params {
char *cmd;
char *interface;
char *chan_opts;
uint32_t num_channels;
uint32_t enable_dcc;
struct dsrc_channel channels[2];
uint32_t repeat_rate;
uint32_t flags;
};
/**
* Prints the command line usage message.
*/
void dsrc_config_usage()
{
printf("Usage: dsrc_config [-i <interface>] [-c <command>]\n");
printf(" [-o <channel options>] [-d] [-r repeat rate>]\n");
printf("Defaults: interface wlanocb0, channel 5860\n");
printf("-c <command> : \n");
printf(" set_config, ndl_update, get_stats, stats_event, \n");
printf(" clear_stats, set_utc, start_ta, stop_ta, get_tsf, rx_vsa\n");
printf("-o <channel options> : \n");
printf(" Used for set_config, get_stats, start_ta and stop_ta. \n");
printf(" num_channels={1|2} : \n");
printf(" when 1 channel_freq0 and channel_bandwidth0 are needed.\n");
printf(" when 2 same as 1, additionally freq1 and bandwidth1 are needed.\n");
printf(" channel_freq0=<center frequency in MHz>\n");
printf(" channel_bandwidth0=<bandwidth in MHz>\n");
printf(" tx_power0=<max transmit power in dbm>\n");
printf(" duration0=<channel schedule duration in ms>\n");
printf(" guard0=<schedule start guard interval in ms>\n");
printf(" disable_rx_stats0={0|1} : \n");
printf(" when 0 (default) RX stats headers are added.\n");
printf(" when 1 RX stats headers are not added.\n");
printf(" channel_freq1=<center frequency in MHz>\n");
printf(" channel_bandwidth1=<bandwidth in MHz>\n");
printf(" tx_power1=<max transmit power on channel_freq1>\n");
printf(" duration1=<channel schedule duration in ms>\n");
printf(" guard1=<schedule start guard interval in ms>\n");
printf(" disable_rx_stats1={0|1} : \n");
printf(" when 0 (default) RX stats headers are added.\n");
printf(" when 1 RX stats headers are not added.\n");
printf(" expiry_tsf={0|1} : \n");
printf(" when 0 (default) expiry time in TX options is relative.\n");
printf(" when 1 expiry time in TX options is interpreted as a TSF time.\n");
printf(" eth_mode={0|1} :\n");
printf(" when 0 (default) the app must send 802.11 frames and firmware will not convert.\n");
printf(" when 1 the firmware will convert 802.3 frames to 802.11.\n");
printf("-d : \n");
printf(" Enable DCC parameters if this option is present.\n");
printf(" Used for the set_config command.\n");
printf("-r <repeat rate> : \n");
printf(" Number of times the TA frame will be sent in a 5 seconds interval.\n");
printf(" Used for the start_ta command.\n");
}
int dsrc_config_get_options(int argc, char *argv[],
struct dsrc_config_params *params)
{
int c;
int rc = 0;
/* defaults */
params->interface = "wlanocb0";
params->cmd = "set_config";
while ((c = getopt(argc, argv, "c:i:o:df:r:h?")) != -1) {
switch (c) {
case 'c':
params->cmd = optarg;
break;
case 'i':
params->interface = optarg;
break;
case 'o':
params->chan_opts = optarg;
break;
case 'd':
params->enable_dcc = 1;
break;
case 'r':
params->repeat_rate = strtoul(optarg, NULL, 10);
break;
case 'h':
case '?':
default:
rc = -1;
dsrc_config_usage();
goto bail;
}
}
bail:
return rc;
}
static void dsrc_channel_init(struct dsrc_config_params *params)
{
params->num_channels = 1;
params->flags = OCB_CONFIG_FLAG_80211_FRAME_MODE;
params->channels[0].frequency = DEFAULT_CONTROL_CHANNEL;
params->channels[0].bandwidth = 10;
params->channels[0].sched_duration = DEFAULT_CCH_DURATION_MS;
params->channels[0].sched_guard = DEFAULT_CCH_GUARD_MS;
params->channels[0].tx_power = DEFAULT_CCH_TX_POWER;
params->channels[0].flags = 0;
params->channels[0].qos_params[DSRC_OCB_AC_BE].aifsn = DEFAULR_QOS_BE_AIFSN;
params->channels[0].qos_params[DSRC_OCB_AC_BE].cwmax = DEFAULT_QOS_BE_CWMAX;
params->channels[0].qos_params[DSRC_OCB_AC_BE].cwmin = DEFAULT_QOS_BE_CWMIN;
params->channels[0].qos_params[DSRC_OCB_AC_BK].aifsn = DEFAULT_QOS_BK_AIFSN;
params->channels[0].qos_params[DSRC_OCB_AC_BK].cwmax = DEFAULT_QOS_BK_CWMAX;
params->channels[0].qos_params[DSRC_OCB_AC_BK].cwmin = DEFAULT_QOS_BK_CWMIN;
params->channels[0].qos_params[DSRC_OCB_AC_VI].aifsn = DEFAULT_QOS_VI_AIFSN;
params->channels[0].qos_params[DSRC_OCB_AC_VI].cwmax = DEFAULT_QOS_VI_CWMAX;
params->channels[0].qos_params[DSRC_OCB_AC_VI].cwmin = DEFAULT_QOS_VI_CWMIN;
params->channels[0].qos_params[DSRC_OCB_AC_VO].aifsn = DEFAULT_QOS_VO_AIFSN;
params->channels[0].qos_params[DSRC_OCB_AC_VO].cwmax = DEFAULT_QOS_VO_CWMAX;
params->channels[0].qos_params[DSRC_OCB_AC_VO].cwmin = DEFAULT_QOS_VO_CWMIN;
params->channels[1].frequency = DEFAULT_SERVICE_CHANNEL;
params->channels[1].bandwidth = 10;
params->channels[1].sched_duration = DEFAULT_SCH_DURATION_MS;
params->channels[1].sched_guard = DEFAULT_SCH_GUARD_MS;
params->channels[1].tx_power = DEFAULT_SCH_TX_POWER;
params->channels[1].flags = 0;
params->channels[1].qos_params[DSRC_OCB_AC_BE].aifsn = DEFAULR_QOS_BE_AIFSN;
params->channels[1].qos_params[DSRC_OCB_AC_BE].cwmax = DEFAULT_QOS_BE_CWMAX;
params->channels[1].qos_params[DSRC_OCB_AC_BE].cwmin = DEFAULT_QOS_BE_CWMIN;
params->channels[1].qos_params[DSRC_OCB_AC_BK].aifsn = DEFAULT_QOS_BK_AIFSN;
params->channels[1].qos_params[DSRC_OCB_AC_BK].cwmax = DEFAULT_QOS_BK_CWMAX;
params->channels[1].qos_params[DSRC_OCB_AC_BK].cwmin = DEFAULT_QOS_BK_CWMIN;
params->channels[1].qos_params[DSRC_OCB_AC_VI].aifsn = DEFAULT_QOS_VI_AIFSN;
params->channels[1].qos_params[DSRC_OCB_AC_VI].cwmax = DEFAULT_QOS_VI_CWMAX;
params->channels[1].qos_params[DSRC_OCB_AC_VI].cwmin = DEFAULT_QOS_VI_CWMIN;
params->channels[1].qos_params[DSRC_OCB_AC_VO].aifsn = DEFAULT_QOS_VO_AIFSN;
params->channels[1].qos_params[DSRC_OCB_AC_VO].cwmax = DEFAULT_QOS_VO_CWMAX;
params->channels[1].qos_params[DSRC_OCB_AC_VO].cwmin = DEFAULT_QOS_VO_CWMIN;
}
static int dsrc_parse_channel_options(struct dsrc_config_params *params)
{
int rc = 0;
enum {
NUM_CHAN = 0,
CHAN0, BW0, PWR0, DUR0, GUARD0, DISABLE_RX_STATS0,
CHAN1, BW1, PWR1, DUR1, GUARD1, DISABLE_RX_STATS1,
EXPIRY_TSF, ETH_MODE,
THE_END
};
char *set_chan_opts[] = {
[NUM_CHAN] = "num_channels",
[CHAN0] = "channel_freq0",
[BW0] = "channel_bandwidth0",
[PWR0] = "tx_power0",
[DUR0] = "duration0",
[GUARD0] = "guard0",
[DISABLE_RX_STATS0] = "disable_rx_stats0",
[CHAN1] = "channel_freq1",
[BW1] = "channel_bandwidth1",
[PWR1] = "tx_power1",
[DUR1] = "duration1",
[GUARD1] = "guard1",
[DISABLE_RX_STATS1] = "disable_rx_stats1",
[EXPIRY_TSF] = "expiry_tsf",
[ETH_MODE] = "eth_mode",
[THE_END] = NULL
};
char *value;
dsrc_channel_init(params);
while (params->chan_opts && *(params->chan_opts) != '\0') {
switch (getsubopt(&params->chan_opts, set_chan_opts, &value)) {
case NUM_CHAN:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[NUM_CHAN]);
break;
}
params->num_channels = strtol(value, NULL, 10);
break;
case CHAN0:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[CHAN0]);
break;
}
params->channels[0].frequency = strtol(value, NULL, 10);
break;
case CHAN1:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[CHAN1]);
break;
}
params->channels[1].frequency = strtol(value, NULL, 10);
break;
case BW0:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[BW0]);
break;
}
params->channels[0].bandwidth = strtol(value, NULL, 10);
break;
case BW1:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[BW1]);
break;
}
params->channels[1].bandwidth = strtol(value, NULL, 10);
break;
case PWR0:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[PWR0]);
break;
}
params->channels[0].tx_power = strtol(value, NULL, 10);
break;
case PWR1:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[PWR1]);
break;
}
params->channels[1].tx_power = strtol(value, NULL, 10);
break;
case DUR0:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[DUR0]);
break;
}
params->channels[0].sched_duration = strtol(value, NULL, 10);
break;
case DUR1:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[DUR1]);
break;
}
params->channels[1].sched_duration = strtol(value, NULL, 10);
break;
case GUARD0:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[GUARD0]);
break;
}
params->channels[0].sched_guard = strtol(value, NULL, 10);
break;
case GUARD1:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[GUARD1]);
break;
}
params->channels[1].sched_guard = strtol(value, NULL, 10);
break;
case DISABLE_RX_STATS0:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[DISABLE_RX_STATS0]);
break;
}
if (strtol(value, NULL, 10))
params->channels[0].flags |=
OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR;
else
params->channels[0].flags &=
~OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR;
break;
case DISABLE_RX_STATS1:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[DISABLE_RX_STATS1]);
break;
}
if (strtol(value, NULL, 10))
params->channels[1].flags |=
OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR;
else
params->channels[1].flags &=
~OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR;
break;
case EXPIRY_TSF:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[EXPIRY_TSF]);
break;
}
if (strtol(value, NULL, 10))
params->flags |= OCB_CONFIG_FLAG_EXPIRY_TIME_IN_TSF;
else
params->flags &= ~OCB_CONFIG_FLAG_EXPIRY_TIME_IN_TSF;
break;
case ETH_MODE:
if (value == NULL) {
printf("Missing value for suboption '%s'\n",
set_chan_opts[ETH_MODE]);
break;
}
if (strtol(value, NULL, 10))
params->flags &= ~OCB_CONFIG_FLAG_80211_FRAME_MODE;
else
params->flags |= OCB_CONFIG_FLAG_80211_FRAME_MODE;
break;
default:
rc = -1;
dsrc_config_usage();
goto bail;
}
}
bail:
return rc;
}
int dsrc_set_config(char *interface, unsigned char num_channels,
struct dsrc_channel channels[2], int enable_dcc, unsigned int flags)
{
dsrc_ocb_config_channel_t chan[2] = { {0} };
dsrc_ocb_config_sched_t sched[2] = { {0} };
dcc_ndl_chan *dcc_chan = NULL;
dcc_ndl_active_state_config *state_cfg = NULL;
unsigned char num_active_states = 0;
unsigned char num_dcc_channels = 0;
/* Convert to host driver structs */
chan[0].chan_freq = channels[0].frequency;
chan[0].bandwidth = channels[0].bandwidth;
chan[0].max_pwr = channels[0].tx_power;
chan[0].min_pwr = 6;
chan[0].flags = channels[0].flags;
sched[0].chan_freq = channels[0].frequency;
sched[0].total_duration = channels[0].sched_duration;
sched[0].guard_interval = channels[0].sched_guard;
chan[0].qos_params[DSRC_OCB_AC_BE].aifsn =
channels[0].qos_params[DSRC_OCB_AC_BE].aifsn;
chan[0].qos_params[DSRC_OCB_AC_BE].cwmax =
channels[0].qos_params[DSRC_OCB_AC_BE].cwmax;
chan[0].qos_params[DSRC_OCB_AC_BE].cwmin =
channels[0].qos_params[DSRC_OCB_AC_BE].cwmin;
chan[0].qos_params[DSRC_OCB_AC_BK].aifsn =
channels[0].qos_params[DSRC_OCB_AC_BK].aifsn;
chan[0].qos_params[DSRC_OCB_AC_BK].cwmax =
channels[0].qos_params[DSRC_OCB_AC_BK].cwmax;
chan[0].qos_params[DSRC_OCB_AC_BK].cwmin =
channels[0].qos_params[DSRC_OCB_AC_BK].cwmin;
chan[0].qos_params[DSRC_OCB_AC_VI].aifsn =
channels[0].qos_params[DSRC_OCB_AC_VI].aifsn;
chan[0].qos_params[DSRC_OCB_AC_VI].cwmax =
channels[0].qos_params[DSRC_OCB_AC_VI].cwmax;
chan[0].qos_params[DSRC_OCB_AC_VI].cwmin =
channels[0].qos_params[DSRC_OCB_AC_VI].cwmin;
chan[0].qos_params[DSRC_OCB_AC_VO].aifsn =
channels[0].qos_params[DSRC_OCB_AC_VO].aifsn;
chan[0].qos_params[DSRC_OCB_AC_VO].cwmax =
channels[0].qos_params[DSRC_OCB_AC_VO].cwmax;
chan[0].qos_params[DSRC_OCB_AC_VO].cwmin =
channels[0].qos_params[DSRC_OCB_AC_VO].cwmin;
chan[1].qos_params[DSRC_OCB_AC_BE].aifsn =
channels[1].qos_params[DSRC_OCB_AC_BE].aifsn;
chan[1].qos_params[DSRC_OCB_AC_BE].cwmax =
channels[1].qos_params[DSRC_OCB_AC_BE].cwmax;
chan[1].qos_params[DSRC_OCB_AC_BE].cwmin =
channels[1].qos_params[DSRC_OCB_AC_BE].cwmin;
chan[1].qos_params[DSRC_OCB_AC_BK].aifsn =
channels[1].qos_params[DSRC_OCB_AC_BK].aifsn;
chan[1].qos_params[DSRC_OCB_AC_BK].cwmax =
channels[1].qos_params[DSRC_OCB_AC_BK].cwmax;
chan[1].qos_params[DSRC_OCB_AC_BK].cwmin =
channels[1].qos_params[DSRC_OCB_AC_BK].cwmin;
chan[1].qos_params[DSRC_OCB_AC_VI].aifsn =
channels[1].qos_params[DSRC_OCB_AC_VI].aifsn;
chan[1].qos_params[DSRC_OCB_AC_VI].cwmax =
channels[1].qos_params[DSRC_OCB_AC_VI].cwmax;
chan[1].qos_params[DSRC_OCB_AC_VI].cwmin =
channels[1].qos_params[DSRC_OCB_AC_VI].cwmin;
chan[1].qos_params[DSRC_OCB_AC_VO].aifsn =
channels[1].qos_params[DSRC_OCB_AC_VO].aifsn;
chan[1].qos_params[DSRC_OCB_AC_VO].cwmax =
channels[1].qos_params[DSRC_OCB_AC_VO].cwmax;
chan[1].qos_params[DSRC_OCB_AC_VO].cwmin =
channels[1].qos_params[DSRC_OCB_AC_VO].cwmin;
chan[1].chan_freq = channels[1].frequency;
chan[1].bandwidth = channels[1].bandwidth;
chan[1].max_pwr = channels[1].tx_power;
chan[1].min_pwr = 6;
chan[1].flags = channels[1].flags;
sched[1].chan_freq = channels[1].frequency;
sched[1].total_duration = channels[1].sched_duration;
sched[1].guard_interval = channels[1].sched_guard;
/* Get NDL */
if (enable_dcc) {
dcc_get_config(&num_dcc_channels, &dcc_chan, &num_active_states,
&state_cfg);
if (num_dcc_channels < num_channels) {
printf("DCC enabled but NDL not provided\n");
return -1;
}
}
/* Pass NDL chan and active states down. */
return dsrc_ocb_set_config(interface, num_channels, chan, dcc_chan,
num_channels, sched, num_active_states, state_cfg, flags);
}
int dsrc_update_ndl(char *interface)
{
dcc_ndl_chan *dcc_chan;
dcc_ndl_active_state_config *state_cfg;
unsigned char num_channels, num_active_states;
/* Get NDL */
dcc_get_config(&num_channels, &dcc_chan, &num_active_states, &state_cfg);
/* Pass NDL chan and active states down. */
return dsrc_ocb_dcc_ndl_update(interface, num_channels, dcc_chan,
num_active_states, state_cfg);
}
int dsrc_get_stats(char *interface, uint32_t chan_freq1, uint32_t chan_freq2)
{
unsigned int num_channels = 1;
dcc_channel_stats_request stats_request[2];
stats_request[0].chan_freq = chan_freq1;
stats_request[0].dcc_stats_bitmap = DCC_BITMAP_DEFAULT;
if (chan_freq2 != 0) {
num_channels = 2;
stats_request[1].chan_freq = chan_freq2;
stats_request[1].dcc_stats_bitmap = DCC_BITMAP_DEFAULT;
}
return dsrc_ocb_dcc_get_stats(interface, num_channels, &stats_request[0]);
}
void dsrc_dcc_stats_event(char *interface)
{
dsrc_ocb_dcc_stats_event(interface);
}
int dsrc_clear_stats(char *interface)
{
return dsrc_ocb_dcc_clear_stats(interface, DCC_BITMAP_DEFAULT);
}
int dsrc_get_tsf_timer(char *interface)
{
return dsrc_ocb_get_tsf_timer(interface);
}
int dsrc_set_utc_time(char *interface)
{
uint8_t time_value[DSRC_OCB_UTC_TIME_LEN];
uint8_t time_error[DSRC_OCB_UTC_TIME_ERROR_LEN];
/* This is the UTC time in seconds from Jan 1st, 1958 */
uint64_t seconds;
uint64_t *time_ptr;
/* Time error as sequence of 1s means it is undetermined */
memset(time_error, TIME_ERROR_DEFAULT, DSRC_OCB_UTC_TIME_ERROR_LEN);
/* Initialize time value */
memset(time_value, 0, DSRC_OCB_UTC_TIME_LEN);
/* UTC time is the number of nanoseconds since Jan 1st 1958 */
seconds = (uint64_t)time(NULL);
seconds += SEC_1958_1970;
time_ptr = (uint64_t*)time_value;
/* UTC time in IEEE spec is set in nanoseconds */
*time_ptr = seconds*1000000;
return dsrc_ocb_set_utc_time(interface, time_value, time_error);
}
int dsrc_start_timing_advert(char *interface, uint32_t chan_freq,
uint32_t repeat_rate)
{
return dsrc_ocb_start_timing_advert(interface, chan_freq, repeat_rate);
}
int dsrc_stop_timing_advert(char *interface, uint32_t chan_freq)
{
return dsrc_ocb_stop_timing_advert(interface, chan_freq);
}
void dsrc_rx_vsa_frames(char *interface)
{
dsrc_ocb_rx_vsa_frames(interface);
}
int main(int argc, char **argv)
{
struct dsrc_config_params params = {0};
int rc = -1;
/* Process command line options */
rc = dsrc_config_get_options(argc, argv, &params);
if (rc) {
goto exit;
}
/* Parse the channel options */
rc = dsrc_parse_channel_options(&params);
if (rc) {
goto exit;
}
if (!strcmp(params.cmd, "set_config"))
rc = dsrc_set_config(params.interface, params.num_channels,
params.channels, params.enable_dcc, params.flags);
else if (!strcmp(params.cmd, "set_utc"))
rc = dsrc_set_utc_time(params.interface);
else if (!strcmp(params.cmd, "start_ta"))
rc = dsrc_start_timing_advert(params.interface,
params.channels[0].frequency, params.repeat_rate);
else if (!strcmp(params.cmd, "stop_ta"))
rc = dsrc_stop_timing_advert(params.interface,
params.channels[0].frequency);
else if (!strcmp(params.cmd, "ndl_update"))
rc = dsrc_update_ndl(params.interface);
else if (!strcmp(params.cmd, "get_stats"))
rc = dsrc_get_stats(params.interface, params.channels[0].frequency,
params.channels[1].frequency);
else if (!strcmp(params.cmd, "stats_event"))
dsrc_dcc_stats_event(params.interface);
else if (!strcmp(params.cmd, "clear_stats"))
rc = dsrc_clear_stats(params.interface);
else if (!strcmp(params.cmd, "get_tsf"))
rc = dsrc_get_tsf_timer(params.interface);
else if (!strcmp(params.cmd, "rx_vsa"))
dsrc_rx_vsa_frames(params.interface);
else
dsrc_config_usage();
if (rc) {
printf("Error executing command, ret=%d\n", rc);
} else {
printf("Success executing command\n");
}
exit:
return rc;
}