mirror of
https://github.com/Telecominfraproject/wlan-cloud-loadsim.git
synced 2026-01-12 23:05:01 +00:00
Merge remote-tracking branch 'origin/main' into main
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
-record ('AWLAN_Node',{
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>>:: binary() | ets_dont_care(),
|
||||
mqtt_settings = [<<"map">>,[]] :: term() | ets_dont_care(),
|
||||
sku_number = [<<"set">>,[]] :: term() | ets_dont_care(),
|
||||
model = <<>>:: term() | ets_dont_care(),
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
|
||||
-record ('Wifi_Stats_Config', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>>:: binary() | ets_dont_care(),
|
||||
'_version' = [<<"uuid">>,<<"4ad2c67d-99d6-4431-a6a7-09a0fa95b8e2">>] :: term(),
|
||||
radio_type = <<"2.4G">> :: term() | ets_dont_care(),
|
||||
sampling_interval = 10 :: term() | ets_dont_care(),
|
||||
@@ -83,19 +83,19 @@
|
||||
}).
|
||||
|
||||
-record ('Hotspot20_Config', {
|
||||
key_id :: binary() | ets_dont_care()
|
||||
'**key_id**' = <<>>:: binary() | ets_dont_care()
|
||||
}).
|
||||
|
||||
-record ('Hotspot20_OSU_Providers', {
|
||||
key_id :: binary() | ets_dont_care()
|
||||
'**key_id**' = <<>>:: binary() | ets_dont_care()
|
||||
}).
|
||||
|
||||
-record ('Hotspot20_Icon_Config', {
|
||||
key_id :: binary() | ets_dont_care()
|
||||
'**key_id**' :: binary() | ets_dont_care()
|
||||
}).
|
||||
|
||||
-record ('Wifi_RRM_Config', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
'_version' = [<<"uuid">>,<<"9bbd18e7-ed7e-4ff3-b89d-a54c12b27ed7">>] :: term(),
|
||||
freq_band = <<"5GU">> :: term(),
|
||||
probe_resp_threshold = -90 :: term(),
|
||||
@@ -109,13 +109,13 @@
|
||||
}).
|
||||
|
||||
-record ('Command_State', {
|
||||
key_id :: binary() | ets_dont_care()
|
||||
'**key_id**' = <<>>:: binary() | ets_dont_care()
|
||||
}).
|
||||
|
||||
|
||||
|
||||
-record ('Wifi_VIF_Config', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
vif_radio_idx = [<<"set">>,[]] :: term(),
|
||||
if_name = <<"wlan0">> :: term() | ets_dont_care(),
|
||||
ap_bridge = <<"">> :: term() | ets_dont_care(),
|
||||
@@ -154,12 +154,12 @@
|
||||
|
||||
|
||||
-record ('Wifi_VIF_State', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
vif_radio_idx = [<<"set">>,[]]:: term()
|
||||
}).
|
||||
|
||||
-record ('Wifi_Associated_Clients', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
'_version' = [<<"uuid">>,<<"5bc3eb0f-1cc3-4dae-aae5-af02c8d2f1c7">>] :: term(),
|
||||
mac = <<"">> :: term(),
|
||||
state = <<"">> :: term(),
|
||||
@@ -171,7 +171,7 @@
|
||||
|
||||
|
||||
-record ('DHCP_leased_IP', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
db_status = 1 :: term(),
|
||||
subnet_mask = <<"255.255.255.0">> :: term(),
|
||||
hostname = <<"">> :: term(),
|
||||
@@ -184,14 +184,14 @@
|
||||
vendor_class = <<"">> :: term(),
|
||||
device_type = 0 :: term(),
|
||||
dhcp_server = <<"192.168.1.1">> :: term(),
|
||||
device_name = <<"">> :: term(),
|
||||
device_name = <<"Simulation">> :: term(),
|
||||
fingerprint = <<"1,121,3,6,15,114,119,252">> :: term(),
|
||||
primary_dns = <<"192.168.1.1">> :: term(),
|
||||
gateway = <<"192.168.1.1">> :: term()
|
||||
}).
|
||||
|
||||
-record ('Wifi_Radio_Config', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
dfs_demo = [<<"set">>,[]] :: term(),
|
||||
if_name = <<"radio0">> :: term() | ets_dont_care(),
|
||||
temperature_control = [<<"map">>,[]] :: term(),
|
||||
@@ -222,7 +222,7 @@
|
||||
}).
|
||||
|
||||
-record ('Wifi_Radio_State',{
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
if_name = <<>> :: term(),
|
||||
dfs_demo = [<<"set">>,[]] :: term(),
|
||||
thermal_downgraded = [<<"set">>,[]] :: term(),
|
||||
@@ -259,7 +259,7 @@
|
||||
}).
|
||||
|
||||
-record ('Wifi_Inet_Config', {
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
if_name = <<"">> :: term(),
|
||||
dhcpd = [<<"map">>,[]] :: term(),
|
||||
dhcp_sniff = false :: term(),
|
||||
@@ -294,7 +294,7 @@
|
||||
}).
|
||||
|
||||
-record ('Wifi_Inet_State',{
|
||||
key_id :: binary() | ets_dont_care(),
|
||||
'**key_id**' = <<>> :: binary() | ets_dont_care(),
|
||||
dhcpd = [<<"map">>,[]] :: term(),
|
||||
if_name = <<"">> :: term(),
|
||||
upnp_mode = [<<"set">>,[]] :: term(),
|
||||
@@ -333,6 +333,7 @@
|
||||
initial :: boolean(),
|
||||
insert :: boolean(),
|
||||
delete :: boolean(),
|
||||
modify :: boolean()
|
||||
modify :: boolean(),
|
||||
published = true :: boolean()
|
||||
}).
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
-include("../include/common.hrl").
|
||||
-include("../include/ovsdb_definitions.hrl").
|
||||
-include("../include/ovsdb_ap_tables.hrl").
|
||||
-include("../include/opensync_stats.hrl").
|
||||
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
@@ -25,7 +26,7 @@
|
||||
-export([start_ap/1,stop_ap/1,pause_ap/1,cancel_ap/1]).
|
||||
|
||||
%% comm API
|
||||
-export([rpc_cmd/2,rpc_request/2,reset_comm/1,mqtt_conf/2,post_event/4,post_event/3]).
|
||||
-export([rpc_cmd/2,rpc_request/2,reset_comm/1,mqtt_conf/2,post_event/4,post_event/3,check_publish_monitor/1,check_for_mqtt_updates/1]).
|
||||
|
||||
|
||||
%% gen_server callbacks
|
||||
@@ -48,7 +49,8 @@
|
||||
store :: ets:tid(), % the tables where OVSDB server stores info
|
||||
req_queue :: ets:tid(), % not used at the moment ... used to que request IDs
|
||||
reporting :: timer:tref(), % statistics reporting interval timer reference
|
||||
stats_ets :: ets:tid() % statistics table
|
||||
stats_ets :: ets:tid(), % statistics table
|
||||
updates = none :: none | timer:tref() % timer reference for periodic updates from MQTT while running
|
||||
}).
|
||||
|
||||
|
||||
@@ -147,6 +149,14 @@ post_event (Node, Event, Args, Comment) ->
|
||||
post_event (Event, Args, Comment) ->
|
||||
post_event(self(),Event,Args,Comment).
|
||||
|
||||
-spec check_publish_monitor (Node :: pid()) -> ok.
|
||||
check_publish_monitor (Node) ->
|
||||
gen_server:cast(Node,check_publish_monitor).
|
||||
|
||||
-spec check_for_mqtt_updates (Node :: pid()) -> ok.
|
||||
check_for_mqtt_updates (Node) ->
|
||||
gen_server:cast(Node,check_mqtt_updates).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -226,6 +236,14 @@ handle_cast ({stats_update,Event},State) ->
|
||||
true = update_statistics(Event,State#ap_state.stats_ets),
|
||||
{noreply, State};
|
||||
|
||||
handle_cast (check_mqtt_updates, State) ->
|
||||
S = request_mqtt_updates(State),
|
||||
{noreply, S};
|
||||
|
||||
handle_cast (check_publish_monitor, State) ->
|
||||
ovsdb_ap_monitor:publish_unpublished(State#ap_state.store),
|
||||
{noreply, State};
|
||||
|
||||
handle_cast (send_report,State) ->
|
||||
{noreply, report_statistics(State)};
|
||||
|
||||
@@ -337,6 +355,9 @@ handle_info({'EXIT', Pid, Reason}, State) ->
|
||||
?L_E(?DBGSTR("Abnormal exit from ~p with reason: ~p",[Pid,Reason])),
|
||||
{noreply, State};
|
||||
|
||||
handle_info({client_stats,Serial,Stats},State) ->
|
||||
S = handle_mqtt_stats_update(Serial,Stats,State),
|
||||
{noreply, S};
|
||||
|
||||
handle_info (Msg,State) ->
|
||||
?L_E(?DBGSTR("got unexpected info message ~p",[Msg])),
|
||||
@@ -385,7 +406,7 @@ code_change (_,OldState,_) ->
|
||||
prepare_state (CAName, ID, Options) ->
|
||||
Store = ets:new(ovsdb_ap,[bag,private,{keypos, 1}]),
|
||||
Stats = ets:new(ovsdb_ap_stats,[ordered_set,private,{keypos, 2}]),
|
||||
{'ok', Tref} = timer:apply_interval(proplists:get_value(report_int,Options,?AP_REPORT_INTERVAL),
|
||||
{ok, Tref} = timer:apply_interval(proplists:get_value(report_int,Options,?AP_REPORT_INTERVAL),
|
||||
gen_server,cast,[self(),send_report]),
|
||||
Redirector = proplists:get_value(redirector,Options,<<"">>),
|
||||
update_statistics({report_mark,{},<<>>},Stats),
|
||||
@@ -415,7 +436,21 @@ set_status (Status, #ap_state{status=OldStatus, config=Cfg}=State) ->
|
||||
ovsdb_client_handler:ap_status(Status,ovsdb_ap_config:id(Cfg)),
|
||||
post_event(status_change,{OldStatus,Status},io_lib:format("status change := ~p -> ~p",[OldStatus,Status])),
|
||||
?L_I(?DBGSTR("AP ~p : status change := ~p -> ~p",[self(),OldStatus,Status])),
|
||||
State#ap_state{status=Status}.
|
||||
start_stop_mqtt_updates(State#ap_state{status=Status}).
|
||||
|
||||
-spec start_stop_mqtt_updates (State :: #ap_state{}) -> NewState :: #ap_state{}.
|
||||
start_stop_mqtt_updates(#ap_state{status=running, updates=none}=State) ->
|
||||
{ok, Ref} = timer:apply_interval(60000,?MODULE,check_for_mqtt_updates,[self()]),
|
||||
State#ap_state{updates=Ref};
|
||||
start_stop_mqtt_updates(#ap_state{status=running}=State) ->
|
||||
State;
|
||||
start_stop_mqtt_updates(#ap_state{updates=U}=State) when U =/= none->
|
||||
{ok, cancel} = timer:cancel(U),
|
||||
State#ap_state{updates=none};
|
||||
start_stop_mqtt_updates(State) ->
|
||||
State.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -598,6 +633,20 @@ stop_mqtt(#ap_state{mqtt=idle}=State) ->
|
||||
stop_mqtt(#ap_state{ca_name=CAName, id=ID}=State) ->
|
||||
_ = mqtt_client_manager:stop_client(CAName,ID),
|
||||
State#ap_state{mqtt=idle}.
|
||||
|
||||
-spec request_mqtt_updates (State :: #ap_state{}) -> NewState :: #ap_state{}.
|
||||
request_mqtt_updates (#ap_state{config=Cfg} = State) ->
|
||||
CA = ovsdb_ap_config:caname(Cfg),
|
||||
Serial = ovsdb_ap_config:serial(Cfg),
|
||||
Mqtt = mqtt_client_manager:get_client_pid(CA,Serial),
|
||||
Mqtt ! {send_stats, self()},
|
||||
State.
|
||||
|
||||
-spec handle_mqtt_stats_update (Serial :: binary(), Stats :: #{binary() => #'Client.Stats'{}}, State :: #ap_state{}) -> NewState :: #ap_state{}.
|
||||
handle_mqtt_stats_update (_Serial,_Stats,State) ->
|
||||
io:format("GOT MQTT STATS:~n"),
|
||||
State.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
-record (cfg, {
|
||||
ca_name :: string() | binary(),
|
||||
redirector :: binary(),
|
||||
serial :: binary(),
|
||||
id :: binary(),
|
||||
store_ref :: ets:tid(),
|
||||
cacert = <<>> :: binary(), % pem file (in memory) of the server certificate chain
|
||||
@@ -31,7 +32,7 @@
|
||||
|
||||
|
||||
-export([new/4,configure/1]).
|
||||
-export ([id/1,ca_certs/1,client_cert/1,client_key/1,tip_redirector/2,tip_manager/2]).
|
||||
-export ([id/1,ca_certs/1,client_cert/1,client_key/1,tip_redirector/2,tip_manager/2,caname/1,serial/1]).
|
||||
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
@@ -65,7 +66,8 @@ configure (#cfg{ca_name=CAName, id=ID, redirector=R}=Config) ->
|
||||
],
|
||||
initialize_ap_tables(Config#cfg.store_ref,validate_config(APC)),
|
||||
Config#cfg{
|
||||
cacert = Info#client_info.cacert,
|
||||
cacert = Info#client_info.cacert,
|
||||
serial = Info#client_info.serial,
|
||||
cert = Info#client_info.cert,
|
||||
key = Info#client_info.key
|
||||
}.
|
||||
@@ -112,6 +114,14 @@ initialize_ap_tables (Store, APC) ->
|
||||
id(Cfg) ->
|
||||
Cfg#cfg.id.
|
||||
|
||||
-spec caname (Config :: cfg()) -> CAName :: binary().
|
||||
caname(Cfg) ->
|
||||
Cfg#cfg.ca_name.
|
||||
|
||||
-spec serial (Config :: cfg()) -> Serial :: binary().
|
||||
serial(Cfg) ->
|
||||
Cfg#cfg.serial.
|
||||
|
||||
-spec ca_certs (Config :: cfg()) -> binary().
|
||||
ca_certs (Cfg) ->
|
||||
Cfg#cfg.cacert.
|
||||
@@ -169,7 +179,7 @@ modify_mac (MAC) ->
|
||||
-spec create_table (Table :: atom(), AP_Config :: [{atom(),term()}], Store :: ets:tid()) -> true.
|
||||
create_table ('Wifi_Radio_State',APC,Store) ->
|
||||
ets:insert(Store, #'Wifi_Radio_State'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
if_name = <<"radio0">>,
|
||||
mac = modify_mac(proplists:get_value(lan_mac,APC)),
|
||||
bcn_int = 100,
|
||||
@@ -188,7 +198,7 @@ create_table ('Wifi_Radio_State',APC,Store) ->
|
||||
freq_band = <<"5GU">>
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Radio_State' {
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
if_name = <<"radio1">>,
|
||||
mac = modify_mac(proplists:get_value(lan_mac,APC)),
|
||||
bcn_int = 100,
|
||||
@@ -208,7 +218,7 @@ create_table ('Wifi_Radio_State',APC,Store) ->
|
||||
freq_band = <<"2.4G">>
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Radio_State'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
if_name = <<"radio2">>,
|
||||
mac = modify_mac(proplists:get_value(lan_mac,APC)),
|
||||
bcn_int = 100,
|
||||
@@ -229,20 +239,20 @@ create_table ('Wifi_Radio_State',APC,Store) ->
|
||||
|
||||
create_table ('Wifi_Radio_Config',_APC,Store) ->
|
||||
ets:insert(Store, #'Wifi_Radio_Config'{
|
||||
key_id = <<"830bd195-7114-4e99-9b51-5622e47ce221">>,
|
||||
'**key_id**' = <<"830bd195-7114-4e99-9b51-5622e47ce221">>,
|
||||
'_uuid' = [<<"uuid">>, <<"830bd195-7114-4e99-9b51-5622e47ce221">>],
|
||||
freq_band = <<"5GU">>,
|
||||
if_name = <<"radio0">>
|
||||
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Radio_Config'{
|
||||
key_id = <<"94f9b810-8c71-4961-a9c0-7f3a96869368">>,
|
||||
'**key_id**' = <<"94f9b810-8c71-4961-a9c0-7f3a96869368">>,
|
||||
'_uuid' = [<<"uuid">>, <<"94f9b810-8c71-4961-a9c0-7f3a96869368">>],
|
||||
freq_band = <<"5GL">>,
|
||||
if_name = <<"radio2">>
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Radio_Config'{
|
||||
key_id = <<"fb11d840-cbe9-4e32-9744-ebcda9162e52">>,
|
||||
'**key_id**' = <<"fb11d840-cbe9-4e32-9744-ebcda9162e52">>,
|
||||
'_uuid' = [<<"uuid">>, <<"fb11d840-cbe9-4e32-9744-ebcda9162e52">>],
|
||||
freq_band = <<"2.4G">>,
|
||||
if_name = <<"radio1">>
|
||||
@@ -250,7 +260,7 @@ create_table ('Wifi_Radio_Config',_APC,Store) ->
|
||||
|
||||
create_table ('Wifi_Inet_State',APC,Store) ->
|
||||
ets:insert(Store, #'Wifi_Inet_State'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
if_name= <<"wwan">>,
|
||||
if_type = <<"eth">>,
|
||||
enabled = false,
|
||||
@@ -258,7 +268,7 @@ create_table ('Wifi_Inet_State',APC,Store) ->
|
||||
inet_config = [<<"uuid">>,<<"7e38a63b-526a-4b83-b30e-edd4c17ab3f6">>]
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Inet_State'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
dhcpd = [<<"map">>,[[<<"lease_time">>,<<"12h">>],[<<"start">>,<<"100">>],[<<"stop">>,<<"150">>]]],
|
||||
if_name= <<"lan">>,
|
||||
if_type = <<"bridge">>,
|
||||
@@ -273,7 +283,7 @@ create_table ('Wifi_Inet_State',APC,Store) ->
|
||||
inet_config = [<<"uuid">>,<<"19484645-8519-4bd0-98dd-13f1fec83395">>]
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Inet_State'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
if_name= <<"wan6">>,
|
||||
if_type = <<"eth">>,
|
||||
enabled = false,
|
||||
@@ -281,7 +291,7 @@ create_table ('Wifi_Inet_State',APC,Store) ->
|
||||
inet_config = [<<"uuid">>,<<"b803af39-e392-437b-8c86-dd87d24f8b49">>]
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Inet_State'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
if_name= <<"wan">>,
|
||||
if_type = <<"bridge">>,
|
||||
enabled = true,
|
||||
@@ -300,7 +310,7 @@ create_table ('Wifi_Inet_State',APC,Store) ->
|
||||
|
||||
create_table ('Wifi_Inet_Config',APC,Store) ->
|
||||
ets:insert(Store, #'Wifi_Inet_Config'{
|
||||
key_id = <<"1a533ecc-90d7-499e-a76c-0d593a446fdb">>,
|
||||
'**key_id**' = <<"1a533ecc-90d7-499e-a76c-0d593a446fdb">>,
|
||||
'_uuid' = [<<"uuid">>, <<"1a533ecc-90d7-499e-a76c-0d593a446fdb">>],
|
||||
dhcpd = [<<"map">>,[]],
|
||||
if_name = <<"wan">>,
|
||||
@@ -318,7 +328,7 @@ create_table ('Wifi_Inet_Config',APC,Store) ->
|
||||
inet_addr = [<<"set">>,[]]
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Inet_Config'{
|
||||
key_id = <<"b803af39-e392-437b-8c86-dd87d24f8b49">>,
|
||||
'**key_id**' = <<"b803af39-e392-437b-8c86-dd87d24f8b49">>,
|
||||
'_uuid' = [<<"uuid">>, <<"b803af39-e392-437b-8c86-dd87d24f8b49">>],
|
||||
if_name = <<"wan6">>,
|
||||
network = true,
|
||||
@@ -327,7 +337,7 @@ create_table ('Wifi_Inet_Config',APC,Store) ->
|
||||
'NAT' = false
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Inet_Config'{
|
||||
key_id = <<"7e38a63b-526a-4b83-b30e-edd4c17ab3f6">>,
|
||||
'**key_id**' = <<"7e38a63b-526a-4b83-b30e-edd4c17ab3f6">>,
|
||||
'_uuid' = [<<"uuid">>, <<"7e38a63b-526a-4b83-b30e-edd4c17ab3f6">>],
|
||||
if_name = <<"wwan">>,
|
||||
network = true,
|
||||
@@ -337,7 +347,7 @@ create_table ('Wifi_Inet_Config',APC,Store) ->
|
||||
ip_assign_scheme = <<"dhcp">>
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Inet_Config'{
|
||||
key_id = <<"19484645-8519-4bd0-98dd-13f1fec83395">>,
|
||||
'**key_id**' = <<"19484645-8519-4bd0-98dd-13f1fec83395">>,
|
||||
'_uuid' = [<<"uuid">>, <<"19484645-8519-4bd0-98dd-13f1fec83395">>],
|
||||
dhcpd = [<<"map">>,[[<<"lease_time">>,<<"12h">>],[<<"start">>,<<"100">>],[<<"stop">>,<<"150">>]]],
|
||||
if_name = <<"lan">>,
|
||||
@@ -352,7 +362,7 @@ create_table ('Wifi_Inet_Config',APC,Store) ->
|
||||
|
||||
create_table ('Wifi_RRM_Config',_APC,Store) ->
|
||||
ets:insert(Store,#'Wifi_RRM_Config'{
|
||||
key_id = <<"d1f9874c-d8e7-4426-9d70-c856c4dc6126">>,
|
||||
'**key_id**' = <<"d1f9874c-d8e7-4426-9d70-c856c4dc6126">>,
|
||||
'_version' = [<<"uuid">>,<<"9bbd18e7-ed7e-4ff3-b89d-a54c12b27ed7">>],
|
||||
freq_band = <<"2.4G">>,
|
||||
min_load = 50,
|
||||
@@ -361,7 +371,7 @@ create_table ('Wifi_RRM_Config',_APC,Store) ->
|
||||
snr_percentage_drop = 20
|
||||
}),
|
||||
ets:insert(Store,#'Wifi_RRM_Config'{
|
||||
key_id = <<"8cf973a6-a268-4de4-9bf2-5f7d9222f806">>,
|
||||
'**key_id**' = <<"8cf973a6-a268-4de4-9bf2-5f7d9222f806">>,
|
||||
'_version' = [<<"uuid">>,<<"9bbd18e7-ed7e-4ff3-b89d-a54c12b27ed7">>],
|
||||
freq_band = <<"5GL">>,
|
||||
min_load = 40,
|
||||
@@ -370,7 +380,7 @@ create_table ('Wifi_RRM_Config',_APC,Store) ->
|
||||
snr_percentage_drop = 30
|
||||
}),
|
||||
ets:insert(Store,#'Wifi_RRM_Config'{
|
||||
key_id = <<"44deb01a-a2a8-4b5b-a2be-0bdf04050b97">>,
|
||||
'**key_id**' = <<"44deb01a-a2a8-4b5b-a2be-0bdf04050b97">>,
|
||||
'_version' = [<<"uuid">>,<<"9bbd18e7-ed7e-4ff3-b89d-a54c12b27ed7">>],
|
||||
freq_band = <<"5GU">>,
|
||||
min_load = 40,
|
||||
@@ -383,7 +393,7 @@ create_table ('Wifi_Associated_Clients',APC,Store) ->
|
||||
%io:format("CONFIGURED WIFI CLIENTS:~n~p~n",[proplists:get_value(wifi_clients,APC)]),
|
||||
F = fun({_,_,[MAC|_]}) ->
|
||||
ets:insert(Store, #'Wifi_Associated_Clients'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
'_version' = [<<"uuid">>, utils:uuid_b()],
|
||||
mac = MAC,
|
||||
state = <<"active">>
|
||||
@@ -391,7 +401,7 @@ create_table ('Wifi_Associated_Clients',APC,Store) ->
|
||||
end,
|
||||
[F(X) || X <- proplists:get_value(wifi_clients,APC)];
|
||||
% ets:insert(Store, #'Wifi_Associated_Clients'{
|
||||
% key_id = <<"ee49ed4e-5a04-4100-bf6a-ebfbbc54250e">>,
|
||||
% '**key_id**' = <<"ee49ed4e-5a04-4100-bf6a-ebfbbc54250e">>,
|
||||
% '_version' = [<<"uuid">>,<<"5bc3eb0f-1cc3-4dae-aae5-af02c8d2f1c7">>],
|
||||
% mac = <<"52:b6:76:03:6d:f2">>,
|
||||
% state = <<"active">>,
|
||||
@@ -402,40 +412,42 @@ create_table ('Wifi_Associated_Clients',APC,Store) ->
|
||||
% });
|
||||
|
||||
create_table ('DHCP_leased_IP',APC,Store) ->
|
||||
CL = proplists:get_value(wifi_clients,APC),
|
||||
NM = proplists:get_value(name,APC),
|
||||
F = fun(N,{_,_,[MAC|_]}) ->
|
||||
ets:insert(Store, #'DHCP_leased_IP'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
'_version' = [<<"uuid">>, utils:uuid_b()],
|
||||
hostname = iolist_to_binary([proplists:get_value(name,APC),"_",integer_to_list(N)]),
|
||||
inet_addr = iolist_to_binary(["192.168.1.",integer_to_list(N+1)]),
|
||||
hwaddr = MAC
|
||||
hwaddr = MAC,
|
||||
device_name = iolist_to_binary([NM,".SimClient_",integer_to_list(N+1)])
|
||||
})
|
||||
end,
|
||||
CL = proplists:get_value(wifi_clients,APC),
|
||||
[F(N,X) || {N,X} <- lists:zip(lists:seq(1,length(CL)),CL)];
|
||||
|
||||
create_table ('Wifi_Stats_Config',_APC,Store) ->
|
||||
ets:insert(Store, #'Wifi_Stats_Config'{
|
||||
key_id = <<"f84b6834-80d6-4fd6-af73-98e3f4f96033">>,
|
||||
'**key_id**' = <<"f84b6834-80d6-4fd6-af73-98e3f4f96033">>,
|
||||
'_uuid' = [<<"uuid">>,<<"f84b6834-80d6-4fd6-af73-98e3f4f96033">>],
|
||||
radio_type = <<"2.4G">>
|
||||
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Stats_Config'{
|
||||
key_id = <<"682166f4-8d40-47b9-8ddc-827940cae8ef">>,
|
||||
'**key_id**' = <<"682166f4-8d40-47b9-8ddc-827940cae8ef">>,
|
||||
'_uuid' = [<<"uuid">>,<<"682166f4-8d40-47b9-8ddc-827940cae8ef">>],
|
||||
radio_type = <<"5GL">>
|
||||
|
||||
}),
|
||||
ets:insert(Store, #'Wifi_Stats_Config'{
|
||||
key_id = <<"21b32c56-5011-455c-9c7c-c58b9d43d583">>,
|
||||
'**key_id**' = <<"21b32c56-5011-455c-9c7c-c58b9d43d583">>,
|
||||
'_uuid' = [<<"uuid">>,<<"21b32c56-5011-455c-9c7c-c58b9d43d583">>],
|
||||
radio_type = <<"5GU">>
|
||||
});
|
||||
|
||||
create_table ('AWLAN_Node',APC,Store) ->
|
||||
ets:insert(Store, #'AWLAN_Node'{
|
||||
key_id = utils:uuid_b(),
|
||||
'**key_id**' = utils:uuid_b(),
|
||||
redirector_addr = proplists:get_value(tip_redirector,APC),
|
||||
serial_number = proplists:get_value(serial,APC),
|
||||
id = proplists:get_value(serial,APC),
|
||||
|
||||
139
src/ovsdb_ap_monitor.erl
Normal file
139
src/ovsdb_ap_monitor.erl
Normal file
@@ -0,0 +1,139 @@
|
||||
%%%-----------------------------------------------------------------------------
|
||||
%%% @author helge
|
||||
%%% @copyright (C) 2020, Arilia Wireless Inc.
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 17. December 2020 @ 11:05:46
|
||||
%%%-----------------------------------------------------------------------------
|
||||
-module(ovsdb_ap_monitor).
|
||||
-author("helge").
|
||||
|
||||
-include("../include/common.hrl").
|
||||
-include("../include/ovsdb_ap_tables.hrl").
|
||||
|
||||
|
||||
-export ([req_monitor/3,maybe_publish_data/6,publish_unpublished/1]).
|
||||
|
||||
|
||||
-spec req_monitor (NameSpace :: binary(), ToMonitor :: [#{binary()=>term()}], Store :: ets:tid()) -> Result :: #{binary()=>term()}.
|
||||
req_monitor (NameSpace,[{Table,Operations}|_],Store) ->
|
||||
monitor (NameSpace,Table,Operations,Store);
|
||||
% case Table of
|
||||
% <<"Wifi_Associated_Clients">> ->
|
||||
% QRes = ovsdb_dba:select_with_key(Table,[],Store),
|
||||
% timer:apply_after(5000,?MODULE,publish_monitor,[self(),NameSpace,monitor_result(Table,QRes,[])]),
|
||||
% #{};
|
||||
% <<"DHCP_leased_IP">> ->
|
||||
% QRes = ovsdb_dba:select_with_key(Table,[],Store),
|
||||
% timer:apply_after(5500,?MODULE,publish_monitor,[self(),NameSpace,monitor_result(Table,QRes,[])]),
|
||||
% #{};
|
||||
% _ ->
|
||||
% Ret
|
||||
% end;
|
||||
req_monitor (NameSpace,OPS,_) ->
|
||||
?L_EA("Monitor request for namespace '~s' with unsupported operatiosn format ~p",[NameSpace,OPS]),
|
||||
#{}.
|
||||
|
||||
-spec monitor (NameSpace :: binary(), Table :: binary(), Operations :: #{binary()=>term()}, Store :: ets:tid()) -> Result :: #{binary()=>term()}.
|
||||
monitor (NameSpace, Table, Operations, Store) ->
|
||||
Sel = maps:get(<<"select">>,Operations,#{<<"modify">>=>true}),
|
||||
M = #monitors{
|
||||
namespace = NameSpace,
|
||||
table = Table,
|
||||
initial = maps:get(<<"initial">>,Sel,false),
|
||||
insert = maps:get(<<"insert">>,Sel,false),
|
||||
delete = maps:get(<<"delete">>,Sel,false),
|
||||
modify = maps:get(<<"modify">>,Sel,false)
|
||||
},
|
||||
ets:insert(Store, M),
|
||||
case should_return_value(initial,Table,Store) of
|
||||
true ->
|
||||
QRes = ovsdb_dba:select_with_key(Table,[],Store),
|
||||
monitor_result(Table,QRes,[]);
|
||||
% R = monitor_result(Table,QRes,[]),
|
||||
% io:format("MONITOR RESULT:~n~p~n",[R]),
|
||||
% R;
|
||||
false ->
|
||||
M2 = M#monitors{published=false},
|
||||
ets:delete_object(Store,M),
|
||||
ets:insert(Store, M2),
|
||||
#{}
|
||||
end.
|
||||
|
||||
-spec should_return_value(State :: initial | insert | delete | modify, TableName :: binary(), Store :: ets:tid()) -> boolean().
|
||||
should_return_value (initial,Table,Store) ->
|
||||
length(ets:match_object(Store,#monitors{table=Table, initial=true, _='_'})) =/= 0;
|
||||
should_return_value (insert,Table,Store) ->
|
||||
length(ets:match_object(Store,#monitors{table=Table, initial=true, _='_'})) =/= 0;
|
||||
should_return_value (delete,Table,Store) ->
|
||||
length(ets:match_object(Store,#monitors{table=Table, initial=true, _='_'})) =/= 0;
|
||||
should_return_value (modify,Table,Store) ->
|
||||
length(ets:match_object(Store,#monitors{table=Table, initial=true, _='_'})) =/= 0.
|
||||
|
||||
-spec monitor_result (TableName :: binary(), NewRows :: [{Key :: binary(), #{binary()=>any()}}], OldRows :: [{Key :: binary(), #{binary()=>any()}}]) -> #{binary()=>any()}.
|
||||
monitor_result (_,[],[]) ->
|
||||
#{};
|
||||
monitor_result (T,NewRows,[]) ->
|
||||
L = [{K,#{<<"new">>=>M}} || {K,M} <- NewRows],
|
||||
#{T => maps:from_list(L)};
|
||||
monitor_result (T,NewRows,OldRows) ->
|
||||
OldMap = maps:from_list(OldRows),
|
||||
F = fun ({K,Map}) ->
|
||||
case maps:is_key(K,OldMap) of
|
||||
true ->
|
||||
{K,#{<<"new">>=>Map, <<"old">>=>maps:get(K,OldMap)}};
|
||||
false ->
|
||||
{K,#{<<"new">>=>Map}}
|
||||
end
|
||||
end,
|
||||
L = [F(X) || X <- NewRows],
|
||||
#{T => maps:from_list(L)}.
|
||||
|
||||
|
||||
|
||||
|
||||
-spec publish_monitor (NameSpace :: binary(), Data :: #{binary()=>term()}) -> ok.
|
||||
publish_monitor (NameSpace,Data) ->
|
||||
RPC = #{
|
||||
<<"id">> => null,
|
||||
<<"method">> => <<"update">>,
|
||||
<<"params">> => [NameSpace,Data]
|
||||
},
|
||||
% Json = iolist_to_binary(jiffy:encode(RPC)),
|
||||
% io:format("PUBLISHING: ~s~n~s~n",[NameSpace,Json]),
|
||||
?L_IA("PUBLISHING: ~s",[NameSpace]),
|
||||
ovsdb_ap:rpc_request(self(),RPC).
|
||||
|
||||
-spec maybe_publish_data (NameSpace :: binary(),
|
||||
Tablename :: binary(),
|
||||
Operation :: insert | delete | modify,
|
||||
NewRows :: [{Key :: binary(), #{binary()=>any()}}],
|
||||
OldRows :: [{Key :: binary(), #{binary()=>any()}}],
|
||||
Store :: ets:tid()) -> ok.
|
||||
maybe_publish_data (NS,T,Op,New,Old,Store) ->
|
||||
case should_return_value(Op,T,Store) of
|
||||
true ->
|
||||
Res = monitor_result(T,New,Old),
|
||||
publish_monitor(NS,Res),
|
||||
ok;
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
-spec publish_unpublished (Store :: ets:tid()) -> ok.
|
||||
publish_unpublished (Store) ->
|
||||
ToPublish = ets:match_object(Store,#monitors{published=false, modify=true, _='_'}),
|
||||
%ToPublish = ets:match_object(Store,#monitors{_='_'}),
|
||||
%io:format ("UNPUBLISHED:~n~p~n",[ToPublish]),
|
||||
F = fun (#monitors{namespace=NS, table=T}=P) ->
|
||||
QRes = ovsdb_dba:select_with_key(T,[],Store),
|
||||
publish_monitor(NS,monitor_result(T,QRes,[])),
|
||||
P#monitors{published=true}
|
||||
end,
|
||||
N = [F(X) || X <- ToPublish],
|
||||
[ets:delete_object(Store,X) || X <- ToPublish],
|
||||
ets:insert(Store,N).
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
-include("../include/common.hrl").
|
||||
-include("../include/ovsdb_ap_tables.hrl").
|
||||
|
||||
-export ([eval_req/4,eval_resp/4,publish_monitor/3]).
|
||||
-export ([eval_req/4,eval_resp/4]).
|
||||
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
@@ -30,11 +30,12 @@ eval_req(<<"transact">>,Id,#{<<"params">>:=_P},_Store) ->
|
||||
{ok, make_result(Id,<<>>)};
|
||||
|
||||
eval_req(<<"monitor">>,Id,#{<<"params">>:=[<<"Open_vSwitch">>,NSpace|Tables]},Store) when length(Tables)==1 ->
|
||||
Mon = req_monitor(NSpace,maps:to_list(hd(Tables)),Store),
|
||||
Mon = ovsdb_ap_monitor:req_monitor(NSpace,maps:to_list(hd(Tables)),Store),
|
||||
Res = make_result(Id,Mon),
|
||||
% Json = iolist_to_binary(jiffy:encode(Res,[pretty])),
|
||||
% io:format("MONITOR REQUEST (~s):~n~s~n",[NSpace,Json]),
|
||||
io:format("MONITOR REQUEST (~s):~n",[NSpace]),
|
||||
timer:apply_after(3000,ovsdb_ap,check_publish_monitor,[self()]),
|
||||
{ok, Res};
|
||||
eval_req(<<"monitor">>,Id,P,_) ->
|
||||
?L_EA("unrecognized monitor request: ~p",[P]),
|
||||
@@ -79,7 +80,7 @@ eval_resp (Id, _Data, Queue, _Store) ->
|
||||
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% transaction and monitor handling
|
||||
%% transaction handling
|
||||
|
||||
-spec run_transactions (Id :: binary(), Transactions :: [#{binary() => term()}], Store :: ets:tid(), Acc :: [#{binary()=>any()}]) -> [#{binary()=>any()}].
|
||||
run_transactions (_,[],_,Acc) ->
|
||||
@@ -90,89 +91,6 @@ run_transactions (Id,[Trans|More],Store,Acc) when is_map(Trans) ->
|
||||
Qr = table_query(Trans,Store),
|
||||
run_transactions (Id,More,Store,[Qr|Acc]).
|
||||
|
||||
-spec req_monitor (NameSpace :: binary(), ToMonitor :: [#{binary()=>term()}], Store :: ets:tid()) -> Result :: #{binary()=>term()}.
|
||||
req_monitor (NameSpace,[{Table,Operations}|_],Store) ->
|
||||
{M,Ret} = monitor (NameSpace,Table,Operations,Store),
|
||||
case Table of
|
||||
<<"Wifi_Associated_Clients">> ->
|
||||
Res = monitor_result(modify,M,Store),
|
||||
timer:apply_after(5000,?MODULE,publish_monitor,[self(),NameSpace,Res]),
|
||||
#{};
|
||||
<<"DHCP_leased_IP">> ->
|
||||
Res = monitor_result(modify,M,Store),
|
||||
timer:apply_after(5500,?MODULE,publish_monitor,[self(),NameSpace,Res]),
|
||||
#{};
|
||||
_ ->
|
||||
Ret
|
||||
end;
|
||||
req_monitor (NameSpace,OPS,_) ->
|
||||
?L_EA("Monitor request for namespace '~s' with unsupported operatiosn format ~p",[NameSpace,OPS]),
|
||||
#{}.
|
||||
|
||||
-spec monitor (NameSpace :: binary(), Table :: binary(), Operations :: #{binary()=>term()}, Store :: ets:tid()) -> Result :: #{binary()=>term()}.
|
||||
monitor (NameSpace, Table, Operations, Store) ->
|
||||
Sel = maps:get(<<"select">>,Operations,#{<<"modify">>=>true}),
|
||||
M = #monitors{
|
||||
namespace = NameSpace,
|
||||
table = Table,
|
||||
initial = maps:get(<<"initial">>,Sel,false),
|
||||
insert = maps:get(<<"insert">>,Sel,false),
|
||||
delete = maps:get(<<"delete">>,Sel,false),
|
||||
modify = maps:get(<<"modify">>,Sel,false)
|
||||
},
|
||||
ets:insert(Store, M),
|
||||
{M,monitor_result(initial,M,Store)}.
|
||||
|
||||
-spec monitor_result (State :: initial | insert | delete | modify, Monitor :: #monitors{}, Store :: ets:tid()) -> Result :: #{binary()=>term()}.
|
||||
monitor_result (initial,#monitors{table=T, initial=true}, Store) ->
|
||||
monitor_table_query(T, new, Store);
|
||||
monitor_result (insert,#monitors{table=T, insert=true}, Store) ->
|
||||
monitor_table_query(T, new, Store);
|
||||
monitor_result (delete,#monitors{table=T, delete=true}, Store) ->
|
||||
monitor_table_query(T, old, Store);
|
||||
monitor_result (modify,#monitors{table=T, modify=true}, Store) ->
|
||||
monitor_table_query(T, both, Store);
|
||||
monitor_result (_,_,_) ->
|
||||
#{}.
|
||||
|
||||
-spec monitor_table_query (Table :: binary(), Which :: new | old | both,Store :: ets:tid()) -> Result :: #{binary()=>term()}.
|
||||
monitor_table_query (Table, Which, Store) ->
|
||||
Fields = rec_fields(Table),
|
||||
F = fun(X) ->
|
||||
M = maps:from_list(lists:zip(Fields,X)),
|
||||
{KeyId,M2} = case Table of
|
||||
<<"Wifi_Associated_Clients">> ->
|
||||
{KeyId2,Mt} = maps:take(<<"key_id">>,M),
|
||||
{KeyId2,Mt#{<<"key_id">>=><<"">>}};
|
||||
_ ->
|
||||
maps:take(<<"key_id">>,M)
|
||||
end,
|
||||
case Which of
|
||||
new -> {KeyId,#{<<"new">>=>M2}};
|
||||
old -> {KeyId,#{<<"old">>=>M2}};
|
||||
both -> {KeyId,#{<<"new">>=>M2}} %, <<"old">>=>#{}}}
|
||||
end
|
||||
end,
|
||||
case ets:select(Store,create_match_spec(Table,[])) of
|
||||
[] ->
|
||||
#{};
|
||||
Res ->
|
||||
#{Table=>maps:from_list([F(X) || X <- Res])}
|
||||
end.
|
||||
|
||||
|
||||
-spec publish_monitor (AP :: pid(), NameSpace :: binary(), Data :: #{binary()=>term()}) -> ok.
|
||||
publish_monitor (AP,NameSpace,Data) ->
|
||||
RPC = #{
|
||||
<<"id">> => null,
|
||||
<<"method">> => <<"update">>,
|
||||
<<"params">> => [NameSpace,Data]
|
||||
},
|
||||
Json = iolist_to_binary(jiffy:encode(RPC)),
|
||||
io:format("PUBLISHING: ~s~n~s~n",[NameSpace,Json]),
|
||||
?L_IA("PUBLISHING: ~s",[NameSpace]),
|
||||
ovsdb_ap:rpc_request(AP,RPC).
|
||||
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% handling OVSDB tables
|
||||
@@ -180,80 +98,29 @@ publish_monitor (AP,NameSpace,Data) ->
|
||||
-spec table_query (P :: map(), Store :: ets:tid()) -> map().
|
||||
|
||||
table_query (#{<<"table">>:=T, <<"op">>:= <<"select">>, <<"columns">>:=C, <<"where">>:=W},S) ->
|
||||
Res = ets:select(S,create_match_spec(T,W)),
|
||||
#{ <<"rows">> => make_res_rows(T,Res,C,[])};
|
||||
Res = ovsdb_dba:select(T,W,S),
|
||||
#{ <<"rows">> => make_res_rows(Res,C,[])};
|
||||
table_query (#{<<"table">>:=T, <<"op">>:= <<"select">>, <<"where">>:=W},S) ->
|
||||
Res = ets:select(S,create_match_spec(T,W)),
|
||||
[_|Cols] = rec_fields(T),
|
||||
#{ <<"rows">> => make_res_rows(T,Res,Cols,[])};
|
||||
Res = ovsdb_dba:select(T,W,S),
|
||||
#{ <<"rows">> => make_res_rows(Res,all,[])};
|
||||
|
||||
table_query (#{<<"table">>:=T, <<"op">>:= <<"delete">>, <<"where">>:=W},S) ->
|
||||
M = create_match_spec(T,W),
|
||||
D = ets:select_delete(S,[setelement(3,hd(M),[true])]),
|
||||
D = ovsdb_dba:delete(T,W,S),
|
||||
#{ <<"count">> => D};
|
||||
|
||||
table_query (#{<<"table">>:=T, <<"op">>:= <<"insert">>, <<"row">>:=R},S) ->
|
||||
Fields = rec_fields(T),
|
||||
UUID = utils:uuid_b(),
|
||||
Default = maps:from_list(lists:zip(Fields,tl(tuple_to_list(default_record(T))))),
|
||||
Rwi = maps:merge(Default,R#{<<"key_id">>=>utils:uuid_b(),<<"_uuid">>=>[<<"uuid">>,UUID]}),
|
||||
Rec = list_to_tuple([binary_to_atom(T)|[maps:get(X,Rwi,<<"###WILL_CRASH###">>) || X<-Fields]]),
|
||||
% case T of
|
||||
% <<"Wifi_VIF_Config">> ->
|
||||
% io:format("INSERT VIF:~nInput=~p~nResult=~p~n",[R,Rec]);
|
||||
% _ ->
|
||||
% ok
|
||||
% end,
|
||||
ets:insert(S,Rec),
|
||||
#{uuid=>[uuid,UUID]};
|
||||
UUIDs = ovsdb_dba:insert(T,R,S),
|
||||
#{uuid=>[uuid|UUIDs]};
|
||||
|
||||
table_query (#{<<"table">>:=T, <<"op">>:= <<"mutate">>, <<"mutations">>:=Mut, <<"where">>:=W},S) ->
|
||||
D = mutate_table(T,Mut,W,S),
|
||||
D = ovsdb_dba:mutate_table(T,Mut,W,S),
|
||||
#{<<"count">> => D};
|
||||
|
||||
table_query (#{<<"table">>:=T, <<"op">>:= <<"update">>, <<"row">>:=R, <<"where">>:=W},S) ->
|
||||
M = create_match_spec(T,W),
|
||||
Res = ets:select(S,M),
|
||||
D = ets:select_delete(S,[setelement(3,hd(M),[true])]),
|
||||
Upd = update_records(T,R,Res,[]),
|
||||
ets:insert(S,Upd),
|
||||
D = ovsdb_dba:update(T,R,W,S),
|
||||
check_update_actions(R),
|
||||
#{<<"count">> => D}.
|
||||
|
||||
%--------mutate_table/4------------------hndle mutations to fields in a table row (or rows)
|
||||
|
||||
-spec mutate_table (Table :: binary(), Mutations :: [[any()]], Where :: [any()], Store :: ets:tid()) -> RowsAffected :: integer().
|
||||
mutate_table (Table,Mut,Where,Store) ->
|
||||
mutate_table_a (Table,Mut,Where,Store,0).
|
||||
|
||||
-spec mutate_table_a (Table :: binary(), Mutations :: [[any()]], Where :: [any()], Store :: ets:tid(), Acc :: integer()) -> RowsAffected :: integer().
|
||||
mutate_table_a (_,[],_,_,A) ->
|
||||
A;
|
||||
mutate_table_a (Table,[Mut|Tail],Where,Store,A) ->
|
||||
MSpec = create_match_spec(Table,Where),
|
||||
[ToMutate] = ets:select(Store,MSpec),
|
||||
Mutated = apply_mutations(Mut, Table, ToMutate),
|
||||
%io:format("MUTATION: MUT=~p~nToMutate=~p~n,Mutated=~p~n",[Mut,ToMutate,Mutated]),
|
||||
D = ets:select_delete(Store,[setelement(3,hd(MSpec),[true])]),
|
||||
ets:insert(Store,list_to_tuple([binary_to_atom(Table)|Mutated])),
|
||||
mutate_table_a (Table,Tail,Where,Store,A+D).
|
||||
|
||||
-spec apply_mutations (Mutations :: [], Table :: binary(), ToMutate :: tuple()) -> MutatedRecord :: tuple().
|
||||
apply_mutations ([Field,<<"insert">>,What],Table,Record) ->
|
||||
RecMap = lists:zip(rec_fields(Table),Record),
|
||||
case proplists:get_value(Field,RecMap) of
|
||||
undefined ->
|
||||
Record;
|
||||
[T,L] ->
|
||||
F = fun (X,_) when X=:=Field -> [T,[What|L]]; (_,V) -> V end,
|
||||
[F(Key,Val) || {Key,Val}<-RecMap]
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%--------check_update_actions/1----------special handling for some updates that need to trigger actions
|
||||
|
||||
@@ -267,40 +134,14 @@ check_update_actions (_) ->
|
||||
ok.
|
||||
|
||||
%--------make_res_rows/3-----------------formats query results into proper rows map
|
||||
-spec make_res_rows (Record :: binary(), Res :: [[{binary(),any()}]], Cols :: [binary()], Acc :: [#{}]) -> [#{}].
|
||||
make_res_rows (R,Res,[],Acc) ->
|
||||
make_res_rows (R,Res,rec_fields(R),Acc);
|
||||
make_res_rows (_,[],_,Acc) ->
|
||||
-spec make_res_rows (Res :: [#{binary()=>any()}], Cols :: all | [binary()], Acc :: [#{binary()=>any()}]) -> [#{binary()=>any()}].
|
||||
make_res_rows (Res,all,_) ->
|
||||
Res;
|
||||
make_res_rows ([],_,Acc) ->
|
||||
lists:reverse(Acc);
|
||||
make_res_rows (R,[H|T],C,Acc) ->
|
||||
M = maps:from_list([{F,V}|| {F,V}<-lists:zip(rec_fields(R),H), lists:member(F,C)]),
|
||||
make_res_rows(R,T,C,[M|Acc]).
|
||||
|
||||
%--------create_match_spec/3-------------creates proper match specification from RPC command for ETS search
|
||||
-spec create_match_spec (TableName :: binary(), Where :: []) -> [{tuple(),list(),list()}].
|
||||
create_match_spec (R,W) ->
|
||||
Op = #{<<"==">>=>'==', <<"!=">>=>'/=', <<"<=">>=>'<=', <<"<">>=>'<', <<">=">>=>'>=', <<">">>=>'>'},
|
||||
Fields = rec_fields(R),
|
||||
MP = [binary_to_atom(list_to_binary([$$,integer_to_list(X)])) || X<-lists:seq(1,length(Fields))],
|
||||
C = [{maps:get(O,Op,'=='),field_idx(A1,Fields,1),field_idx(A2,Fields,1)}|| [A1,O,A2] <- W],
|
||||
[{list_to_tuple([binary_to_atom(R)|MP]),C,['$$']}].
|
||||
|
||||
field_idx (F,[],_) -> F;
|
||||
field_idx (F,[F|_],N) -> binary_to_atom(list_to_binary([$$,integer_to_list(N)]));
|
||||
field_idx (F,[_|T],N) -> field_idx(F,T,N+1).
|
||||
|
||||
%--------update_records/4-----------------create an updated record to be inserted into ETS from RCP call
|
||||
-spec update_records (TableName :: binary(), NewValues :: #{binary():=any()}, Records :: [[any()]], Acc :: [[any()]]) -> [tuple()].
|
||||
update_records (_,_,[],Acc) ->
|
||||
Acc;
|
||||
update_records (T,V,[R|Rest],Acc) ->
|
||||
Fields = rec_fields(T),
|
||||
Default = maps:from_list(lists:zip(Fields,tl(tuple_to_list(default_record(T))))),
|
||||
Cand = maps:from_list(lists:zip(Fields,R)),
|
||||
DefCand = maps:merge(Default,Cand),
|
||||
ResMap = maps:merge(DefCand,V),
|
||||
Rec = list_to_tuple([binary_to_atom(T)|[maps:get(X,ResMap,<<"###WILL_CRASH###">>) || X<-Fields]]),
|
||||
update_records(T,V,Rest,[Rec|Acc]).
|
||||
make_res_rows ([H|T],C,Acc) ->
|
||||
M = maps:from_list([{F,V}|| {F,V}<-maps:to_list(H), lists:member(F,C)]),
|
||||
make_res_rows(T,C,[M|Acc]).
|
||||
|
||||
%--------read_schema/1-------------------reads the schema from disk for a particular device type
|
||||
-spec read_schema(Store :: ets:tid()) -> binary().
|
||||
@@ -315,70 +156,3 @@ read_schema (Store) ->
|
||||
?L_EA("Cannot read schmea file for model: ~s",[Model]),
|
||||
<<>>
|
||||
end.
|
||||
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% record convertion helpers
|
||||
-spec rec_fields (RecordName :: binary()) -> Fieldnames :: [binary()].
|
||||
rec_fields (<<"Wifi_Inet_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Inet_Config')];
|
||||
rec_fields (<<"Wifi_Radio_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Radio_Config')];
|
||||
rec_fields (<<"Wifi_VIF_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_VIF_Config')];
|
||||
rec_fields (<<"Wifi_VIF_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_VIF_State')];
|
||||
rec_fields (<<"Wifi_Associated_Clients">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Associated_Clients')];
|
||||
rec_fields (<<"Command_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Command_State')];
|
||||
rec_fields (<<"DHCP_leased_IP">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'DHCP_leased_IP')];
|
||||
rec_fields (<<"Wifi_RRM_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_RRM_Config')];
|
||||
rec_fields (<<"Hotspot20_Icon_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Hotspot20_Icon_Config')];
|
||||
rec_fields (<<"Hotspot20_OSU_Providers">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Hotspot20_OSU_Providers')];
|
||||
rec_fields (<<"Hotspot20_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Hotspot20_Config')];
|
||||
rec_fields (<<"Wifi_Stats_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Stats_Config')];
|
||||
rec_fields (<<"Wifi_Radio_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Radio_State')];
|
||||
rec_fields (<<"Wifi_Inet_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Inet_State')];
|
||||
rec_fields (<<"AWLAN_Node">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'AWLAN_Node')].
|
||||
|
||||
-spec default_record(RecordName::binary) -> Record :: tuple().
|
||||
default_record (<<"Wifi_Inet_Config">>) ->
|
||||
#'Wifi_Inet_Config'{};
|
||||
default_record (<<"Wifi_Radio_Config">>) ->
|
||||
#'Wifi_Radio_Config'{};
|
||||
default_record (<<"Wifi_VIF_Config">>) ->
|
||||
#'Wifi_VIF_Config'{};
|
||||
default_record (<<"Wifi_VIF_State">>) ->
|
||||
#'Wifi_VIF_State'{};
|
||||
default_record (<<"Wifi_Associated_Clients">>) ->
|
||||
#'Wifi_Associated_Clients'{};
|
||||
default_record (<<"Command_State">>) ->
|
||||
#'Command_State'{};
|
||||
default_record (<<"DHCP_leased_IP">>) ->
|
||||
#'DHCP_leased_IP'{};
|
||||
default_record (<<"Wifi_RRM_Config">>) ->
|
||||
#'Wifi_RRM_Config'{};
|
||||
default_record (<<"Hotspot20_Icon_Config">>) ->
|
||||
#'Hotspot20_Icon_Config'{};
|
||||
default_record (<<"Hotspot20_OSU_Providers">>) ->
|
||||
#'Hotspot20_OSU_Providers'{};
|
||||
default_record (<<"Hotspot20_Config">>) ->
|
||||
#'Hotspot20_Config'{};
|
||||
default_record (<<"Wifi_Stats_Config">>) ->
|
||||
#'Wifi_Stats_Config'{};
|
||||
default_record (<<"Wifi_Radio_State">>) ->
|
||||
#'Wifi_Radio_State'{};
|
||||
default_record (<<"Wifi_Inet_State">>) ->
|
||||
#'Wifi_Inet_State'{};
|
||||
default_record (<<"AWLAN_Node">>) ->
|
||||
#'AWLAN_Node'{}.
|
||||
|
||||
257
src/ovsdb_dba.erl
Normal file
257
src/ovsdb_dba.erl
Normal file
@@ -0,0 +1,257 @@
|
||||
%%%-----------------------------------------------------------------------------
|
||||
%%% @author helge
|
||||
%%% @copyright (C) 2020, Arilia Wireless Inc.
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 17. December 2020 @ 11:21:29
|
||||
%%%-----------------------------------------------------------------------------
|
||||
-module(ovsdb_dba).
|
||||
-author("helge").
|
||||
|
||||
-include("../include/common.hrl").
|
||||
-include("../include/ovsdb_ap_tables.hrl").
|
||||
|
||||
-export ([select/3,select_with_key/3,delete/3,delete_ret/3,insert/3,update/4,mutate_table/4]).
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% common types
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
-type selspec() :: [binary(),...].
|
||||
-type matchspec() :: [{tuple(),list(),list()},...].
|
||||
-type db_record() :: #{binary()=>term()}.
|
||||
-type db_records() :: [db_record()].
|
||||
|
||||
-export_type ([selspec/0]).
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% API: table / database access
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-spec select (TableName :: binary(), Where :: selspec(), Store :: ets:tid()) -> Rows :: db_records().
|
||||
select (T,W,S) ->
|
||||
MSpec = create_match_spec(T,W),
|
||||
R = ets:select(S,MSpec),
|
||||
Fields = tl(rec_fields(T)), % drop the first field since that is our internal key index
|
||||
[ maps:from_list(lists:zip(Fields,tl(X))) || X <- R ].
|
||||
|
||||
-spec select_with_key (TableName :: binary(), Where :: selspec(), Store :: ets:tid()) -> [{Key :: binary(), db_record()}].
|
||||
select_with_key(T,W,S) ->
|
||||
MSpec = create_match_spec(T,W),
|
||||
R = ets:select(S,MSpec),
|
||||
[ maps:take(<<"**key_id**">>,X) || X <- [ maps:from_list(lists:zip(rec_fields(T),X)) || X <- R ]].
|
||||
|
||||
|
||||
|
||||
-spec delete (TableName :: binary(), Where :: selspec(), Store :: ets:tid()) -> NumDeleted :: integer().
|
||||
delete (T,W,S) ->
|
||||
MSpec = create_match_spec(T,W),
|
||||
DelSpec = [ setelement(3,X,[true]) || X <- MSpec ],
|
||||
ets:select_delete(S,DelSpec).
|
||||
|
||||
-spec delete_ret (TableName :: binary(), Where :: selspec(), Store :: ets:tid()) -> DeletedRows :: [tuple()].
|
||||
delete_ret (T,W,S) ->
|
||||
MSpec = create_match_spec(T,W),
|
||||
DelSpec = [ setelement(3,X,[true]) || X <- MSpec ],
|
||||
R = ets:select(S,MSpec),
|
||||
_ = ets:select_delete(S,DelSpec),
|
||||
Fields = tl(rec_fields(T)), % drop the first field since that is our internal key index
|
||||
[ maps:from_list(lists:zip(Fields,tl(X))) || X <- R ].
|
||||
|
||||
-spec insert (TableName :: binary(), Records :: db_record() | db_records(), Store :: ets:tid()) -> RowUUIDs :: [binary()].
|
||||
insert (T,R,S) when is_map(R) ->
|
||||
insert (T,[R],S);
|
||||
insert (T,R,S) ->
|
||||
{UUIDs,ModRec} = lists:unzip([ make_row_uuid(T,X) || X <- R ]),
|
||||
ets:insert(S,ModRec),
|
||||
UUIDs.
|
||||
|
||||
-spec update (TableName :: binary(), Record :: db_record(), Where :: selspec(), Store :: ets:tid()) -> RowUUIDs :: [binary()].
|
||||
update (T,R,W,S) ->
|
||||
MSpec = create_match_spec(T,W),
|
||||
DelSpec = [ setelement(3,X,[true]) || X <- MSpec ],
|
||||
Res = ets:select(S,MSpec),
|
||||
_ = ets:select_delete(S,DelSpec),
|
||||
Old = [ maps:from_list(lists:zip(rec_fields(T),X)) || X <- Res ],
|
||||
{UUIDs,ModRec} = lists:unzip([ modify_row_record(T,X,R) || X <- Old ]),
|
||||
ets:insert(S,ModRec),
|
||||
UUIDs.
|
||||
|
||||
-spec mutate_table (TableName :: binary(), Mutations :: [[any()]], Where :: selspec(), Store :: ets:tid()) -> RowsAffected :: integer().
|
||||
mutate_table (Table,Mut,Where,Store) ->
|
||||
MSpec = create_match_spec(Table,Where),
|
||||
DelSpec = [ setelement(3,X,[true]) || X <- MSpec ],
|
||||
Res = ets:select(Store,MSpec),
|
||||
_ = ets:select_delete(Store,DelSpec),
|
||||
ToMutate = [ maps:from_list(lists:zip(rec_fields(Table),X)) || X <- Res ],
|
||||
Mutated = [ mutate_table_row(Table,Mut,X) || X <- ToMutate ],
|
||||
ets:insert(Store,Mutated),
|
||||
length(Mutated).
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% internal DB access functions
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-spec make_row_uuid (TableName :: binary(), Record :: db_record()) -> {UUID :: binary(), ModRecord :: tuple()}.
|
||||
make_row_uuid (T,R) ->
|
||||
Fields = rec_fields(T),
|
||||
D_map = maps:from_list(lists:zip(Fields,default_values(T))),
|
||||
Ins_map = maps:merge(D_map,R),
|
||||
UUID = utils:uuid_b(),
|
||||
F = fun ({<<"_uuid">>,[<<"uuid">>,_]}) ->
|
||||
{<<"_uuid">>,[<<"uuid">>,UUID]};
|
||||
({<<"**key_id**">>,_}) ->
|
||||
{<<"**key_id**">>,UUID};
|
||||
(X) ->
|
||||
X
|
||||
end,
|
||||
URec = maps:from_list([ F(X) || X <- maps:to_list(Ins_map) ]),
|
||||
{ UUID, map_to_record(T,URec)}.
|
||||
|
||||
-spec modify_row_record (TableName :: binary(), OldRecord :: db_record(), NewRecord :: db_record()) -> {UUID :: binary(), ModRecord :: tuple()}.
|
||||
modify_row_record(T,O,N) ->
|
||||
Fields = rec_fields(T),
|
||||
D_map = maps:from_list(lists:zip(Fields,default_values(T))),
|
||||
Ins_map = maps:merge(maps:merge(D_map,O),N),
|
||||
#{<<"**key_id**">>:=KeyID } = O,
|
||||
UUID = case N of
|
||||
#{<<"_uuid">>:=[<<"uuid">>,V]} ->
|
||||
V;
|
||||
#{<<"_uuid">>:=V} when is_binary(V) ->
|
||||
V;
|
||||
_ ->
|
||||
utils:uuid_b()
|
||||
end,
|
||||
F = fun ({<<"_uuid">>,[<<"uuid">>,_]}) ->
|
||||
{<<"_uuid">>,[<<"uuid">>,UUID]};
|
||||
({<<"**key_id**">>,_}) ->
|
||||
{<<"**key_id**">>,KeyID};
|
||||
(X) ->
|
||||
X
|
||||
end,
|
||||
URec = maps:from_list([ F(X) || X <- maps:to_list(Ins_map) ]),
|
||||
{ KeyID, map_to_record(T,URec)}.
|
||||
|
||||
-spec mutate_table_row (TableName :: binary(), Mutations :: [[any()]], Where :: [any()]) -> MutatedRecord :: tuple().
|
||||
mutate_table_row (T,[],MutRow) ->
|
||||
map_to_record(T,MutRow);
|
||||
mutate_table_row (Table,[Mut|Tail],MutRow) ->
|
||||
Mutated = apply_mutation(Mut,MutRow),
|
||||
mutate_table_row(Table,Tail,Mutated).
|
||||
|
||||
-spec apply_mutation (Mutations :: [], ToMutate :: #{binary()=>any()}) -> Mutated :: #{binary()=>any()}.
|
||||
apply_mutation ([Field,<<"insert">>,What],RowMap) when is_map_key(Field,RowMap) ->
|
||||
#{Field:=V} = RowMap,
|
||||
NewValue = case V of
|
||||
[K,Up] when is_list(V) ->
|
||||
[K,lists:reverse([What | lists:reverse(Up)])];
|
||||
_ ->
|
||||
V
|
||||
end,
|
||||
RowMap#{Field=>NewValue};
|
||||
apply_mutation ([F,Op,_],RowMap) ->
|
||||
?L_EA("table mutation with operation '~s' on Fields '~s' not supported!",[Op,F]),
|
||||
RowMap.
|
||||
|
||||
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% internal functions
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
-spec create_match_spec (TableName :: binary(), Where :: selspec()) -> MatchSpec :: matchspec().
|
||||
create_match_spec (R,W) ->
|
||||
Op = #{<<"==">>=>'==', <<"!=">>=>'/=', <<"<=">>=>'<=', <<"<">>=>'<', <<">=">>=>'>=', <<">">>=>'>'},
|
||||
Fields = rec_fields(R),
|
||||
MP = [binary_to_atom(list_to_binary([$$,integer_to_list(X)])) || X<-lists:seq(1,length(Fields))],
|
||||
C = [{maps:get(O,Op,'=='),field_idx(A1,Fields,1),field_idx(A2,Fields,1)}|| [A1,O,A2] <- W],
|
||||
[{list_to_tuple([binary_to_atom(R)|MP]),C,['$$']}].
|
||||
|
||||
field_idx (F,[],_) -> F;
|
||||
field_idx (F,[F|_],N) -> binary_to_atom(list_to_binary([$$,integer_to_list(N)]));
|
||||
field_idx (F,[_|T],N) -> field_idx(F,T,N+1).
|
||||
|
||||
-spec map_to_record (TableName :: binary(), Map :: #{binary()=>any()}) -> Record :: tuple().
|
||||
map_to_record (T,M) ->
|
||||
Fields = rec_fields(T),
|
||||
List = [ maps:get(X,M,<<"###CRASH###">>) || X <- Fields],
|
||||
list_to_tuple([binary_to_atom(T) | List]).
|
||||
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% record convertion helpers
|
||||
-spec rec_fields (RecordName :: binary()) -> Fieldnames :: [binary()].
|
||||
rec_fields (<<"Wifi_Inet_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Inet_Config')];
|
||||
rec_fields (<<"Wifi_Radio_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Radio_Config')];
|
||||
rec_fields (<<"Wifi_VIF_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_VIF_Config')];
|
||||
rec_fields (<<"Wifi_VIF_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_VIF_State')];
|
||||
rec_fields (<<"Wifi_Associated_Clients">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Associated_Clients')];
|
||||
rec_fields (<<"Command_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Command_State')];
|
||||
rec_fields (<<"DHCP_leased_IP">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'DHCP_leased_IP')];
|
||||
rec_fields (<<"Wifi_RRM_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_RRM_Config')];
|
||||
rec_fields (<<"Hotspot20_Icon_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Hotspot20_Icon_Config')];
|
||||
rec_fields (<<"Hotspot20_OSU_Providers">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Hotspot20_OSU_Providers')];
|
||||
rec_fields (<<"Hotspot20_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Hotspot20_Config')];
|
||||
rec_fields (<<"Wifi_Stats_Config">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Stats_Config')];
|
||||
rec_fields (<<"Wifi_Radio_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Radio_State')];
|
||||
rec_fields (<<"Wifi_Inet_State">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'Wifi_Inet_State')];
|
||||
rec_fields (<<"AWLAN_Node">>) ->
|
||||
[atom_to_binary(X)||X<-record_info(fields,'AWLAN_Node')].
|
||||
|
||||
-spec default_record(RecordName::binary()) -> Record :: tuple().
|
||||
default_record (<<"Wifi_Inet_Config">>) ->
|
||||
#'Wifi_Inet_Config'{};
|
||||
default_record (<<"Wifi_Radio_Config">>) ->
|
||||
#'Wifi_Radio_Config'{};
|
||||
default_record (<<"Wifi_VIF_Config">>) ->
|
||||
#'Wifi_VIF_Config'{};
|
||||
default_record (<<"Wifi_VIF_State">>) ->
|
||||
#'Wifi_VIF_State'{};
|
||||
default_record (<<"Wifi_Associated_Clients">>) ->
|
||||
#'Wifi_Associated_Clients'{};
|
||||
default_record (<<"Command_State">>) ->
|
||||
#'Command_State'{};
|
||||
default_record (<<"DHCP_leased_IP">>) ->
|
||||
#'DHCP_leased_IP'{};
|
||||
default_record (<<"Wifi_RRM_Config">>) ->
|
||||
#'Wifi_RRM_Config'{};
|
||||
default_record (<<"Hotspot20_Icon_Config">>) ->
|
||||
#'Hotspot20_Icon_Config'{};
|
||||
default_record (<<"Hotspot20_OSU_Providers">>) ->
|
||||
#'Hotspot20_OSU_Providers'{};
|
||||
default_record (<<"Hotspot20_Config">>) ->
|
||||
#'Hotspot20_Config'{};
|
||||
default_record (<<"Wifi_Stats_Config">>) ->
|
||||
#'Wifi_Stats_Config'{};
|
||||
default_record (<<"Wifi_Radio_State">>) ->
|
||||
#'Wifi_Radio_State'{};
|
||||
default_record (<<"Wifi_Inet_State">>) ->
|
||||
#'Wifi_Inet_State'{};
|
||||
default_record (<<"AWLAN_Node">>) ->
|
||||
#'AWLAN_Node'{}.
|
||||
|
||||
-spec default_values(RecordName::binary()) -> Values :: [term()].
|
||||
default_values(T) ->
|
||||
[_|R] = tuple_to_list(default_record(T)),
|
||||
R.
|
||||
|
||||
@@ -329,6 +329,17 @@ c1()->
|
||||
nodes = ['simnode1@debfarm1-node-c.arilia.com'] },
|
||||
simengine:create(Simulation).
|
||||
|
||||
t1_key_h() ->
|
||||
_ = import_ca("sim1","mypassword","tip2-cakey.pem","tip2-cacert.pem"),
|
||||
Simulation = #simulation{ name = <<"sim1">>,
|
||||
ca = <<"sim1">>,
|
||||
num_devices = 10,
|
||||
opensync_server_port = 6643,
|
||||
opensync_server_name = <<"10.20.0.118">>,
|
||||
nodes = ['simnode1@hypatia.syramo.com'] },
|
||||
simengine:create(Simulation).
|
||||
|
||||
|
||||
r1(X)->
|
||||
w(X),
|
||||
_ = push_simulation("sim1"),
|
||||
|
||||
Reference in New Issue
Block a user