@@ -484,7 +484,7 @@ if Code.ensure_loaded?(Circuits.UART) do
484484 :supervisor
485485 ] )
486486
487- validate_open_opts ( opts2 )
487+ validate_open_opts ( opts2 , "open/2" )
488488
489489 GenServer . start_link ( __MODULE__ , { callback , Map . new ( opts2 ) } , genserver_opts )
490490 end
@@ -497,6 +497,91 @@ if Code.ensure_loaded?(Circuits.UART) do
497497 GenServer . call ( transport , :close )
498498 end
499499
500+ @ doc """
501+ Get the current transport state.
502+
503+ This function is important when disabling token passing and
504+ waiting for the transport to transition to the IDLE or NO_TOKEN state,
505+ to then be able to shut down the transport gracefully.
506+
507+ See also `disable_token_passing/1`.
508+ """
509+ @ spec get_state ( TransportBehaviour . transport ( ) ) :: :idle | :no_token | atom ( )
510+ def get_state ( transport ) when is_server ( transport ) do
511+ GenServer . call ( transport , :get_state )
512+ end
513+
514+ @ doc """
515+ Disables the transport's token passing (only if master node).
516+
517+ Disabling the token passing will try to pass on the token, if held,
518+ as soon as possible, but only if the successor is known.
519+ If the successor is unknown or a timeout occurrs, the token will be dropped.
520+ The consequence of dropping the token will be that the remaining
521+ MS/TP master nodes will notice the lost token and generate a new token.
522+
523+ Whether it transitions to IDLE or NO_TOKEN state depends on
524+ its current state and could even change later on from IDLE to NO_TOKEN.
525+ Once the transport reaches IDLE or NO_TOKEN, the transport can be
526+ safely shut down.
527+
528+ When the token passing is disabled, sending any frame that does not
529+ involve sending a reply is disabled and return an error.
530+
531+ After disabling the transport token passing, it can only be re-enabled
532+ by restarting the transport.
533+ """
534+ @ spec disable_token_passing ( TransportBehaviour . transport ( ) ) :: :ok | { :error , term ( ) }
535+ def disable_token_passing ( transport ) when is_server ( transport ) do
536+ GenServer . call ( transport , :disable_token_passing )
537+ end
538+
539+ @ doc """
540+ Configures the transport.
541+
542+ Only some of the available `t:open_options/0` can be configured,
543+ unsupported options can only be changed by re-starting the transport completely.
544+
545+ The following options are supported:
546+ - `baudrate`
547+ - `log_communication`
548+ - `log_communication_rcv`
549+ - `max_info_frames`
550+ - `max_master_address`
551+
552+ For a description of each option, see `open/2`.
553+
554+ Note that reconfiguring the baudrate on the fly MAY lead to invalid frames!
555+ May also lead to dropping token.
556+ """
557+ @ spec configure ( TransportBehaviour . transport ( ) , open_options ( ) ) :: :ok | { :error , term ( ) }
558+ def configure ( transport , opts ) when is_server ( transport ) and is_list ( opts ) do
559+ unless Keyword . keyword? ( opts ) do
560+ raise ArgumentError , "configure/2 expected a keyword list, got: #{ inspect ( opts ) } "
561+ end
562+
563+ validate_open_opts ( opts , "configure/2" )
564+
565+ Enum . each ( opts , fn
566+ # Supported options
567+ { key , _val }
568+ when key in [
569+ :baudrate ,
570+ :log_communication ,
571+ :log_communication_rcv ,
572+ :max_info_frames ,
573+ :max_master_address
574+ ] ->
575+ true
576+
577+ { key , _val } ->
578+ raise ArgumentError ,
579+ "configure/2 does not supported option " <> inspect ( key )
580+ end )
581+
582+ GenServer . call ( transport , { :configure , Map . new ( opts ) } )
583+ end
584+
500585 @ doc """
501586 Get the broadcast address.
502587 """
@@ -714,94 +799,6 @@ if Code.ensure_loaded?(Circuits.UART) do
714799 is_integer ( destination ) and destination >= 0 and destination <= 255
715800 end
716801
717- @ doc """
718- Get the current transport state.
719-
720- This function is important when disabling token passing and
721- waiting for the transport to transition to the IDLE or NO_TOKEN state,
722- to then be able to shut down the transport gracefully.
723-
724- See also `disable_token_passing/1`.
725- """
726- @ spec get_state ( TransportBehaviour . transport ( ) ) :: :idle | :no_token | atom ( )
727- def get_state ( transport ) when is_server ( transport ) do
728- GenServer . call ( transport , :get_state )
729- end
730-
731- @ doc """
732- Disables the transport's token passing (only if master node).
733-
734- Disabling the token passing will try to pass on the token, if held,
735- as soon as possible, but only if the successor is known.
736- If the successor is unknown or a timeout occurrs, the token will be dropped.
737- The consequence of dropping the token will be that the remaining
738- MS/TP master nodes will notice the lost token and generate a new token.
739-
740- Whether it transitions to IDLE or NO_TOKEN state depends on
741- its current state and could even change later on from IDLE to NO_TOKEN.
742- Once the transport reaches IDLE or NO_TOKEN, the transport can be
743- safely shut down.
744-
745- When the token passing is disabled, sending any frame that does not
746- involve sending a reply is disabled and return an error.
747-
748- After disabling the transport token passing, it can only be re-enabled
749- by restarting the transport.
750- """
751- @ spec disable_token_passing ( TransportBehaviour . transport ( ) ) :: :ok | { :error , term ( ) }
752- def disable_token_passing ( transport ) when is_server ( transport ) do
753- GenServer . call ( transport , :disable_token_passing )
754- end
755-
756- @ doc """
757- Configures the transport.
758-
759- Only some of the available `t:open_options/0` can be configured,
760- unsupported options can only be changed by re-starting the transport completely.
761-
762- The following options are supported:
763- - `baudrate`
764- - `log_communication`
765- - `log_communication_rcv`
766- - `max_info_frames`
767- - `max_master_address`
768-
769- For a description of each option, see `open/2`.
770-
771- Note that reconfiguring the baudrate on the fly MAY lead to invalid frames!
772- May also lead to dropping token.
773- """
774- @ spec configure ( TransportBehaviour . transport ( ) , open_options ( ) ) :: :ok | { :error , term ( ) }
775- def configure ( transport , opts ) when is_server ( transport ) and is_list ( opts ) do
776- unless Keyword . keyword? ( opts ) do
777- raise ArgumentError , "configure/2 expected a keyword list, got: #{ inspect ( opts ) } "
778- end
779-
780- Enum . each ( opts , fn
781- { :baudrate , val } when is_integer ( val ) and val > 0 ->
782- true
783-
784- { :log_communication , val } when is_boolean ( val ) ->
785- true
786-
787- { :log_communication_rcv , val } when is_boolean ( val ) ->
788- true
789-
790- { :max_info_frames , val } when is_integer ( val ) and val > 0 ->
791- true
792-
793- { :max_master_address , val } when is_integer ( val ) and val > 0 ->
794- true
795-
796- { key , val } ->
797- raise ArgumentError ,
798- "configure/2 received unsupported combination - key: " <>
799- inspect ( key ) <> ", value: " <> inspect ( val )
800- end )
801-
802- GenServer . call ( transport , { :configure , Map . new ( opts ) } )
803- end
804-
805802 @ doc false
806803 def init ( { callback , opts } ) do
807804 new_opts =
@@ -3279,7 +3276,7 @@ if Code.ensure_loaded?(Circuits.UART) do
32793276 end
32803277
32813278 # credo:disable-for-lines:50 Credo.Check.Refactor.CyclomaticComplexity
3282- defp validate_open_opts ( opts ) do
3279+ defp validate_open_opts ( opts , mfa ) when is_binary ( mfa ) do
32833280 case opts [ :baudrate ] do
32843281 nil ->
32853282 :ok
@@ -3289,21 +3286,23 @@ if Code.ensure_loaded?(Circuits.UART) do
32893286
32903287 term ->
32913288 raise ArgumentError ,
3292- "open/2 expected baudrate to be a non negative integer, " <>
3289+ mfa <>
3290+ " expected baudrate to be a non negative integer, " <>
32933291 "got: #{ inspect ( term ) } "
32943292 end
32953293
32963294 case opts [ :local_address ] do
32973295 nil ->
32983296 raise ArgumentError ,
3299- "open/2 expected local_address to be present (absent in opts)"
3297+ mfa <> " expected local_address to be present (absent in opts)"
33003298
33013299 term when is_integer ( term ) and term >= @ min_master_addr and term <= @ max_slave_addr ->
33023300 :ok
33033301
33043302 term ->
33053303 raise ArgumentError ,
3306- "open/2 expected local_address to be a valid address in the range of 0-254, " <>
3304+ mfa <>
3305+ " expected local_address to be a valid address in the range of 0-254, " <>
33073306 "got: #{ inspect ( term ) } "
33083307 end
33093308
@@ -3316,7 +3315,8 @@ if Code.ensure_loaded?(Circuits.UART) do
33163315
33173316 term ->
33183317 raise ArgumentError ,
3319- "open/2 expected log_communication to be a boolean, " <>
3318+ mfa <>
3319+ " expected log_communication to be a boolean, " <>
33203320 "got: #{ inspect ( term ) } "
33213321 end
33223322
@@ -3329,7 +3329,8 @@ if Code.ensure_loaded?(Circuits.UART) do
33293329
33303330 term ->
33313331 raise ArgumentError ,
3332- "open/2 expected log_communication_rcv to be a boolean, " <>
3332+ mfa <>
3333+ " expected log_communication_rcv to be a boolean, " <>
33333334 "got: #{ inspect ( term ) } "
33343335 end
33353336
@@ -3342,7 +3343,8 @@ if Code.ensure_loaded?(Circuits.UART) do
33423343
33433344 term ->
33443345 raise ArgumentError ,
3345- "open/2 expected max_info_frames to be a positive integer, " <>
3346+ mfa <>
3347+ " expected max_info_frames to be a positive integer, " <>
33463348 "got: #{ inspect ( term ) } "
33473349 end
33483350
@@ -3355,21 +3357,23 @@ if Code.ensure_loaded?(Circuits.UART) do
33553357
33563358 term ->
33573359 raise ArgumentError ,
3358- "open/2 expected max_master_address to be an integer in the range 0-127, " <>
3360+ mfa <>
3361+ " expected max_master_address to be an integer in the range 0-127, " <>
33593362 "got: #{ inspect ( term ) } "
33603363 end
33613364
33623365 case opts [ :port_name ] do
33633366 nil ->
33643367 raise ArgumentError ,
3365- "open/2 expected port_name to be present (absent in opts)"
3368+ mfa <> " expected port_name to be present (absent in opts)"
33663369
33673370 term when is_binary ( term ) ->
33683371 :ok
33693372
33703373 term ->
33713374 raise ArgumentError ,
3372- "open/2 expected port_name to be a binary, " <>
3375+ mfa <>
3376+ " expected port_name to be a binary, " <>
33733377 "got: #{ inspect ( term ) } "
33743378 end
33753379
@@ -3394,7 +3398,8 @@ if Code.ensure_loaded?(Circuits.UART) do
33943398
33953399 term ->
33963400 raise ArgumentError ,
3397- "open/2 expected supervisor to be a valid supervisor reference, " <>
3401+ mfa <>
3402+ " expected supervisor to be a valid supervisor reference, " <>
33983403 "got: #{ inspect ( term ) } "
33993404 end
34003405 end
0 commit comments