diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml old mode 100644 new mode 100755 diff --git a/.idea/gradle.xml b/.idea/gradle.xml old mode 100644 new mode 100755 diff --git a/.idea/misc.xml b/.idea/misc.xml old mode 100644 new mode 100755 diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml old mode 100644 new mode 100755 diff --git a/.idea/vcs.xml b/.idea/vcs.xml old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/app/.gitignore b/app/.gitignore old mode 100644 new mode 100755 diff --git a/app/build.gradle b/app/build.gradle old mode 100644 new mode 100755 diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro old mode 100644 new mode 100755 diff --git a/app/src/androidTest/java/com/example/user/myapp/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/user/myapp/ExampleInstrumentedTest.java deleted file mode 100644 index b8d289f..0000000 --- a/app/src/androidTest/java/com/example/user/myapp/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.user.myapp; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.example.user.myapp", appContext.getPackageName()); - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml old mode 100644 new mode 100755 diff --git a/app/src/main/java/com/example/user/myapp/DisplayMessageActivity.java b/app/src/main/java/com/example/user/myapp/DisplayMessageActivity.java deleted file mode 100644 index 3717a74..0000000 --- a/app/src/main/java/com/example/user/myapp/DisplayMessageActivity.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.example.user.myapp; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.support.v4.content.LocalBroadcastManager; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import java.util.ArrayList; - -public class DisplayMessageActivity extends AppCompatActivity { - - private Handler handlerCoil; - private Handler handlerInputRegister; - private Handler handlerDiscreteInput; - - private GlobalState state; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_display_message); - - // listener - LocalBroadcastManager.getInstance(this).registerReceiver(coilMessageReceiver, new IntentFilter("readOnlyCoil")); - LocalBroadcastManager.getInstance(this).registerReceiver(discreteInputMessageReceiver, new IntentFilter("readOnlyDiscreteInput")); - LocalBroadcastManager.getInstance(this).registerReceiver(inputRegisterMessageReceiver, new IntentFilter("readOnlyInputRegister")); - - state = (GlobalState) getApplicationContext(); - - Toast toast = Toast.makeText(getApplicationContext(), "This is my toast !", Toast.LENGTH_LONG); - toast.show(); - //handler - handlerCoil = new Handler(); - handlerCoil.post(refreshCoil); - - handlerInputRegister = new Handler(); - handlerInputRegister.post(refreshInputRegister); - - handlerDiscreteInput = new Handler(); - handlerDiscreteInput.post(refreshDiscreteInput); - } - - Runnable refreshCoil = new Runnable() { - @Override - public void run() { - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("read.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.Q_COIL.getStartReference()); - serviceIntent.putExtra("extra.count", GlobalState.InputConfig.Q_COIL.getCount()); - serviceIntent.putExtra("extra.intent.name", "readOnlyCoil"); - getApplicationContext().startService(serviceIntent); - - handlerCoil.postDelayed(this, 2000); - } - }; - - Runnable refreshDiscreteInput = new Runnable() { - @Override - public void run() { - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("read.discrete.input"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.I_DI.getStartReference()); - serviceIntent.putExtra("extra.count", GlobalState.InputConfig.I_DI.getCount()); - serviceIntent.putExtra("extra.intent.name", "readOnlyDiscreteInput"); - getApplicationContext().startService(serviceIntent); - - handlerDiscreteInput.postDelayed(this, 5000); - } - }; - - Runnable refreshInputRegister = new Runnable() { - @Override - public void run() { - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("read.input.register"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.AI_IR.getStartReference()); - serviceIntent.putExtra("extra.count", GlobalState.InputConfig.AI_IR.getCount()); - serviceIntent.putExtra("extra.intent.name", "readOnlyInputRegister"); - getApplicationContext().startService(serviceIntent); - - handlerInputRegister.postDelayed(this, 1000); - } - }; - - // on message receive, update the view with values - private BroadcastReceiver coilMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Bundle bundle = intent.getExtras(); - boolean[] booleanArray = bundle.getBooleanArray("coilValues"); - - TextView textView1 = findViewById(R.id.textView1); - textView1.setText(new Boolean(booleanArray[0]).toString()); - - TextView textView2 = findViewById(R.id.textView2); - textView2.setText(new Boolean(booleanArray[1]).toString()); - - TextView textView3 = findViewById(R.id.textView3); - textView3.setText(new Boolean(booleanArray[2]).toString()); - - TextView textView4 = findViewById(R.id.textView4); - textView4.setText(new Boolean(booleanArray[3]).toString()); - - TextView textView5 = findViewById(R.id.textView5); - textView5.setText(new Boolean(booleanArray[4]).toString()); - - TextView textView6 = findViewById(R.id.textView6); - textView6.setText(new Boolean(booleanArray[5]).toString()); - - TextView textView7 = findViewById(R.id.textView7); - textView7.setText(new Boolean(booleanArray[6]).toString()); - - TextView textView8 = findViewById(R.id.textView8); - textView8.setText(new Boolean(booleanArray[7]).toString()); - } - }; - - private BroadcastReceiver inputRegisterMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Bundle bundle = intent.getExtras(); - ArrayList integerArrayList = bundle.getIntegerArrayList("irValues"); - - TextView textView9 = findViewById(R.id.textView9); - textView9.setText(integerArrayList.get(0).toString()); - } - }; - - private BroadcastReceiver discreteInputMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Bundle bundle = intent.getExtras(); - boolean[] booleanArray = bundle.getBooleanArray("discreteInputValues"); - - TextView textView10 = findViewById(R.id.textView10); - textView10.setText(new Boolean(booleanArray[0]).toString()); - - TextView textView11 = findViewById(R.id.h2_textview); - textView11.setText(new Boolean(booleanArray[1]).toString()); - - TextView textView12 = findViewById(R.id.h1_textview); - textView12.setText(new Boolean(booleanArray[2]).toString()); - - TextView textView13 = findViewById(R.id.textView13); - textView13.setText(new Boolean(booleanArray[3]).toString()); - - TextView textView14 = findViewById(R.id.textView14); - textView14.setText(new Boolean(booleanArray[4]).toString()); - - TextView textView15 = findViewById(R.id.textView15); - textView15.setText(new Boolean(booleanArray[5]).toString()); - - TextView textView16 = findViewById(R.id.textView16); - textView16.setText(new Boolean(booleanArray[6]).toString()); - - TextView textView17 = findViewById(R.id.textView17); - textView17.setText(new Boolean(booleanArray[7]).toString()); - - TextView textView18 = findViewById(R.id.textView18); - textView18.setText(new Boolean(booleanArray[8]).toString()); - - TextView textView19 = findViewById(R.id.textView19); - textView19.setText(new Boolean(booleanArray[9]).toString()); - - TextView textView20 = findViewById(R.id.textView20); - textView20.setText(new Boolean(booleanArray[10]).toString()); - - TextView textView21 = findViewById(R.id.textView21); - textView21.setText(new Boolean(booleanArray[11]).toString()); - } - }; -} diff --git a/app/src/main/java/com/example/user/myapp/GlobalState.java b/app/src/main/java/com/example/user/myapp/GlobalState.java deleted file mode 100644 index a0a3d94..0000000 --- a/app/src/main/java/com/example/user/myapp/GlobalState.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.example.user.myapp; - -import android.app.Application; - -import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; -import com.ghgande.j2mod.modbus.net.TCPMasterConnection; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.HashMap; - -public class GlobalState extends Application { - - private String ipAddress = "172.16.202.14"; - private int port = 502; - private HashMap mapMappingValue = new HashMap(); - // - public enum InputConfig { - Q_COIL(8192, 8), - VM_COIL2 (1, 8), - VM_COIL3 (64, 8), - AI_IR(0, 2), - I_DI(0, 12); - - private int startReference; - private int count; - - InputConfig (int startReference, int count) { - this.startReference = startReference; - this.count = count; - } - - - // getter/setter - public int getStartReference() { - return startReference; - } - - public int getCount() { - return count; - } - } - - public HashMap getMapMappingValue() { - initMappingValue(); - return mapMappingValue; - } - - // getter/setter - public String getIpAddress() { - return ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - private void initMappingValue () { - mapMappingValue.clear(); - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference(), InputConfig.Q_COIL.getStartReference()); // 64/8192 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 6, InputConfig.Q_COIL.getStartReference() + 1); // 70/8193 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 1, InputConfig.Q_COIL.getStartReference() + 4); // 65/8196 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 7, InputConfig.Q_COIL.getStartReference() + 5); // 71/8197 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 4, InputConfig.Q_COIL.getStartReference() + 6); // 68/8198 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 5, InputConfig.Q_COIL.getStartReference() + 7); // 69/8199 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 2, InputConfig.Q_COIL.getStartReference() + 2); // 66/8194 - mapMappingValue.put(InputConfig.VM_COIL3.getStartReference() + 3, InputConfig.Q_COIL.getStartReference() + 3); // 67/8195 - } -} diff --git a/app/src/main/java/com/example/user/myapp/MainActivity.java b/app/src/main/java/com/example/user/myapp/MainActivity.java deleted file mode 100644 index 9e15bf9..0000000 --- a/app/src/main/java/com/example/user/myapp/MainActivity.java +++ /dev/null @@ -1,268 +0,0 @@ -package com.example.user.myapp; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.support.v4.content.LocalBroadcastManager; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -public class MainActivity extends AppCompatActivity { - - private Handler handlerCoil; - private Handler handlerDiscreteInput; - - private GlobalState state; - private static final Integer REFRESH_DELAY = 1000; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - state = (GlobalState) getApplicationContext(); - // listener - LocalBroadcastManager.getInstance(this).registerReceiver(coilMessageReceiver, new IntentFilter("readOnlyCoil")); - LocalBroadcastManager.getInstance(this).registerReceiver(discreteInputMessageReceiver, new IntentFilter("readOnlyDiscreteInput")); - // handler - handlerCoil = new Handler(); - handlerCoil.post(refreshCoil); - - handlerDiscreteInput = new Handler(); - handlerDiscreteInput.post(refreshDiscreteInput); - - setContentView(R.layout.activity_main); - - // swipe event - OnSwipeTouchListener onSwipeTouchListener = new OnSwipeTouchListener(MainActivity.this) { - @Override - public void onSwipeLeft() { - Intent nextIntent = new Intent(MainActivity.this, ManualDriveActivity.class); - startActivity(nextIntent); - // handlerCoil.removeCallbacks(refreshCoil); - // handlerDiscreteInput.removeCallbacks(refreshDiscreteInput); - } - }; - - final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0); - viewGroup.setOnTouchListener(onSwipeTouchListener); - } - - @Override - public void onPause () { - super.onPause(); - handlerCoil.removeCallbacks(refreshCoil); - handlerDiscreteInput.removeCallbacks(refreshDiscreteInput); - } - - @Override - public void onResume () { - super.onResume(); - handlerCoil.post(refreshCoil); - handlerDiscreteInput.post(refreshDiscreteInput); - } - - Runnable refreshCoil = new Runnable() { - @Override - public void run() { - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("read.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.Q_COIL.getStartReference()); - serviceIntent.putExtra("extra.count", GlobalState.InputConfig.Q_COIL.getCount()); - serviceIntent.putExtra("extra.intent.name", "readOnlyCoil"); - getApplicationContext().startService(serviceIntent); - - handlerCoil.postDelayed(this, REFRESH_DELAY); - } - }; - - Runnable refreshDiscreteInput = new Runnable() { - @Override - public void run() { - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("read.discrete.input"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.I_DI.getStartReference()); - serviceIntent.putExtra("extra.count", GlobalState.InputConfig.I_DI.getCount()); - serviceIntent.putExtra("extra.intent.name", "readOnlyDiscreteInput"); - getApplicationContext().startService(serviceIntent); - - handlerDiscreteInput.postDelayed(this, REFRESH_DELAY); - } - }; - - // on message receive, update the lights with dependings on coil value - private BroadcastReceiver coilMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Bundle bundle = intent.getExtras(); - boolean[] booleanArray = bundle.getBooleanArray("coilValues"); - - // ============= Light =============== - ImageView pu1StatusLightOn = findViewById(R.id.pu1_status_light_on_mainview); - ImageView pu1StatusLightOff = findViewById(R.id.pu1_status_light_off_mainview); - ImageView pu2StatusLightOn = findViewById(R.id.pu2_status_light_on_mainview); - ImageView pu2StatusLightOff = findViewById(R.id.pu2_status_light_off_mainview); - - ImageView sp1StatusLightOn = findViewById(R.id.sp1_status_light_on_mainview); - ImageView sp1StatusLightOff = findViewById(R.id.sp1_status_light_off_mainview); - ImageView b1StatusLightOn = findViewById(R.id.b1_status_light_on_mainview); - ImageView b1StatusLightOff = findViewById(R.id.b1_status_light_off_mainview); - - ImageView m1StatusLightOn = findViewById(R.id.m1_status_light_on_mainview); - ImageView m1StatusLightOff = findViewById(R.id.m1_status_light_off_mainview); - ImageView m2StatusLightOn = findViewById(R.id.m2_status_light_on_mainview); - ImageView m2StatusLightOff = findViewById(R.id.m2_status_light_off_mainview); - - // ============== Coil : Range 8192 - 8199 ================= - // 8199 - if (booleanArray[7]) { - b1StatusLightOn.setVisibility(View.VISIBLE); - b1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - b1StatusLightOn.setVisibility(View.INVISIBLE); - b1StatusLightOff.setVisibility(View.VISIBLE); - } - - // 8194 - if (booleanArray[2]) { - m1StatusLightOn.setVisibility(View.VISIBLE); - m1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - m1StatusLightOn.setVisibility(View.INVISIBLE); - m1StatusLightOff.setVisibility(View.VISIBLE); - } - - // 8195 - if (booleanArray[3]) { - m2StatusLightOn.setVisibility(View.VISIBLE); - m2StatusLightOff.setVisibility(View.INVISIBLE); - } else { - m2StatusLightOn.setVisibility(View.INVISIBLE); - m2StatusLightOff.setVisibility(View.VISIBLE); - } - - // 8196 - if (booleanArray[4]) { - pu1StatusLightOn.setVisibility(View.VISIBLE); - pu1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - pu1StatusLightOn.setVisibility(View.INVISIBLE); - pu1StatusLightOff.setVisibility(View.VISIBLE); - } - - // 8197 - if (booleanArray[5]) { - pu2StatusLightOn.setVisibility(View.VISIBLE); - pu2StatusLightOff.setVisibility(View.INVISIBLE); - } else { - pu2StatusLightOn.setVisibility(View.INVISIBLE); - pu2StatusLightOff.setVisibility(View.VISIBLE); - } - - // 8198 - if (booleanArray[6]) { - sp1StatusLightOn.setVisibility(View.VISIBLE); - sp1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - sp1StatusLightOn.setVisibility(View.INVISIBLE); - sp1StatusLightOff.setVisibility(View.VISIBLE); - } - } - }; - - private BroadcastReceiver discreteInputMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Bundle bundle = intent.getExtras(); - boolean[] booleanArray = bundle.getBooleanArray("discreteInputValues"); - - // Lights - ImageView h1StatusLightOn = findViewById(R.id.h1_status_light_on_mainview); - ImageView h1StatusLightOff = findViewById(R.id.h1_status_light_off_mainview); - ImageView h2StatusLightOn = findViewById(R.id.h2_status_light_on_mainview); - ImageView h2StatusLightOff = findViewById(R.id.h2_status_light_off_mainview); - - ImageView ind1StatusLightOn = findViewById(R.id.ind1_status_light_on_mainview); - ImageView ind1StatusLightOff = findViewById(R.id.ind1_status_light_off_mainview); - ImageView ls5StatusLightOn = findViewById(R.id.ls5_status_light_on_mainview); - ImageView ls5StatusLightOff = findViewById(R.id.ls5_status_light_off_mainview); - ImageView ls1StatusLightOn = findViewById(R.id.ls1_status_light_on_mainview); - ImageView ls1StatusLightOff = findViewById(R.id.ls1_status_light_off_mainview); - ImageView ls4StatusLightOn = findViewById(R.id.ls4_status_light_on_mainview); - ImageView ls4StatusLightOff = findViewById(R.id.ls4_status_light_off_mainview); - - // ============ Discrete Input : Range 0 - 11 ======================== - // di 1 - if (booleanArray[1]) { - h1StatusLightOff.setVisibility(View.VISIBLE); - } else { - h1StatusLightOff.setVisibility(View.INVISIBLE); - } - - // di 2 - if (booleanArray[2]) { - h1StatusLightOn.setVisibility(View.VISIBLE); - } else { - h1StatusLightOn.setVisibility(View.INVISIBLE); - } - - // di 10 - if (booleanArray[10]) { - h2StatusLightOff.setVisibility(View.VISIBLE); - } else { - h2StatusLightOff.setVisibility(View.INVISIBLE); - } - - // di 9 - if (booleanArray[9]) { - h2StatusLightOn.setVisibility(View.VISIBLE); - } else { - h2StatusLightOn.setVisibility(View.INVISIBLE); - } - - // di 11 - if (booleanArray[11]) { - ind1StatusLightOff.setVisibility(View.INVISIBLE); - ind1StatusLightOn.setVisibility(View.VISIBLE); - } else { - ind1StatusLightOff.setVisibility(View.VISIBLE); - ind1StatusLightOn.setVisibility(View.INVISIBLE); - } - - // di 4 - if (booleanArray[4]) { - ls5StatusLightOff.setVisibility(View.INVISIBLE); - ls5StatusLightOn.setVisibility(View.VISIBLE); - } else { - ls5StatusLightOff.setVisibility(View.VISIBLE); - ls5StatusLightOn.setVisibility(View.INVISIBLE); - } - - // di 0 - if (booleanArray[0]) { - ls1StatusLightOff.setVisibility(View.INVISIBLE); - ls1StatusLightOn.setVisibility(View.VISIBLE); - } else { - ls1StatusLightOff.setVisibility(View.VISIBLE); - ls1StatusLightOn.setVisibility(View.INVISIBLE); - } - - // di 3 - if (booleanArray[3]) { - ls4StatusLightOff.setVisibility(View.INVISIBLE); - ls4StatusLightOn.setVisibility(View.VISIBLE); - } else { - ls4StatusLightOff.setVisibility(View.VISIBLE); - ls4StatusLightOn.setVisibility(View.INVISIBLE); - } - } - }; -} - diff --git a/app/src/main/java/com/example/user/myapp/ManualDriveActivity.java b/app/src/main/java/com/example/user/myapp/ManualDriveActivity.java deleted file mode 100644 index db74488..0000000 --- a/app/src/main/java/com/example/user/myapp/ManualDriveActivity.java +++ /dev/null @@ -1,382 +0,0 @@ -package com.example.user.myapp; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.support.v4.content.LocalBroadcastManager; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.view.MotionEvent; -import android.view.View; -import android.widget.Button; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.ToggleButton; - -import java.util.HashMap; -import java.util.Map; - -public class ManualDriveActivity extends AppCompatActivity { - private GlobalState state; - private Handler coilHandler; - private Handler manualModeCheckHandler; - - private HashMap mapCoilCheckStatus = new HashMap <> (); - private HashMap mapButtonCoil = new HashMap<>(); - private boolean manualMode = false; - - private void initMap () { - mapCoilCheckStatus.put(64, false); - mapCoilCheckStatus.put(70, false); - mapCoilCheckStatus.put(65, false); - mapCoilCheckStatus.put(71, false); - mapCoilCheckStatus.put(68, false); - mapCoilCheckStatus.put(69, false); - mapCoilCheckStatus.put(66, false); - mapCoilCheckStatus.put(67, false); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - state = (GlobalState) getApplicationContext(); - initMap(); // initialise the value of the coil toggle state + the corresponding coil to button - - setContentView(R.layout.activity_manual_drive); - - ToggleButton h1ControlButton =findViewById(R.id.h1_control_button); - ToggleButton h2ControlButton = findViewById(R.id.h2_control_button); - ToggleButton pu1ControlButton = findViewById(R.id.pu1_control_button); - ToggleButton pu2ControlButton = findViewById(R.id.pu2_control_button); - ToggleButton sp1ControlButton = findViewById(R.id.sp1_control_button); - ToggleButton b1ControlButton = findViewById(R.id.b1_control_button); - ToggleButton m1ControlButton = findViewById(R.id.m1_control_button); - ToggleButton m2ControlButton = findViewById(R.id.m2_control_button); - - mapButtonCoil.put(h1ControlButton, 64); - mapButtonCoil.put(h2ControlButton, 72); - mapButtonCoil.put(pu1ControlButton, 65); - mapButtonCoil.put(pu2ControlButton, 73); - mapButtonCoil.put(sp1ControlButton, 68); - mapButtonCoil.put(b1ControlButton, 69); - mapButtonCoil.put(m1ControlButton, 66); - mapButtonCoil.put(m2ControlButton, 67); - - - - LocalBroadcastManager.getInstance(this).registerReceiver(coilWriterMessageReceiver, new IntentFilter("readVmCoil2")); - // LocalBroadcastManager.getInstance(this).registerReceiver(coilWriterMessageReceiver, new IntentFilter("checkCoilValue")); - LocalBroadcastManager.getInstance(this).registerReceiver(coilMessageReceiver, new IntentFilter("readOnlyCoil")); - - // manual drive button - ToggleButton manualDriveOverrideButton = (ToggleButton) findViewById(R.id.manual_override_button); - manualDriveOverrideButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - // writing the value true - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("write.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.VM_COIL2.getStartReference()); - serviceIntent.putExtra("extra.bit", true); - serviceIntent.putExtra("extra.intent.name", "readVmCoil2"); - serviceIntent.putExtra("extra.is.basic.coil", false); - getApplicationContext().startService(serviceIntent); - } else { - // writing the value false - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("write.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.VM_COIL2.getStartReference()); - serviceIntent.putExtra("extra.bit", false); - serviceIntent.putExtra("extra.intent.name", "readVmCoil2"); - serviceIntent.putExtra("extra.is.basic.coil", false); - getApplicationContext().startService(serviceIntent); - } - } - }); - - // for each toggle button, set the event - for (Map.Entry entry : mapButtonCoil.entrySet()) { - final ToggleButton button = entry.getKey(); - final Integer coilToWrite = entry.getValue(); - button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked && manualMode) { - // writing the value true - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("write.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", coilToWrite); - serviceIntent.putExtra("extra.bit", true); - serviceIntent.putExtra("extra.intent.name", "writeBit"); - serviceIntent.putExtra("extra.is.basic.coil", true); - getApplicationContext().startService(serviceIntent); - mapCoilCheckStatus.put(coilToWrite, true); - } else { - // writing the value false - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("write.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", coilToWrite); - serviceIntent.putExtra("extra.bit", false); - serviceIntent.putExtra("extra.intent.name", "writeBit"); - serviceIntent.putExtra("extra.is.basic.coil", true); - getApplicationContext().startService(serviceIntent); - mapCoilCheckStatus.put(coilToWrite, false); - } - } - }); - } - } - - @Override - protected void onStart () { - super.onStart(); - coilHandler = new Handler(); - coilHandler.post(refreshCoil); - - manualModeCheckHandler = new Handler(); - manualModeCheckHandler.post(checkManualMockStatus) ; - } - - private BroadcastReceiver coilWriterMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - boolean isManualModeActivated = intent.getBooleanExtra("coil", false); - if (isManualModeActivated) { - manualMode = true; - } else { - manualMode = false; - } - } - }; - - private Runnable checkManualMockStatus = new Runnable() { - @Override - public void run() { - ToggleButton h1ControlButton = findViewById(R.id.h1_control_button); - ToggleButton h2ControlButton = findViewById(R.id.h2_control_button); - Button pu1ControlButton = findViewById(R.id.pu1_control_button); - Button pu2ControlButton = findViewById(R.id.pu2_control_button); - Button sp1ControlButton = findViewById(R.id.sp1_control_button); - Button b1ControlButton = findViewById(R.id.b1_control_button); - ToggleButton m1ControlButton = findViewById(R.id.m1_control_button); - ToggleButton m2ControlButton = findViewById(R.id.m2_control_button); - - // ============= Light =============== - ImageView manualLightOn = findViewById(R.id.manual_override_status_light_on); - ImageView manualLightOff = findViewById(R.id.manual_override_status_light_off); - - ImageView h1StatusLightOn = findViewById(R.id.h1_status_light_on); - ImageView h1StatusLightOff = findViewById(R.id.h1_status_light_off); - ImageView h2StatusLightOn = findViewById(R.id.h2_status_light_on); - ImageView h2StatusLightOff = findViewById(R.id.h2_status_light_off); - - ImageView pu1StatusLightOn = findViewById(R.id.pu1_status_light_on); - ImageView pu1StatusLightOff = findViewById(R.id.pu1_status_light_off); - ImageView pu2StatusLightOn = findViewById(R.id.pu2_status_light_on); - ImageView pu2StatusLightOff = findViewById(R.id.pu2_status_light_off); - - ImageView sp1StatusLightOn = findViewById(R.id.sp1_status_light_on); - ImageView sp1StatusLightOff = findViewById(R.id.sp1_status_light_off); - ImageView b1StatusLightOn = findViewById(R.id.b1_status_light_on); - ImageView b1StatusLightOff = findViewById(R.id.b1_status_light_off); - - ImageView m1StatusLightOn = findViewById(R.id.m1_status_light_on); - ImageView m1StatusLightOff = findViewById(R.id.m1_status_light_off); - ImageView m2StatusLightOn = findViewById(R.id.m2_status_light_on); - ImageView m2StatusLightOff = findViewById(R.id.m2_status_light_off); - - if (!manualMode) { - manualLightOn.setVisibility(View.INVISIBLE); - manualLightOff.setVisibility(View.VISIBLE); - - h1ControlButton.setEnabled(false); - h2ControlButton.setEnabled(false); - m1ControlButton.setEnabled(false); - m2ControlButton.setEnabled(false); - pu1ControlButton.setEnabled(false); - pu2ControlButton.setEnabled(false); - sp1ControlButton.setEnabled(false); - b1ControlButton.setEnabled(false); - - manualLightOn.setVisibility(View.INVISIBLE); - manualLightOff.setVisibility(View.VISIBLE); - // switch all off - h1StatusLightOn.setVisibility(View.INVISIBLE); - h1StatusLightOff.setVisibility(View.INVISIBLE); - h2StatusLightOn.setVisibility(View.INVISIBLE); - h2StatusLightOff.setVisibility(View.INVISIBLE); - m1StatusLightOn.setVisibility(View.INVISIBLE); - m1StatusLightOff.setVisibility(View.INVISIBLE); - m2StatusLightOn.setVisibility(View.INVISIBLE); - m2StatusLightOff.setVisibility(View.INVISIBLE); - pu1StatusLightOn.setVisibility(View.INVISIBLE); - pu1StatusLightOff.setVisibility(View.INVISIBLE); - pu2StatusLightOn.setVisibility(View.INVISIBLE); - pu2StatusLightOff.setVisibility(View.INVISIBLE); - sp1StatusLightOn.setVisibility(View.INVISIBLE); - sp1StatusLightOff.setVisibility(View.INVISIBLE); - b1StatusLightOn.setVisibility(View.INVISIBLE); - b1StatusLightOff.setVisibility(View.INVISIBLE); - } - manualModeCheckHandler.postDelayed(this, 1000); - } - }; - - private Runnable refreshCoil = new Runnable() { - @Override - public void run() { - Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class); - serviceIntent.setAction("read.coil"); - serviceIntent.putExtra("extra.ip.address", state.getIpAddress()); - serviceIntent.putExtra("extra.ip.port", state.getPort()); - serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.Q_COIL.getStartReference()); - serviceIntent.putExtra("extra.count", GlobalState.InputConfig.Q_COIL.getCount()); - serviceIntent.putExtra("extra.intent.name", "readOnlyCoil"); - getApplicationContext().startService(serviceIntent); - - coilHandler.postDelayed(this, 3000); - } - }; - - // on message receive, update the view with values - private BroadcastReceiver coilMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Bundle bundle = intent.getExtras(); - boolean[] booleanArray = bundle.getBooleanArray("coilValues"); - - // ========== Button ============ - ToggleButton h1ControlButton = findViewById(R.id.h1_control_button); - ToggleButton h2ControlButton = findViewById(R.id.h2_control_button); - Button pu1ControlButton = findViewById(R.id.pu1_control_button); - Button pu2ControlButton = findViewById(R.id.pu2_control_button); - Button sp1ControlButton = findViewById(R.id.sp1_control_button); - Button b1ControlButton = findViewById(R.id.b1_control_button); - ToggleButton m1ControlButton = findViewById(R.id.m1_control_button); - ToggleButton m2ControlButton = findViewById(R.id.m2_control_button); - - // ============= Light =============== - ImageView manualLightOn = findViewById(R.id.manual_override_status_light_on); - ImageView manualLightOff = findViewById(R.id.manual_override_status_light_off); - - ImageView h1StatusLightOn = findViewById(R.id.h1_status_light_on); - ImageView h1StatusLightOff = findViewById(R.id.h1_status_light_off); - ImageView h2StatusLightOn = findViewById(R.id.h2_status_light_on); - ImageView h2StatusLightOff = findViewById(R.id.h2_status_light_off); - - ImageView pu1StatusLightOn = findViewById(R.id.pu1_status_light_on); - ImageView pu1StatusLightOff = findViewById(R.id.pu1_status_light_off); - ImageView pu2StatusLightOn = findViewById(R.id.pu2_status_light_on); - ImageView pu2StatusLightOff = findViewById(R.id.pu2_status_light_off); - - ImageView sp1StatusLightOn = findViewById(R.id.sp1_status_light_on); - ImageView sp1StatusLightOff = findViewById(R.id.sp1_status_light_off); - ImageView b1StatusLightOn = findViewById(R.id.b1_status_light_on); - ImageView b1StatusLightOff = findViewById(R.id.b1_status_light_off); - - ImageView m1StatusLightOn = findViewById(R.id.m1_status_light_on); - ImageView m1StatusLightOff = findViewById(R.id.m1_status_light_off); - ImageView m2StatusLightOn = findViewById(R.id.m2_status_light_on); - ImageView m2StatusLightOff = findViewById(R.id.m2_status_light_off); - - if (manualMode) { - h1ControlButton.setEnabled(true); - h2ControlButton.setEnabled(true); - m1ControlButton.setEnabled(true); - m2ControlButton.setEnabled(true); - pu1ControlButton.setEnabled(true); - pu2ControlButton.setEnabled(true); - sp1ControlButton.setEnabled(true); - b1ControlButton.setEnabled(true); - - manualLightOn.setVisibility(View.VISIBLE); - manualLightOff.setVisibility(View.INVISIBLE); - // lightning - // ======== h1 ========= - if (booleanArray[0] == true) { - h1StatusLightOn.setVisibility(View.VISIBLE); - h1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - h1StatusLightOn.setVisibility(View.INVISIBLE); - h1StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== h2 ====== - if (booleanArray[1] == true) { - h2StatusLightOn.setVisibility(View.VISIBLE); - h2StatusLightOff.setVisibility(View.INVISIBLE); - } else { - h2StatusLightOn.setVisibility(View.INVISIBLE); - h2StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== m1 ====== - if (booleanArray[2] == true) { - m1StatusLightOn.setVisibility(View.VISIBLE); - m1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - m1StatusLightOn.setVisibility(View.INVISIBLE); - m1StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== m2 ====== - if (booleanArray[3] == true) { - m2StatusLightOn.setVisibility(View.VISIBLE); - m2StatusLightOff.setVisibility(View.INVISIBLE); - } else { - m2StatusLightOn.setVisibility(View.INVISIBLE); - m2StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== pu1 ====== - if (booleanArray[4] == true) { - pu1StatusLightOn.setVisibility(View.VISIBLE); - pu1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - pu1StatusLightOn.setVisibility(View.INVISIBLE); - pu1StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== pu2 ====== - if (booleanArray[5] == true) { - pu2StatusLightOn.setVisibility(View.VISIBLE); - pu2StatusLightOff.setVisibility(View.INVISIBLE); - } else { - pu2StatusLightOn.setVisibility(View.INVISIBLE); - pu2StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== m2 ====== - if (booleanArray[6] == true) { - sp1StatusLightOn.setVisibility(View.VISIBLE); - sp1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - sp1StatusLightOn.setVisibility(View.INVISIBLE); - sp1StatusLightOff.setVisibility(View.VISIBLE); - } - - // ======== m2 ====== - if (booleanArray[7] == true) { - b1StatusLightOn.setVisibility(View.VISIBLE); - b1StatusLightOff.setVisibility(View.INVISIBLE); - } else { - b1StatusLightOn.setVisibility(View.INVISIBLE); - b1StatusLightOff.setVisibility(View.VISIBLE); - } - } - } - }; -} diff --git a/app/src/main/java/com/example/user/myapp/MeasurementActivity.java b/app/src/main/java/com/example/user/myapp/MeasurementActivity.java deleted file mode 100644 index bf1cf54..0000000 --- a/app/src/main/java/com/example/user/myapp/MeasurementActivity.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.user.myapp; - -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; - -public class MeasurementActivity extends AppCompatActivity { - - Boolean myBoolean = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_measurement); - } - - - public boolean toggle () { - return myBoolean ? false: true; - } -} diff --git a/app/src/main/java/com/example/user/myapp/MyIntentService.java b/app/src/main/java/com/example/user/myapp/MyIntentService.java deleted file mode 100644 index b0ca2ad..0000000 --- a/app/src/main/java/com/example/user/myapp/MyIntentService.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.example.user.myapp; - -import android.app.IntentService; -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.content.LocalBroadcastManager; - -import com.ghgande.j2mod.modbus.facade.ModbusTCPMaster; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.util.BitVector; - -import java.util.ArrayList; -import java.util.List; - -/** - * An {@link IntentService} subclass for handling asynchronous task requests in - * a service on a separate handler thread. - *

- * TODO: Customize class - update intent actions, extra parameters and static - * helper methods. - */ -public class MyIntentService extends IntentService { - - // read action - private static final String ACTION_READ_COIL = "read.coil"; - private static final String ACTION_READ_INPUT_REGISTER = "read.input.register"; - private static final String ACTION_READ_DISCRETE_INPUT = "read.discrete.input"; - - // write action - private static final String ACTION_WRITE_COIL = "write.coil"; - - private static final String ACTION_CHECK_COIL = "check.coil"; - - private ModbusTCPMaster master; - - // TODO: Rename parameters - private static final String EXTRA_IP_ADDRESS = "extra.ip.address"; - private static final String EXTRA_PORT = "extra.ip.port"; - private static final String EXTRA_REF = "extra.ref"; - private static final String EXTRA_COUNT = "extra.count"; - private static final String EXTRA_INTENT_NAME = "extra.intent.name"; - - private static final String EXTRA_BIT_TO_SET = "extra.bit"; - //turns out modbus on siemens logo is crap and isnt responding for at least 50ms - private static final Integer CAP_WAIT_TIME = 100; - //this is not a type, idiot. - - public MyIntentService() { - super("MyIntentService"); - } - - private void sendBooleanListToActivity(List booleanList, String intentName, String bundleName) { - Intent intent = new Intent(intentName); - Bundle bundle = new Bundle(); - bundle.putBooleanArray(bundleName, toPrimitiveArray(booleanList)); - intent.putExtras(bundle); - sendLocationBroadcast(intent); - } - - private void sendIntegerListToActivity (ArrayList integerList, String intentName) { - Intent intent = new Intent(intentName); - Bundle bundle = new Bundle(); - - bundle.putIntegerArrayList("irValues", integerList); - intent.putExtras(bundle); - sendLocationBroadcast(intent); - } - - private void sendLocationBroadcast(Intent intent) { - LocalBroadcastManager.getInstance(this).sendBroadcast(intent); - } - - public void readDiscreteInputAction (String ipAddress, int port, int ref, int count, String intentReceiveName) { - try { - master = new ModbusTCPMaster(ipAddress, port); - master.connect(); - - BitVector bv = master.readInputDiscretes(ref, count); - List listBooleanBit = new ArrayList<>(); - for (int i = 0; i < count; i++) { - System.out.println(i+" discret input "+bv.getBit(i)); - listBooleanBit.add(bv.getBit(i)); - } - sendBooleanListToActivity(listBooleanBit, intentReceiveName, "discreteInputValues"); - Thread.sleep(CAP_WAIT_TIME); - master.disconnect(); - } catch (Exception e) { - System.out.println("Exception in reading discrete input " + e); - } - } - - public void readCoilAction (String ipAddress, int port, int ref, int count, String intentReceiveName) { - try { - master = new ModbusTCPMaster(ipAddress, port); - master.connect(); - - BitVector bv = master.readCoils(ref,count); - List listBooleanBit = new ArrayList<>(); - for (int i = 0; i < count; i++) { - System.out.println(i+" coil "+bv.getBit(i)); - listBooleanBit.add(bv.getBit(i)); - } - sendBooleanListToActivity(listBooleanBit, intentReceiveName, "coilValues"); - Thread.sleep(CAP_WAIT_TIME); - master.disconnect(); - } catch (Exception e) { - System.out.println("Exception in reading coil " + e); - } - } - - public void readInputRegisterAction (String ipAddress, int port, int ref, int count, String intentReceiveName) { - try { - master = new ModbusTCPMaster(ipAddress, port); - master.connect(); - - InputRegister [] inputRegisters = master.readInputRegisters(ref, count); - ArrayList listIntegerInputRegister = new ArrayList<>(); - for (InputRegister ir : inputRegisters) { - listIntegerInputRegister.add(ir.getValue()); - System.out.println(ir.getValue()+" input register "+Math.random()); - } - sendIntegerListToActivity (listIntegerInputRegister, intentReceiveName); - Thread.sleep(CAP_WAIT_TIME); - master.disconnect(); - } catch (Exception e) { - System.out.println("Exception in reading input register " + e); - } - } - - public void writeCoilAction (String ipAddress, int port, int ref, boolean value, String intentReceiveName, boolean withCheck) { - try { - master = new ModbusTCPMaster(ipAddress, port); - master.connect(); - // writing the value - boolean writtenValue = master.writeCoil(ref, value); - if (withCheck) { - System.out.println("I wrote " + writtenValue + " to coil " + ref); - Thread.sleep(CAP_WAIT_TIME); - - GlobalState state = (GlobalState) getApplicationContext(); - - int coilToRead = state.getMapMappingValue().get(ref); - System.out.println("Checking the value of coil "+coilToRead); - boolean currentValue = master.readCoils(coilToRead, 1).getBit(0); - sendNewBitValueToActivity(currentValue, intentReceiveName); - } else { - System.out.println("I switched the manual mode to " + writtenValue); - sendNewBitValueToActivity(writtenValue, intentReceiveName); - } - Thread.sleep(CAP_WAIT_TIME); - master.disconnect(); - } catch (Exception e) { - System.out.println("Exception in writing coil " + e); - } - } - - private void sendNewBitValueToActivity (boolean newValue, String intentReceive) { - Intent intent = new Intent(intentReceive); - intent.putExtra("coil", newValue); - sendLocationBroadcast(intent); - } - - @Override - protected void onHandleIntent(Intent intent) { - if (intent != null) { - final String action = intent.getAction(); - final String ipAddress = intent.getStringExtra(EXTRA_IP_ADDRESS); - final int port = intent.getIntExtra(EXTRA_PORT, 502); - final int ref = intent.getIntExtra(EXTRA_REF, 8192); - final int count = intent.getIntExtra(EXTRA_COUNT, 8); - final String intentName = intent.getStringExtra(EXTRA_INTENT_NAME); - - // for write - final Boolean value = intent.getBooleanExtra(EXTRA_BIT_TO_SET, false); - - final Boolean withCheck = intent.getBooleanExtra("extra.is.basic.coil", false); - - switch(action) { - case ACTION_READ_DISCRETE_INPUT: - readDiscreteInputAction (ipAddress, port, ref, count, intentName); - break; - case ACTION_READ_COIL : - readCoilAction(ipAddress, port, ref, count, intentName); - break; - case ACTION_READ_INPUT_REGISTER : - readInputRegisterAction (ipAddress, port,ref, count, intentName); - break; - case ACTION_WRITE_COIL: - writeCoilAction(ipAddress, port, ref, value, intentName, withCheck); - break; - } - } - } - - - private boolean[] toPrimitiveArray(final List booleanList) { - final boolean[] primitives = new boolean[booleanList.size()]; - int index = 0; - for (Boolean object : booleanList) { - primitives[index++] = object; - } - return primitives; - } -} diff --git a/app/src/main/java/com/example/user/myapp/OnSwipeTouchListener.java b/app/src/main/java/com/example/user/myapp/OnSwipeTouchListener.java deleted file mode 100644 index 88cd3c5..0000000 --- a/app/src/main/java/com/example/user/myapp/OnSwipeTouchListener.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.example.user.myapp; - -import android.content.Context; -import android.view.GestureDetector; -import android.view.GestureDetector.SimpleOnGestureListener; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; - -public class OnSwipeTouchListener implements OnTouchListener { - - - private final GestureDetector gestureDetector; - private Context context; - - /* (non-Javadoc) - * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent) - */ - public boolean onTouch(final View view, final MotionEvent motionEvent) { - return gestureDetector.onTouchEvent(motionEvent); - } - - /** - * Gets the gesture detector. - * - * @return the gesture detector - */ - public GestureDetector getGestureDetector() { - return gestureDetector; - } - - /** - * Instantiates a new on swipe touch listener. - * - * @param context the context - */ - public OnSwipeTouchListener(Context context) { - super(); - this.context = context; - gestureDetector = new GestureDetector(context, new GestureListener()); - } - - private final class GestureListener extends SimpleOnGestureListener { - - private static final int SWIPE_THRESHOLD = 100; - private static final int SWIPE_VELOCITY_THRESHOLD = 100; - - /* (non-Javadoc) - * @see android.view.GestureDetector.SimpleOnGestureListener#onDown(android.view.MotionEvent) - */ - @Override - public boolean onDown(MotionEvent e) { - return true; - } - - /* (non-Javadoc) - * @see android.view.GestureDetector.SimpleOnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float) - */ - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - boolean result = false; - try { - float diffY = e2.getRawY() - e1.getRawY(); - float diffX = e2.getRawX() - e1.getRawX(); - if ((Math.abs(diffX) - Math.abs(diffY)) > SWIPE_THRESHOLD) { - if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { - if (diffX > 0) { - onSwipeRight(); - } else { - onSwipeLeft(); - } - } - } else { - if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { - if (diffY > 0) { - onSwipeBottom(); - } else { - onSwipeTop(); - } - } - } - } catch (Exception e) { - - } - return result; - } - } - - /** - * On swipe right. - */ - public void onSwipeRight() { - } - - /** - * On swipe left. - */ - public void onSwipeLeft() { - } - - /** - * On swipe top. - */ - public void onSwipeTop() { - } - - /** - * On swipe bottom. - */ - public void onSwipeBottom() { - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/Modbus.java b/app/src/main/java/com/ghgande/j2mod/modbus/Modbus.java deleted file mode 100644 index 3ab0c71..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/Modbus.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus; - -/** - * Interface defining all constants related to the - * Modbus protocol. - * - * @author Dieter Wimberger - * @version 1.2rc1 (09/11/2004) - */ -public interface Modbus { - - /** - * Defines the class 1 function code - * for read coils. - */ - int READ_COILS = 1; - - /** - * Defines a class 1 function code - * for read input discretes. - */ - int READ_INPUT_DISCRETES = 2; - - /** - * Defines a class 1 function code - * for read holding registers - */ - int READ_HOLDING_REGISTERS = 3; - - /** - * Defines the class 0 function code - * for read multiple registers. The - * proper name is "Read Holding Registers". - */ - int READ_MULTIPLE_REGISTERS = 3; - - /** - * Defines a class 1 function code - * for read input registers. - */ - int READ_INPUT_REGISTERS = 4; - - /** - * Defines a class 1 function code - * for write coil. - */ - int WRITE_COIL = 5; - - /** - * Defines a class 1 function code - * for write single register. - */ - int WRITE_SINGLE_REGISTER = 6; - - /** - * read exception status - * - * Serial devices only. - */ - int READ_EXCEPTION_STATUS = 7; - - /** - * get serial diagnostics - * - * Serial devices only. - */ - int READ_SERIAL_DIAGNOSTICS = 8; - - /** - * get comm event counter - * - * Serial devices only. - */ - int READ_COMM_EVENT_COUNTER = 11; - - /** - * get comm event log - * - * Serial devices only. - */ - int READ_COMM_EVENT_LOG = 12; - - /** - * Defines a standard function code - * for write multiple coils. - */ - int WRITE_MULTIPLE_COILS = 15; - - /** - * Defines the class 0 function code - * for write multiple registers. - */ - int WRITE_MULTIPLE_REGISTERS = 16; - - /** - * Defines a standard function code - * for read slave ID. - */ - int REPORT_SLAVE_ID = 17; - - /** - * read file record - */ - int READ_FILE_RECORD = 20; - - /** - * write file record - */ - int WRITE_FILE_RECORD = 21; - - /** - * mask write register - * - * Update a single register using its current value and an AND - * and OR mask. - */ - int MASK_WRITE_REGISTER = 22; - - /** - * read / write multiple registers - * - * Write some number of registers, then read some number of - * potentially other registers back. - */ - int READ_WRITE_MULTIPLE = 23; - - /** - * read FIFO queue - * - * Read from a FIFO queue. - */ - int READ_FIFO_QUEUE = 24; - - /** - * Defines the function code for reading - * encapsulated data, such as vendor information. - */ - int READ_MEI = 43; - int READ_MEI_VENDOR_INFO = 14; - - /** - * Defines the byte representation of the coil state on. - */ - int COIL_ON = (byte)255; - - /** - * Defines the byte representation of the coil state pos. - */ - int COIL_OFF = 0; - - /** - * Defines the word representation of the coil state on. - */ - byte[] COIL_ON_BYTES = {(byte)COIL_ON, (byte)COIL_OFF}; - - /** - * Defines the word representation of the coil state pos. - */ - byte[] COIL_OFF_BYTES = {(byte)COIL_OFF, (byte)COIL_OFF}; - - /** - * Defines the maximum number of bits in multiple read/write - * of input discretes or coils (2000). - */ - int MAX_BITS = 2000; - - /** - * Defines the Modbus slave exception offset that is added to the - * function code, to flag an exception. - */ - int EXCEPTION_OFFSET = 128; //the last valid function code is 127 - - /** - * Defines the Modbus slave exception type illegal function. - * This exception code is returned if the slave: - *

    - *
  • does not implement the function code or
  • - *
  • is not in a state that allows it to process the function
  • - *
- */ - int ILLEGAL_FUNCTION_EXCEPTION = 1; - - /** - * Defines the Modbus slave exception type illegal data address. - * This exception code is returned if the reference: - *
    - *
  • does not exist on the slave or
  • - *
  • the combination of reference and length exceeds the bounds - * of the existing registers. - *
  • - *
- */ - int ILLEGAL_ADDRESS_EXCEPTION = 2; - - /** - * Defines the Modbus slave exception type illegal data value. - * This exception code indicates a fault in the structure of the data values - * of a complex request, such as an incorrect implied length.
- * This code does not indicate a problem with application specific validity - * of the value. - */ - int ILLEGAL_VALUE_EXCEPTION = 3; - - /** - * Defines the Modbus slave exception type slave device failure. - * This exception code indicates a fault in the slave device itself. - */ - int SLAVE_DEVICE_FAILURE = 4; - - /** - * Defines the Modbus slave exception type slave busy. This - * exception indicates the the slave is unable to perform the operation - * because it is performing an operation which cannot be interrupted. - */ - int SLAVE_BUSY_EXCEPTION = 6; - - /** - * Defines the Modbus slave exception type negative acknowledgment. - * This exception code indicates the slave cannot perform the requested - * action. - */ - int NEGATIVE_ACKNOWLEDGEMENT = 7; - - /** - * Defines the Modbus slave exception type Gateway target failed to - * respond. This exception code indicates that a Modbus gateway - * failed to receive a response from the specified target. - */ - int GATEWAY_TARGET_NO_RESPONSE = 11; - - /** - * Defines the default port number of Modbus - * (=502). - */ - int DEFAULT_PORT = 502; - - /** - * Defines the maximum message length in bytes - * (=256). - */ - int MAX_MESSAGE_LENGTH = 256; - - /** - * Defines the default transaction identifier (=0). - */ - int DEFAULT_TRANSACTION_ID = 0; - - /** - * Defines the default protocol identifier (=0). - */ - int DEFAULT_PROTOCOL_ID = 0; - - /** - * Defines the default unit identifier (=0). - */ - int DEFAULT_UNIT_ID = 0; - - /** - * Defines the default setting for validity checking - * in transactions (=true). - */ - boolean DEFAULT_VALIDITYCHECK = true; - - /** - * Defines the default setting for I/O operation timeouts - * in milliseconds (=3000). - */ - int DEFAULT_TIMEOUT = 3000; - - /** - * Defines the sleep period between transaction retries - * in milliseconds (=200). - */ - int RETRY_SLEEP_TIME = 500; - - /** - * Defines the default reconnecting setting for - * transactions (=false). - */ - boolean DEFAULT_RECONNECTING = false; - - /** - * Defines the default amount of retires for opening - * a connection (=3). - */ - int DEFAULT_RETRIES = 5; - - /** - * Defines the default number of msec to delay before transmission
- * Inter-message delays are managed by the SerialTransaction object automatically based on the - * baud rate. Setting this value to anything other than zero will bypass that process and force - * a specific inter-message delay - * (=0). - */ - int DEFAULT_TRANSMIT_DELAY = 0; - - /** - * Defines the default number of msec to delay before transmission if not overridden by DEFAULT_TRANSMIT_DELAY - * (=2). - */ - int MINIMUM_TRANSMIT_DELAY = 2; - - /** - * The number of characters delay that must be maintained between adjacent requests on - * the same serial port (within the same transaction) - */ - double INTER_MESSAGE_GAP = 4; - - /** - * Defines the maximum value of the transaction identifier. - * - *

Note: The standard requires that the server copy whatever - * value the client provides. However, the transaction ID is being - * limited to signed 16-bit integers to prevent problems with servers - * that might incorrectly assume the value is a signed value. - */ - int MAX_TRANSACTION_ID = Short.MAX_VALUE; - - /** - * Defines the serial encoding "ASCII". - */ - String SERIAL_ENCODING_ASCII = "ascii"; - - /** - * Defines the serial encoding "RTU". - */ - String SERIAL_ENCODING_RTU = "rtu"; - - /** - * Defines the default serial encoding (ASCII). - */ - String DEFAULT_SERIAL_ENCODING = SERIAL_ENCODING_ASCII; - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/ModbusException.java b/app/src/main/java/com/ghgande/j2mod/modbus/ModbusException.java deleted file mode 100644 index 35ea753..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/ModbusException.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus; - -/** - * Superclass of all specialised exceptions in this package. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Constructs a new ModbusException instance. - */ - public ModbusException() { - super(); - } - - /** - * Constructs a new ModbusException instance with the given - * message. - *

- * - * @param message the message describing this ModbusException. - */ - public ModbusException(String message) { - super(message); - } - - /** - * Constructs a new ModbusException instance with the given - * message. - *

- * - * @param message the message describing this ModbusException. - * @param values optional values of the exception - */ - public ModbusException(String message, Object... values) { - super(String.format(message, values)); - } - - /** - * Constructs a new ModbusException instance with the given - * message and underlying cause. - *

- * - * @param message the message describing this ModbusException. - * @param cause the cause (which is saved for later retrieval by the {@code getCause()} method). - * (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) - */ - public ModbusException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/ModbusIOException.java b/app/src/main/java/com/ghgande/j2mod/modbus/ModbusIOException.java deleted file mode 100644 index b0f4ba6..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/ModbusIOException.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus; - -/** - * Class that implements a ModbusIOException. Instances of this - * exception are thrown when errors in the I/O occur. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusIOException extends ModbusException { - - /** - * - */ - private static final long serialVersionUID = 1L; - private boolean eof = false; - - /** - * Constructs a new ModbusIOException instance. - */ - public ModbusIOException() { - } - - /** - * Constructs a new ModbusIOException instance with the given - * message. - *

- * - * @param message the message describing this ModbusIOException. - */ - public ModbusIOException(String message) { - super(message); - } - - /** - * Constructs a new ModbusIOException instance with the given - * message. - *

- * - * @param message the message describing this ModbusIOException. - * @param values optional values of the exception - */ - public ModbusIOException(String message, Object... values) { - super(message, values); - } - - /** - * Constructs a new ModbusIOException instance. - * - * @param b true if caused by end of stream, false otherwise. - */ - public ModbusIOException(boolean b) { - eof = b; - } - - /** - * Constructs a new ModbusIOException instance with the given - * message. - *

- * - * @param message the message describing this ModbusIOException. - * @param b true if caused by end of stream, false otherwise. - */ - public ModbusIOException(String message, boolean b) { - super(message); - eof = b; - } - - /** - * Constructs a new ModbusIOException instance with the given - * message and underlying cause. - *

- * - * @param message the message describing this ModbusIOException. - * @param cause the cause (which is saved for later retrieval by the {@code getCause()} method). - * (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) - */ - public ModbusIOException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Tests if this ModbusIOException is caused by an end of the - * stream. - *

- * - * @return true if stream ended, false otherwise. - */ - public boolean isEOF() { - return eof; - } - - /** - * Sets the flag that determines whether this ModbusIOException was - * caused by an end of the stream. - *

- * - * @param b true if stream ended, false otherwise. - */ - public void setEOF(boolean b) { - eof = b; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/ModbusSlaveException.java b/app/src/main/java/com/ghgande/j2mod/modbus/ModbusSlaveException.java deleted file mode 100644 index a57e7b0..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/ModbusSlaveException.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus; - -/** - * Class that implements a ModbusSlaveException. Instances of this - * exception are thrown when the slave returns a Modbus exception. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusSlaveException extends ModbusException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Instance type attribute - */ - private int type = -1; - - /** - *

- * Constructs a new ModbusSlaveException instance with the given - * type. - * - *

- * Types are defined according to the protocol specification in - * net.wimpi.modbus.Modbus. - * - * @param type the type of exception that occurred. - */ - public ModbusSlaveException(int type) { - super(); - - this.type = type; - } - - /** - * Get the exception type message associated with the given exception - * number. - * - * @param type Numerical value of the Modbus exception. - * - * @return a String indicating the type of slave exception. - */ - public static String getMessage(int type) { - switch (type) { - case 1: - return "Illegal Function"; - case 2: - return "Illegal Data Address"; - case 3: - return "Illegal Data Value"; - case 4: - return "Slave Device Failure"; - case 5: - return "Acknowledge"; - case 6: - return "Slave Device Busy"; - case 8: - return "Memory Parity Error"; - case 10: - return "Gateway Path Unavailable"; - case 11: - return "Gateway Target Device Failed to Respond"; - } - return "Error Code = " + type; - } - - /** - *

- * Returns the type of this ModbusSlaveException.
- * Types are defined according to the protocol specification in - * net.wimpi.modbus.Modbus. - * - * @return the type of this ModbusSlaveException. - */ - public int getType() { - return type; - } - - /** - *

- * Tests if this ModbusSlaveException is of a given type. - * - *

- * Types are defined according to the protocol specification in - * net.wimpi.modbus.Modbus. - * - * @param TYPE the type to test this ModbusSlaveException type - * against. - * - * @return true if this ModbusSlaveException is of the given type, - * false otherwise. - */ - public boolean isType(int TYPE) { - return (TYPE == type); - } - - /** - * Get the exception type message associated with this exception. - * - * @return a String indicating the type of slave exception. - */ - public String getMessage() { - return getMessage(type); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/facade/AbstractModbusMaster.java b/app/src/main/java/com/ghgande/j2mod/modbus/facade/AbstractModbusMaster.java deleted file mode 100644 index fd3b797..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/facade/AbstractModbusMaster.java +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.facade; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusException; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import com.ghgande.j2mod.modbus.io.ModbusTransaction; -import com.ghgande.j2mod.modbus.msg.*; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.procimg.Register; -import com.ghgande.j2mod.modbus.util.BitVector; - -/** - * Modbus/TCP Master facade - common methods for all the facade implementations - * The emphasis is in making callas to Modbus devices as simple as possible - * for the most common Function Codes. - * This class makes sure that no NPE is raised and that the methods are thread-safe. - * - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -abstract public class AbstractModbusMaster { - - private static final int DEFAULT_UNIT_ID = 1; - - protected ModbusTransaction transaction; - private ReadCoilsRequest readCoilsRequest; - private ReadInputDiscretesRequest readInputDiscretesRequest; - private WriteCoilRequest writeCoilRequest; - private WriteMultipleCoilsRequest writeMultipleCoilsRequest; - private ReadInputRegistersRequest readInputRegistersRequest; - private ReadMultipleRegistersRequest readMultipleRegistersRequest; - private WriteSingleRegisterRequest writeSingleRegisterRequest; - private WriteMultipleRegistersRequest writeMultipleRegistersRequest; - protected int timeout = Modbus.DEFAULT_TIMEOUT; - - /** - * Sets the transaction to use - * - * @param transaction Transaction to use - */ - protected synchronized void setTransaction(ModbusTransaction transaction) { - this.transaction = transaction; - } - - /** - * Connects this ModbusTCPMaster with the slave. - * - * @throws Exception if the connection cannot be established. - */ - abstract public void connect() throws Exception; - - /** - * Disconnects this ModbusTCPMaster from the slave. - */ - abstract public void disconnect(); - - /** - * Reads a given number of coil states from the slave. - * - * Note that the number of bits in the bit vector will be - * forced to the number originally requested. - * - * @param unitId the slave unit id. - * @param ref the offset of the coil to start reading from. - * @param count the number of coil states to be read. - * - * @return a BitVector instance holding the - * received coil states. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized BitVector readCoils(int unitId, int ref, int count) throws ModbusException { - checkTransaction(); - if (readCoilsRequest == null) { - readCoilsRequest = new ReadCoilsRequest(); - } - readCoilsRequest.setUnitID(unitId); - readCoilsRequest.setReference(ref); - readCoilsRequest.setBitCount(count); - transaction.setRequest(readCoilsRequest); - transaction.execute(); - BitVector bv = ((ReadCoilsResponse) getAndCheckResponse()).getCoils(); - bv.forceSize(count); - return bv; - } - - /** - * Writes a coil state to the slave. - * - * @param unitId the slave unit id. - * @param ref the offset of the coil to be written. - * @param state the coil state to be written. - * - * @return the state of the coil as returned from the slave. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized boolean writeCoil(int unitId, int ref, boolean state) throws ModbusException { - checkTransaction(); - if (writeCoilRequest == null) { - writeCoilRequest = new WriteCoilRequest(); - } - writeCoilRequest.setUnitID(unitId); - writeCoilRequest.setReference(ref); - writeCoilRequest.setCoil(state); - transaction.setRequest(writeCoilRequest); - transaction.execute(); - return ((WriteCoilResponse) getAndCheckResponse()).getCoil(); - } - - /** - * Writes a given number of coil states to the slave. - * - * Note that the number of coils to be written is given - * implicitly, through {@link BitVector#size()}. - * - * @param unitId the slave unit id. - * @param ref the offset of the coil to start writing to. - * @param coils a BitVector which holds the coil states to be written. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized void writeMultipleCoils(int unitId, int ref, BitVector coils) throws ModbusException { - checkTransaction(); - if (writeMultipleCoilsRequest == null) { - writeMultipleCoilsRequest = new WriteMultipleCoilsRequest(); - } - writeMultipleCoilsRequest.setUnitID(unitId); - writeMultipleCoilsRequest.setReference(ref); - writeMultipleCoilsRequest.setCoils(coils); - transaction.setRequest(writeMultipleCoilsRequest); - transaction.execute(); - } - - /** - * Reads a given number of input discrete states from the slave. - * - * Note that the number of bits in the bit vector will be - * forced to the number originally requested. - * - * @param unitId the slave unit id. - * @param ref the offset of the input discrete to start reading from. - * @param count the number of input discrete states to be read. - * - * @return a BitVector instance holding the received input discrete - * states. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized BitVector readInputDiscretes(int unitId, int ref, int count) throws ModbusException { - checkTransaction(); - if (readInputDiscretesRequest == null) { - readInputDiscretesRequest = new ReadInputDiscretesRequest(); - } - readInputDiscretesRequest.setUnitID(unitId); - readInputDiscretesRequest.setReference(ref); - readInputDiscretesRequest.setBitCount(count); - transaction.setRequest(readInputDiscretesRequest); - transaction.execute(); - BitVector bv = ((ReadInputDiscretesResponse)getAndCheckResponse()).getDiscretes(); - bv.forceSize(count); - return bv; - } - - /** - * Reads a given number of input registers from the slave. - * - * Note that the number of input registers returned (i.e. array length) - * will be according to the number received in the slave response. - * - * @param unitId the slave unit id. - * @param ref the offset of the input register to start reading from. - * @param count the number of input registers to be read. - * - * @return a InputRegister[] with the received input registers. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized InputRegister[] readInputRegisters(int unitId, int ref, int count) throws ModbusException { - checkTransaction(); - if (readInputRegistersRequest == null) { - readInputRegistersRequest = new ReadInputRegistersRequest(); - } - readInputRegistersRequest.setUnitID(unitId); - readInputRegistersRequest.setReference(ref); - readInputRegistersRequest.setWordCount(count); - transaction.setRequest(readInputRegistersRequest); - transaction.execute(); - return ((ReadInputRegistersResponse) getAndCheckResponse()).getRegisters(); - } - - /** - * Reads a given number of registers from the slave. - * - * Note that the number of registers returned (i.e. array length) - * will be according to the number received in the slave response. - * - * @param unitId the slave unit id. - * @param ref the offset of the register to start reading from. - * @param count the number of registers to be read. - * - * @return a Register[] holding the received registers. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized Register[] readMultipleRegisters(int unitId, int ref, int count) throws ModbusException { - checkTransaction(); - if (readMultipleRegistersRequest == null) { - readMultipleRegistersRequest = new ReadMultipleRegistersRequest(); - } - readMultipleRegistersRequest.setUnitID(unitId); - readMultipleRegistersRequest.setReference(ref); - readMultipleRegistersRequest.setWordCount(count); - transaction.setRequest(readMultipleRegistersRequest); - transaction.execute(); - return ((ReadMultipleRegistersResponse) getAndCheckResponse()).getRegisters(); - } - - /** - * Writes a single register to the slave. - * - * @param unitId the slave unit id. - * @param ref the offset of the register to be written. - * @param register a Register holding the value of the register - * to be written. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized void writeSingleRegister(int unitId, int ref, Register register) throws ModbusException { - checkTransaction(); - if (writeSingleRegisterRequest == null) { - writeSingleRegisterRequest = new WriteSingleRegisterRequest(); - } - writeSingleRegisterRequest.setUnitID(unitId); - writeSingleRegisterRequest.setReference(ref); - writeSingleRegisterRequest.setRegister(register); - transaction.setRequest(writeSingleRegisterRequest); - transaction.execute(); - } - - /** - * Writes a number of registers to the slave. - * - * @param unitId the slave unit id. - * @param ref the offset of the register to start writing to. - * @param registers a Register[] holding the values of - * the registers to be written. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized void writeMultipleRegisters(int unitId, int ref, Register[] registers) throws ModbusException { - checkTransaction(); - if (writeMultipleRegistersRequest == null) { - writeMultipleRegistersRequest = new WriteMultipleRegistersRequest(); - } - writeMultipleRegistersRequest.setUnitID(unitId); - writeMultipleRegistersRequest.setReference(ref); - writeMultipleRegistersRequest.setRegisters(registers); - transaction.setRequest(writeMultipleRegistersRequest); - transaction.execute(); - } - - /** - * Reads a given number of coil states from the slave. - * - * Note that the number of bits in the bit vector will be - * forced to the number originally requested. - * - * @param ref the offset of the coil to start reading from. - * @param count the number of coil states to be read. - * - * @return a BitVector instance holding the - * received coil states. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized BitVector readCoils(int ref, int count) throws ModbusException { - return readCoils(DEFAULT_UNIT_ID, ref, count); - } - - /** - * Writes a coil state to the slave. - * - * @param ref the offset of the coil to be written. - * @param state the coil state to be written. - * - * @return the state of the coil as returned from the slave. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized boolean writeCoil(int ref, boolean state) throws ModbusException { - return writeCoil(DEFAULT_UNIT_ID, ref, state); - } - - /** - * Writes a given number of coil states to the slave. - * - * Note that the number of coils to be written is given - * implicitly, through {@link BitVector#size()}. - * - * @param ref the offset of the coil to start writing to. - * @param coils a BitVector which holds the coil states to be written. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized void writeMultipleCoils(int ref, BitVector coils) throws ModbusException { - writeMultipleCoils(DEFAULT_UNIT_ID, ref, coils); - } - - /** - * Reads a given number of input discrete states from the slave. - * - * Note that the number of bits in the bit vector will be - * forced to the number originally requested. - * - * @param ref the offset of the input discrete to start reading from. - * @param count the number of input discrete states to be read. - * - * @return a BitVector instance holding the received input discrete - * states. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized BitVector readInputDiscretes(int ref, int count) throws ModbusException { - return readInputDiscretes(DEFAULT_UNIT_ID, ref, count); - } - - /** - * Reads a given number of input registers from the slave. - * - * Note that the number of input registers returned (i.e. array length) - * will be according to the number received in the slave response. - * - * @param ref the offset of the input register to start reading from. - * @param count the number of input registers to be read. - * - * @return a InputRegister[] with the received input registers. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized InputRegister[] readInputRegisters(int ref, int count) throws ModbusException { - return readInputRegisters(DEFAULT_UNIT_ID, ref, count); - } - - /** - * Reads a given number of registers from the slave. - * - * Note that the number of registers returned (i.e. array length) - * will be according to the number received in the slave response. - * - * @param ref the offset of the register to start reading from. - * @param count the number of registers to be read. - * - * @return a Register[] holding the received registers. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized Register[] readMultipleRegisters(int ref, int count) throws ModbusException { - return readMultipleRegisters(DEFAULT_UNIT_ID, ref, count); - } - - /** - * Writes a single register to the slave. - * - * @param ref the offset of the register to be written. - * @param register a Register holding the value of the register - * to be written. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized void writeSingleRegister(int ref, Register register) throws ModbusException { - writeSingleRegister(DEFAULT_UNIT_ID, ref, register); - } - - /** - * Writes a number of registers to the slave. - * - * @param ref the offset of the register to start writing to. - * @param registers a Register[] holding the values of - * the registers to be written. - * - * @throws ModbusException if an I/O error, a slave exception or - * a transaction error occurs. - */ - public synchronized void writeMultipleRegisters(int ref, Register[] registers) throws ModbusException { - writeMultipleRegisters(DEFAULT_UNIT_ID, ref, registers); - } - - /** - * Reads the response from the transaction - * If there is no response, then it throws an error - * - * @return Modbus response - * - * @throws ModbusException If response is null - */ - private ModbusResponse getAndCheckResponse() throws ModbusException { - ModbusResponse res = transaction.getResponse(); - if (res == null) { - throw new ModbusException("No response"); - } - return res; - } - - /** - * Checks to make sure there is a transaction to use - * - * @throws ModbusException If transaction is null - */ - private void checkTransaction() throws ModbusException { - if (transaction == null) { - throw new ModbusException("No transaction created, probably not connected"); - } - } - - /** - * Returns the receive timeout in milliseconds - * - * @return Timeout in milliseconds - */ - public int getTimeout() { - return timeout; - } - - /** - * Sets the receive timeout - * - * @param timeout Timeout in milliseconds - */ - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - /** - * Set the amount of retries for opening - * the connection for executing the transaction. - * - * @param retries the amount of retries as int. - */ - synchronized public void setRetries(int retries) { - if (transaction != null) { - transaction.setRetries(retries); - } - } - - /** - * Sets the flag that controls whether the - * validity of a transaction will be checked. - * - * @param b true if checking validity, false otherwise. - */ - synchronized public void setCheckingValidity(boolean b) { - if (transaction != null) { - transaction.setCheckingValidity(b); - } - } - - /** - * Returns the transport being used by the - * - * @return ModbusTransport - */ - public abstract AbstractModbusTransport getTransport(); - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/facade/ModbusTCPMaster.java b/app/src/main/java/com/ghgande/j2mod/modbus/facade/ModbusTCPMaster.java deleted file mode 100644 index b39ac86..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/facade/ModbusTCPMaster.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.facade; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import com.ghgande.j2mod.modbus.io.ModbusTCPTransaction; -import com.ghgande.j2mod.modbus.net.TCPMasterConnection; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Modbus/TCP Master facade. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusTCPMaster extends AbstractModbusMaster { - - private TCPMasterConnection connection; - private boolean reconnecting = false; - private boolean useRtuOverTcp = false; - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - */ - public ModbusTCPMaster(String addr) { - this(addr, Modbus.DEFAULT_PORT, Modbus.DEFAULT_TIMEOUT, false, false); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - */ - public ModbusTCPMaster(String addr, boolean useRtuOverTcp) { - this(addr, Modbus.DEFAULT_PORT, Modbus.DEFAULT_TIMEOUT, false, useRtuOverTcp); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param port the port the slave is listening to. - */ - public ModbusTCPMaster(String addr, int port) { - this(addr, port, Modbus.DEFAULT_TIMEOUT, false, false); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param port the port the slave is listening to. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - */ - public ModbusTCPMaster(String addr, int port, boolean useRtuOverTcp) { - this(addr, port, Modbus.DEFAULT_TIMEOUT, false, useRtuOverTcp); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param port the port the slave is listening to. - * @param timeout Socket timeout in milliseconds - * @param reconnect True if the socket should reconnect if it detects a connection failure - */ - public ModbusTCPMaster(String addr, int port, int timeout, boolean reconnect) { - this(addr, port, timeout, reconnect, false); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param port the port the slave is listening to. - * @param timeout Socket timeout in milliseconds - * @param reconnect True if the socket should reconnect if it detcts a connection failure - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - */ - public ModbusTCPMaster(String addr, int port, int timeout, boolean reconnect, boolean useRtuOverTcp) { - super(); - this.useRtuOverTcp = useRtuOverTcp; - try { - InetAddress slaveAddress = InetAddress.getByName(addr); - connection = new TCPMasterConnection(slaveAddress); - connection.setPort(port); - connection.setTimeout(timeout); - this.timeout = timeout; - setReconnecting(reconnect); - } - catch (UnknownHostException e) { - throw new RuntimeException("Failed to contruct ModbusTCPMaster instance.", e); - } - } - - /** - * Connects this ModbusTCPMaster with the slave. - * - * @throws Exception if the connection cannot be established. - */ - public synchronized void connect() throws Exception { - if (connection != null && !connection.isConnected()) { - connection.connect(useRtuOverTcp); - transaction = connection.getModbusTransport().createTransaction(); - ((ModbusTCPTransaction)transaction).setReconnecting(reconnecting); - setTransaction(transaction); - } - } - - /** - * Disconnects this ModbusTCPMaster from the slave. - */ - public synchronized void disconnect() { - if (connection != null && connection.isConnected()) { - connection.close(); - transaction = null; - setTransaction(null); - } - } - - /** - * Tests if a constant connection is maintained or if a new - * connection is established for every transaction. - * - * @return true if a new connection should be established for each - * transaction, false otherwise. - */ - public boolean isReconnecting() { - return reconnecting; - } - - /** - * Sets the flag that specifies whether to maintain a - * constant connection or reconnect for every transaction. - * - * @param b true if a new connection should be established for each - * transaction, false otherwise. - */ - public synchronized void setReconnecting(boolean b) { - reconnecting = b; - if (transaction != null) { - ((ModbusTCPTransaction)transaction).setReconnecting(b); - } - } - - @Override - public void setTimeout(int timeout) { - super.setTimeout(timeout); - if (connection != null) { - connection.setTimeout(timeout); - } - } - - @Override - public AbstractModbusTransport getTransport() { - return connection == null ? null : connection.getModbusTransport(); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/facade/ModbusUDPMaster.java b/app/src/main/java/com/ghgande/j2mod/modbus/facade/ModbusUDPMaster.java deleted file mode 100644 index 793783e..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/facade/ModbusUDPMaster.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.facade; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import com.ghgande.j2mod.modbus.net.UDPMasterConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Modbus/UDP Master facade. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusUDPMaster extends AbstractModbusMaster { - - private static final Logger logger = LoggerFactory.getLogger(ModbusUDPMaster.class); - - private UDPMasterConnection connection; - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - */ - public ModbusUDPMaster(String addr) { - this(addr, Modbus.DEFAULT_PORT); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param port the port the slave is listening to. - */ - public ModbusUDPMaster(String addr, int port) { - this(addr, port, Modbus.DEFAULT_TIMEOUT); - } - - /** - * Constructs a new master facade instance for communication - * with a given slave. - * - * @param addr an internet address as resolvable IP name or IP number, - * specifying the slave to communicate with. - * @param port the port the slave is listening to. - * @param timeout Socket timeout in milliseconds - */ - public ModbusUDPMaster(String addr, int port, int timeout) { - super(); - try { - InetAddress slaveAddress = InetAddress.getByName(addr); - connection = new UDPMasterConnection(slaveAddress); - connection.setPort(port); - connection.setTimeout(timeout); - } - catch (UnknownHostException e) { - throw new RuntimeException("Failed to construct ModbusUDPMaster instance.", e); - } - } - - /** - * Connects this ModbusTCPMaster with the slave. - * - * @throws Exception if the connection cannot be established. - */ - public synchronized void connect() throws Exception { - if (connection != null && !connection.isConnected()) { - connection.connect(); - transaction = connection.getModbusTransport().createTransaction(); - setTransaction(transaction); - } - } - - /** - * Disconnects this ModbusTCPMaster from the slave. - */ - public synchronized void disconnect() { - if (connection != null && connection.isConnected()) { - connection.close(); - transaction = null; - setTransaction(null); - } - } - - @Override - public void setTimeout(int timeout) { - super.setTimeout(timeout); - if (connection != null) { - connection.setTimeout(timeout); - } - } - - @Override - public AbstractModbusTransport getTransport() { - return connection == null ? null : connection.getModbusTransport(); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/AbstractModbusTransport.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/AbstractModbusTransport.java deleted file mode 100644 index 2bc9408..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/AbstractModbusTransport.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.IOException; - -/** - * Interface defining the I/O mechanisms for - * ModbusMessage instances. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class AbstractModbusTransport { - - protected int timeout = Modbus.DEFAULT_TIMEOUT; - - /** - * Set the socket timeout - * - * @param time Timeout in milliseconds - */ - public void setTimeout(int time) { - timeout = time; - } - - /** - * Closes the raw input and output streams of - * this ModbusTransport. - *

- * - * @throws IOException if a stream - * cannot be closed properly. - */ - public abstract void close() throws IOException; - - /** - * Creates a Modbus transaction for the underlying transport. - * - * @return the new transaction - */ - public abstract ModbusTransaction createTransaction(); - - /** - * Writes a ModbusMessage to the - * output stream of this ModbusTransport. - *

- * - * @param msg a ModbusMessage. - * - * @throws ModbusIOException data cannot be - * written properly to the raw output stream of - * this ModbusTransport. - */ - public abstract void writeRequest(ModbusRequest msg) throws ModbusIOException; - - /** - * Writes a ModbusResponseMessage to the - * output stream of this ModbusTransport. - *

- * - * @param msg a ModbusMessage. - * - * @throws ModbusIOException data cannot be - * written properly to the raw output stream of - * this ModbusTransport. - */ - public abstract void writeResponse(ModbusResponse msg) throws ModbusIOException; - - /** - * Reads a ModbusRequest from the - * input stream of this ModbusTransport. - *

- * - * @param listener Listener the request was received by - * - * @return req the ModbusRequest read from the underlying stream. - * - * @throws ModbusIOException data cannot be - * read properly from the raw input stream of - * this ModbusTransport. - */ - public abstract ModbusRequest readRequest(AbstractModbusListener listener) throws ModbusIOException; - - /** - * Reads a ModbusResponse from the - * input stream of this ModbusTransport. - *

- * - * @return res the ModbusResponse read from the underlying stream. - * - * @throws ModbusIOException data cannot be - * read properly from the raw input stream of - * this ModbusTransport. - */ - public abstract ModbusResponse readResponse() throws ModbusIOException; - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/AbstractSerialTransportListener.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/AbstractSerialTransportListener.java deleted file mode 100644 index cf1b44d..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/AbstractSerialTransportListener.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.msg.ModbusMessage; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; -import com.ghgande.j2mod.modbus.net.AbstractSerialConnection; - -/** - * Any class that wants to listen for the begining and ending of read/writes - * to the Serial channel need to implement this interface - * - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -abstract public class AbstractSerialTransportListener { - - /** - * Will be called whenever a message is about to be written - * - * @param port Port being used - * @param msg Message to be written - */ - public void beforeMessageWrite(AbstractSerialConnection port, ModbusMessage msg) { - } - - /** - * Will be called whenever a message has been written - * - * @param port Port being used - * @param msg Message written - */ - public void afterMessageWrite(AbstractSerialConnection port, ModbusMessage msg) { - } - - /** - * Called before a request is read - * - * @param port Port to read - */ - public void beforeRequestRead(AbstractSerialConnection port) { - } - - /** - * Called whenever a request has been received - * - * @param port Port to read - * @param req Request received - */ - public void afterRequestRead(AbstractSerialConnection port, ModbusRequest req) { - } - - /** - * Called before a response is read - * - * @param port Port to read - */ - public void beforeResponseRead(AbstractSerialConnection port) { - } - - /** - * Called whenever a response has been received - * - * @param port Port to read - * @param res Response received - */ - public void afterResponseRead(AbstractSerialConnection port, ModbusResponse res) { - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/BytesInputStream.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/BytesInputStream.java deleted file mode 100644 index 9332178..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/BytesInputStream.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; - -/** - * Class implementing a byte array input stream with - * a DataInput interface. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class BytesInputStream - extends FastByteArrayInputStream implements DataInput { - - DataInputStream dataInputStream; - - /** - * Constructs a new BytesInputStream instance, - * with an empty buffer of a given size. - * - * @param size the size of the input buffer. - */ - public BytesInputStream(int size) { - super(new byte[size]); - dataInputStream = new DataInputStream(this); - } - - /** - * Constructs a new BytesInputStream instance, - * that will read from the given data. - * - * @param data a byte array containing data to be read. - */ - public BytesInputStream(byte[] data) { - super(data); - dataInputStream = new DataInputStream(this); - } - - /** - * Resets this BytesInputStream using the given - * byte[] as new input buffer. - * - * @param data a byte array with data to be read. - */ - public void reset(byte[] data) { - pos = 0; - mark = 0; - buf = data; - count = data.length; - } - - /** - * Resets this BytesInputStream using the given - * byte[] as new input buffer and a given length. - * - * @param data a byte array with data to be read. - * @param length the length of the buffer to be considered. - */ - public void reset(byte[] data, int length) { - pos = 0; - mark = 0; - count = length; - buf = data; - } - - /** - * Resets this BytesInputStream assigning the input buffer - * a new length. - * - * @param length the length of the buffer to be considered. - */ - public void reset(int length) { - pos = 0; - count = length; - } - - /** - * Skips the given number of bytes or all bytes till the end - * of the assigned input buffer length. - * - * @param n the number of bytes to be skipped as int. - * - * @return the number of bytes skipped. - */ - public int skip(int n) { - mark(pos); - pos += n; - return n; - } - - /** - * Returns the reference to the input buffer. - * - * @return the reference to the byte[] input buffer. - */ - public synchronized byte[] getBuffer() { - byte[] dest = new byte[buf.length]; - System.arraycopy(buf, 0, dest, 0, dest.length); - return dest; - } - - public int getBufferLength() { - return buf.length; - } - - public void readFully(byte b[]) throws IOException { - dataInputStream.readFully(b); - } - - public void readFully(byte b[], int off, int len) throws IOException { - dataInputStream.readFully(b, off, len); - } - - public int skipBytes(int n) throws IOException { - return dataInputStream.skipBytes(n); - } - - public boolean readBoolean() throws IOException { - return dataInputStream.readBoolean(); - } - - public byte readByte() throws IOException { - return dataInputStream.readByte(); - } - - public int readUnsignedByte() throws IOException { - return dataInputStream.readUnsignedByte(); - } - - public short readShort() throws IOException { - return dataInputStream.readShort(); - } - - public int readUnsignedShort() throws IOException { - return dataInputStream.readUnsignedShort(); - } - - public char readChar() throws IOException { - return dataInputStream.readChar(); - } - - public int readInt() throws IOException { - return dataInputStream.readInt(); - } - - public long readLong() throws IOException { - return dataInputStream.readLong(); - } - - public float readFloat() throws IOException { - return dataInputStream.readFloat(); - } - - public double readDouble() throws IOException { - return dataInputStream.readDouble(); - } - - public String readLine() throws IOException { - throw new IOException("Not supported"); - } - - public String readUTF() throws IOException { - return dataInputStream.readUTF(); - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/BytesOutputStream.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/BytesOutputStream.java deleted file mode 100644 index 976f1ba..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/BytesOutputStream.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Class implementing a byte array output stream with - * a DataInput interface. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class BytesOutputStream extends FastByteArrayOutputStream implements DataOutput { - - private DataOutputStream dataOutputStream; - - /** - * Constructs a new BytesOutputStream instance with - * a new output buffer of the given size. - * - * @param size the size of the output buffer as int. - */ - public BytesOutputStream(int size) { - super(size); - dataOutputStream = new DataOutputStream(this); - } - - /** - * Constructs a new BytesOutputStream instance with - * a given output buffer. - * - * @param buffer the output buffer as byte[]. - */ - public BytesOutputStream(byte[] buffer) { - buf = buffer; - count = 0; - dataOutputStream = new DataOutputStream(this); - } - - /** - * Returns the reference to the output buffer. - * - * @return the reference to the byte[] output buffer. - */ - public synchronized byte[] getBuffer() { - byte[] dest = new byte[buf.length]; - System.arraycopy(buf, 0, dest, 0, dest.length); - return dest; - } - - public void reset() { - count = 0; - } - - public void writeBoolean(boolean v) throws IOException { - dataOutputStream.writeBoolean(v); - } - - public void writeByte(int v) throws IOException { - dataOutputStream.writeByte(v); - } - - public void writeShort(int v) throws IOException { - dataOutputStream.writeShort(v); - } - - public void writeChar(int v) throws IOException { - dataOutputStream.writeChar(v); - } - - public void writeInt(int v) throws IOException { - dataOutputStream.writeInt(v); - } - - public void writeLong(long v) throws IOException { - dataOutputStream.writeLong(v); - } - - public void writeFloat(float v) throws IOException { - dataOutputStream.writeFloat(v); - } - - public void writeDouble(double v) throws IOException { - dataOutputStream.writeDouble(v); - } - - public void writeBytes(String s) throws IOException { - int len = s.length(); - for (int i = 0; i < len; i++) { - this.write((byte)s.charAt(i)); - } - } - - public void writeChars(String s) throws IOException { - dataOutputStream.writeChars(s); - } - - public void writeUTF(String str) throws IOException { - dataOutputStream.writeUTF(str); - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/FastByteArrayInputStream.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/FastByteArrayInputStream.java deleted file mode 100644 index 65b1636..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/FastByteArrayInputStream.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; - -/** - * This class is a replacement for ByteArrayInputStream that does not - * synchronize every byte read. - * - * @author Mark Hayes - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class FastByteArrayInputStream extends InputStream { - - private static final Logger logger = LoggerFactory.getLogger(FastByteArrayInputStream.class); - - /** - * Number of bytes in the input buffer. - */ - protected int count; - - /** - * Actual position pointer into the input buffer. - */ - int pos; - - /** - * Marked position pointer into the input buffer. - */ - int mark; - /** - * Input buffer byte[]. - */ - byte[] buf; - - /** - * Creates an input stream. - * - * @param buffer the data to read. - */ - FastByteArrayInputStream(byte[] buffer) { - buf = buffer; - count = buffer.length; - pos = 0; - mark = 0; - } - - // --- begin ByteArrayInputStream compatible methods --- - - public int read() throws IOException { - logger.debug("read()"); - logger.debug("count={} pos={}", count, pos); - return (pos < count) ? (buf[pos++] & 0xff) : (-1); - } - - public int read(byte[] toBuf) throws IOException { - logger.debug("read(byte[])"); - return read(toBuf, 0, toBuf.length); - } - - public int read(byte[] toBuf, int offset, int length) throws IOException { - logger.debug("read(byte[],int,int)"); - int avail = count - pos; - if (avail <= 0) { - return -1; - } - if (length > avail) { - length = avail; - } - for (int i = 0; i < length; i++) { - toBuf[offset++] = buf[pos++]; - } - return length; - } - - public long skip(long count) { - int myCount = (int)count; - if (myCount + pos > this.count) { - myCount = this.count - pos; - } - pos += myCount; - return myCount; - } - - public int available() { - return count - pos; - } - - public int getCount() { - return count; - } - - public void mark(int readlimit) { - logger.debug("mark()"); - mark = pos; - logger.debug("mark={} pos={}", mark, pos); - } - - public void reset() { - logger.debug("reset()"); - pos = mark; - logger.debug("mark={} pos={}", mark, pos); - } - - public boolean markSupported() { - return true; - } - - // --- end ByteArrayInputStream compatible methods --- - - public byte[] toByteArray() { - byte[] toBuf = new byte[count]; - System.arraycopy(buf, 0, toBuf, 0, count); - return toBuf; - } - - /** - * Returns the underlying data being read. - * - * @return the underlying data. - */ - public synchronized byte[] getBufferBytes() { - byte[] dest = new byte[count]; - System.arraycopy(buf, 0, dest, 0, dest.length); - return dest; - } - - /** - * Returns the offset at which data is being read from the buffer. - * - * @return the offset at which data is being read. - */ - public int getBufferOffset() { - return pos; - } - - /** - * Returns the end of the buffer being read. - * - * @return the end of the buffer. - */ - public int getBufferLength() { - return count; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/FastByteArrayOutputStream.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/FastByteArrayOutputStream.java deleted file mode 100644 index be3a0c5..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/FastByteArrayOutputStream.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -/** - * This class is a replacement implementation for ByteArrayOutputStream - * that does not synchronize every - * byte written. - * - * @author Mark Hayes - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class FastByteArrayOutputStream extends OutputStream { - - private static final Logger logger = LoggerFactory.getLogger(FastByteArrayOutputStream.class); - - /** - * Defines the default oputput buffer size (100 bytes). - */ - private static final int DEFAULT_INIT_SIZE = 100; - /** - * Defines the default increment of the output buffer size - * (100 bytes). - */ - private static final int DEFAULT_BUMP_SIZE = 100; - - /** - * Number of bytes in the output buffer. - */ - protected int count; - - /** - * Increment of the output buffer size on overflow. - */ - private int bumpLen; - - /** - * Output buffer byte[]. - */ - byte[] buf; - - /** - * Creates an output stream with default sizes. - */ - FastByteArrayOutputStream() { - buf = new byte[DEFAULT_INIT_SIZE]; - bumpLen = DEFAULT_BUMP_SIZE; - } - - /** - * Creates an output stream with a default bump size and a given initial - * size. - * - * @param initialSize the initial size of the buffer. - */ - FastByteArrayOutputStream(int initialSize) { - buf = new byte[initialSize]; - bumpLen = DEFAULT_BUMP_SIZE; - } - - /** - * Creates an output stream with a given bump size and initial size. - * - * @param initialSize the initial size of the buffer. - * @param bumpSize the amount to increment the buffer. - */ - public FastByteArrayOutputStream(int initialSize, int bumpSize) { - buf = new byte[initialSize]; - bumpLen = bumpSize; - } - - // --- begin ByteArrayOutputStream compatible methods --- - - /** - * Returns the number of bytes written to this - * FastByteArrayOutputStream. - * - * @return the number of bytes written as int. - */ - public int size() { - return count; - } - - /** - * Resets this FastByteArrayOutputStream. - */ - public void reset() { - count = 0; - } - - public void write(int b) throws IOException { - if (count + 1 > buf.length) { - bump(1); - } - buf[count++] = (byte)b; - } - - public void write(byte[] fromBuf) throws IOException { - int needed = count + fromBuf.length - buf.length; - if (needed > 0) { - bump(needed); - } - for (byte aFromBuf : fromBuf) { - buf[count++] = aFromBuf; - } - } - - public void write(byte[] fromBuf, int offset, int length) throws IOException { - - int needed = count + length - buf.length; - if (needed > 0) { - bump(needed); - } - int fromLen = offset + length; - - for (int i = offset; i < fromLen; i++) { - buf[count++] = fromBuf[i]; - } - } - - /** - * Writes the content of this FastByteArrayOutputStream - * to the given output stream. - * - * @param out the output stream to be written to. - * - * @throws IOException if an I/O error occurs. - */ - public synchronized void writeTo(OutputStream out) throws IOException { - out.write(buf, 0, count); - } - - public String toString() { - try { - return new String(buf, 0, count, "US-ASCII"); - } - catch (Exception e) { - logger.debug("Problem converting bytes to string - {}", e.getMessage()); - } - return ""; - } - - /** - * Returns the content of this FastByteArrayOutputStream - * as String. - * - * @param encoding the encoding to be used for conversion. - * - * @return a newly allocated String. - * - * @throws UnsupportedEncodingException if the given encoding is not supported. - */ - public String toString(String encoding) throws UnsupportedEncodingException { - return new String(buf, 0, count, encoding); - } - - /** - * Returns the written bytes in a newly allocated byte[] - * of length getSize(). - * - * @return a newly allocated byte[] with the content of the - * output buffer. - */ - public byte[] toByteArray() { - byte[] toBuf = new byte[count]; - System.arraycopy(buf, 0, toBuf, 0, count); - //for (int i = 0; i < count; i++) { - // toBuf[i] = buf[i]; - //} - return toBuf; - } - - // --- end ByteArrayOutputStream compatible methods --- - - /** - * Copy the buffered data to the given array. - * - * @param toBuf the buffer to hold a copy of the data. - * @param offset the offset at which to start copying. - */ - public void toByteArray(byte[] toBuf, int offset) { - int toLen = (toBuf.length > count) ? count : toBuf.length; - System.arraycopy(buf, offset, toBuf, offset, toLen - offset); - } - - /** - * Returns the buffer owned by this object. - * - * @return the buffer. - */ - public synchronized byte[] getBufferBytes() { - byte[] dest = new byte[count]; - System.arraycopy(buf, 0, dest, 0, dest.length); - return dest; - } - - /** - * Returns the offset of the internal buffer. - * - * @return always zero currently. - */ - public int getBufferOffset() { - return 0; - } - - /** - * Returns the length used in the internal buffer, that is, the offset at - * which data will be written next. - * - * @return the buffer length. - */ - public int getBufferLength() { - return count; - } - - /** - * Ensure that at least the given number of bytes are available in the - * internal buffer. - * - * @param sizeNeeded the number of bytes desired. - */ - public void makeSpace(int sizeNeeded) { - int needed = count + sizeNeeded - buf.length; - if (needed > 0) { - bump(needed); - } - } - - /** - * Skip the given number of bytes in the buffer. - * - * @param sizeAdded number of bytes to skip. - */ - public void addSize(int sizeAdded) { - count += sizeAdded; - } - - private void bump(int needed) { - - byte[] toBuf = new byte[buf.length + needed + bumpLen]; - - System.arraycopy(buf, 0, toBuf, 0, count); - buf = toBuf; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusRTUTCPTransport.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusRTUTCPTransport.java deleted file mode 100644 index fd4349d..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusRTUTCPTransport.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; - -import java.net.Socket; - -/** - * Class that implements the ModbusRTU over tCP transport flavor. - * - * @author axuan - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusRTUTCPTransport extends ModbusTCPTransport { - - /** - * Default constructor - */ - public ModbusRTUTCPTransport() { - // RTU over TCP is headless by default - setHeadless(); - } - - /** - * Constructs a new ModbusTransport instance, for a given - * Socket. - *

- * - * @param socket the Socket used for message transport. - */ - public ModbusRTUTCPTransport(Socket socket) { - super(socket); - // RTU over TCP is headless by default - setHeadless(); - } - - @Override - public void writeResponse(ModbusResponse msg) throws ModbusIOException { - writeMessage(msg, true); - } - - @Override - public void writeRequest(ModbusRequest msg) throws ModbusIOException { - writeMessage(msg, true); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTCPTransaction.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTCPTransaction.java deleted file mode 100644 index f112c04..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTCPTransaction.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusException; -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.ModbusSlaveException; -import com.ghgande.j2mod.modbus.msg.ExceptionResponse; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.net.TCPMasterConnection; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class implementing the ModbusTransaction interface. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusTCPTransaction extends ModbusTransaction { - - private static final Logger logger = LoggerFactory.getLogger(ModbusTCPTransaction.class); - - // instance attributes and associations - private TCPMasterConnection connection; - protected boolean reconnecting = Modbus.DEFAULT_RECONNECTING; - - /** - * Constructs a new ModbusTCPTransaction instance. - */ - public ModbusTCPTransaction() { - } - - /** - * Constructs a new ModbusTCPTransaction instance with a given - * ModbusRequest to be send when the transaction is executed. - *

- * - * @param request a ModbusRequest instance. - */ - public ModbusTCPTransaction(ModbusRequest request) { - setRequest(request); - } - - /** - * Constructs a new ModbusTCPTransaction instance with a given - * TCPMasterConnection to be used for transactions. - *

- * - * @param con a TCPMasterConnection instance. - */ - public ModbusTCPTransaction(TCPMasterConnection con) { - setConnection(con); - transport = con.getModbusTransport(); - } - - /** - * Sets the connection on which this ModbusTransaction should be - * executed. - *

- * An implementation should be able to handle open and closed connections. - *
- *

- * - * @param con a TCPMasterConnection. - */ - public synchronized void setConnection(TCPMasterConnection con) { - connection = con; - transport = con.getModbusTransport(); - } - - /** - * Tests if the connection will be opened and closed for each - * execution. - *

- * - * @return true if reconnecting, false otherwise. - */ - public boolean isReconnecting() { - return reconnecting; - } - - /** - * Sets the flag that controls whether a connection is opened and closed - * for each execution or not. - *

- * - * @param b true if reconnecting, false otherwise. - */ - public void setReconnecting(boolean b) { - reconnecting = b; - } - - @Override - public synchronized void execute() throws ModbusException { - - if (request == null || connection == null) { - throw new ModbusException("Invalid request or connection"); - } - - // Try sending the message up to retries time. Note that the message - // is read immediately after being written, with no flushing of buffers. - int retryCounter = 0; - int retryLimit = (retries > 0 ? retries : Modbus.DEFAULT_RETRIES); - boolean keepTrying = true; - - // While we haven't exhausted all the retry attempts - while (keepTrying) { - - // Automatically connect if we aren't already connected - if (!connection.isConnected()) { - try { - logger.debug("Connecting to: {}:{}", connection.getAddress().toString(), connection.getPort()); - connection.connect(); - transport = connection.getModbusTransport(); - } - catch (Exception ex) { - throw new ModbusIOException("Connection failed for %s:%d", connection.getAddress().toString(), connection.getPort(), ex.getMessage()); - } - } - - // Make sure the timeout is set - transport.setTimeout(connection.getTimeout()); - - try { - - // Write the message to the endpoint - logger.debug("Writing request: {} (try: {}) request transaction ID = {} to {}:{}", request.getHexMessage(), retryCounter, request.getTransactionID(), connection.getAddress().toString(), connection.getPort()); - transport.writeRequest(request); - - // Read the response - response = transport.readResponse(); - logger.debug("Read response: {} (try: {}) response transaction ID = {} from {}:{}", response.getHexMessage(), retryCounter, response.getTransactionID(), connection.getAddress().toString(), connection.getPort()); - keepTrying = false; - - // The slave may have returned an exception -- check for that. - if (response instanceof ExceptionResponse) { - throw new ModbusSlaveException(((ExceptionResponse)response).getExceptionCode()); - } - - // We need to keep retrying if; - // a) the response is empty OR - // b) we have been told to check the validity and the request/response transaction IDs don't match AND - // c) we haven't exceeded the maximum retry count - if (responseIsInValid()) { - retryCounter++; - if (retryCounter >= retryLimit) { - throw new ModbusIOException("Executing transaction failed (tried %d times)", retryLimit); - } - keepTrying = true; - long sleepTime = getRandomSleepTime(retryCounter); - if (response == null) { - logger.debug("Failed to get any response (try: {}) - retrying after {} milliseconds", retryCounter, sleepTime); - } - else { - logger.debug("Failed to get a valid response, transaction IDs do not match (try: {}) - retrying after {} milliseconds", retryCounter, sleepTime); - } - ModbusUtil.sleep(sleepTime); - } - } - catch (ModbusIOException ex) { - - // Up the retry counter and check if we are exhausted - retryCounter++; - if (retryCounter >= retryLimit) { - throw new ModbusIOException("Executing transaction %s failed (tried %d times) %s", request.getHexMessage(), retryLimit, ex.getMessage()); - } - else { - long sleepTime = getRandomSleepTime(retryCounter); - logger.debug("Failed transaction Request: {} (try: {}) - retrying after {} milliseconds", request.getHexMessage(), retryCounter, sleepTime); - ModbusUtil.sleep(sleepTime); - } - - // If this has happened, then we should close and re-open the connection before re-trying - logger.debug("Failed request {} (try: {}) request transaction ID = {} - {} closing and re-opening connection {}:{}", request.getHexMessage(), retryCounter, request.getTransactionID(), ex.getMessage(), connection.getAddress().toString(), connection.getPort()); - connection.close(); - } - - // Increment the transaction ID if we are still trying - if (keepTrying) { - incrementTransactionID(); - } - } - - // Close the connection if it isn't supposed to stick around. - if (isReconnecting()) { - connection.close(); - } - incrementTransactionID(); - } - - /** - * Returns true if the response is not valid - * This can be if the response is null or the transaction ID of the request - * doesn't match the reponse - * - * @return True if invalid - */ - private boolean responseIsInValid() { - if (response == null) { - return true; - } - else if (!response.isHeadless() && validityCheck) { - return request.getTransactionID() != response.getTransactionID(); - } - else { - return false; - } - } - - /** - * incrementTransactionID -- Increment the transaction ID for the next - * transaction. Note that the caller must get the new transaction ID with - * getTransactionID(). This is only done validity checking is enabled so - * that dumb slaves don't cause problems. The original request will have its - * transaction ID incremented as well so that sending the same transaction - * again won't cause problems. - */ - private synchronized void incrementTransactionID() { - if (isCheckingValidity()) { - if (transactionID >= Modbus.MAX_TRANSACTION_ID) { - transactionID = Modbus.DEFAULT_TRANSACTION_ID; - } - else { - transactionID++; - } - } - request.setTransactionID(getTransactionID()); - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTCPTransport.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTCPTransport.java deleted file mode 100644 index 0b6c56e..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTCPTransport.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.msg.ModbusMessage; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.net.TCPMasterConnection; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.net.Socket; -import java.net.SocketException; -import java.net.SocketTimeoutException; - -/** - * Class that implements the Modbus transport flavor. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusTCPTransport extends AbstractModbusTransport { - - private static final Logger logger = LoggerFactory.getLogger(ModbusTCPTransport.class); - - // instance attributes - private DataInputStream dataInputStream; // input stream - private DataOutputStream dataOutputStream; // output stream - private final BytesInputStream byteInputStream = new BytesInputStream(Modbus.MAX_MESSAGE_LENGTH + 6); - private final BytesOutputStream byteOutputStream = new BytesOutputStream(Modbus.MAX_MESSAGE_LENGTH + 6); // write frames - protected Socket socket = null; - protected TCPMasterConnection master = null; - private boolean headless = false; // Some TCP implementations are. - - /** - * Default constructor - */ - public ModbusTCPTransport() { - } - - /** - * Constructs a new ModbusTransport instance, for a given - * Socket. - *

- * - * @param socket the Socket used for message transport. - */ - public ModbusTCPTransport(Socket socket) { - try { - setSocket(socket); - socket.setSoTimeout(timeout); - } - catch (IOException ex) { - logger.debug("ModbusTCPTransport::Socket invalid"); - - throw new IllegalStateException("Socket invalid", ex); - } - } - - /** - * Sets the Socket used for message transport and prepares the - * streams used for the actual I/O. - * - * @param socket the Socket used for message transport. - * - * @throws IOException if an I/O related error occurs. - */ - public void setSocket(Socket socket) throws IOException { - if (this.socket != null) { - this.socket.close(); - this.socket = null; - } - this.socket = socket; - setTimeout(timeout); - prepareStreams(socket); - } - - /** - * Set the transport to be headless - */ - public void setHeadless() { - headless = true; - } - - /** - * Set the transport to be headless - * - * @param headless True if headless - */ - public void setHeadless(boolean headless) { - this.headless = headless; - } - - /** - * Sets the master connection for the transport to use - * - * @param master Master - */ - public void setMaster(TCPMasterConnection master) { - this.master = master; - } - - @Override - public void setTimeout(int time) { - super.setTimeout(time); - if (socket != null) { - try { - socket.setSoTimeout(time); - } - catch (SocketException e) { - logger.warn("Socket exception occurred while setting timeout to " + time, e); - } - } - } - - @Override - public void close() throws IOException { - dataInputStream.close(); - dataOutputStream.close(); - socket.close(); - } - - @Override - public ModbusTransaction createTransaction() { - if (master == null) { - master = new TCPMasterConnection(socket.getInetAddress()); - master.setPort(socket.getPort()); - master.setModbusTransport(this); - } - return new ModbusTCPTransaction(master); - } - - @Override - public void writeResponse(ModbusResponse msg) throws ModbusIOException { - writeMessage(msg, false); - } - - @Override - public void writeRequest(ModbusRequest msg) throws ModbusIOException { - writeMessage(msg, false); - } - - @Override - public ModbusRequest readRequest(AbstractModbusListener listener) throws ModbusIOException { - ModbusRequest req; - try { - byteInputStream.reset(); - - synchronized (byteInputStream) { - byte[] buffer = byteInputStream.getBuffer(); - - if (!headless) { - dataInputStream.readFully(buffer, 0, 6); - - // The transaction ID must be treated as an unsigned short in - // order for validation to work correctly. - - int transaction = ModbusUtil.registerToShort(buffer, 0) & 0x0000FFFF; - int protocol = ModbusUtil.registerToShort(buffer, 2); - int count = ModbusUtil.registerToShort(buffer, 4); - - dataInputStream.readFully(buffer, 6, count); - - if (logger.isDebugEnabled()) { - logger.debug("Read: {}", ModbusUtil.toHex(buffer, 0, count + 6)); - } - - byteInputStream.reset(buffer, (6 + count)); - byteInputStream.skip(6); - - int unit = byteInputStream.readByte(); - int functionCode = byteInputStream.readUnsignedByte(); - - byteInputStream.reset(); - req = ModbusRequest.createModbusRequest(functionCode); - req.setUnitID(unit); - req.setHeadless(false); - - req.setTransactionID(transaction); - req.setProtocolID(protocol); - req.setDataLength(count); - - req.readFrom(byteInputStream); - } - else { - - // This is a headless request. - - int unit = dataInputStream.readByte(); - int function = dataInputStream.readByte(); - - req = ModbusRequest.createModbusRequest(function); - req.setUnitID(unit); - req.setHeadless(true); - req.readData(dataInputStream); - - // Discard the CRC. This is a TCP/IP connection, which has - // proper error correction and recovery. - - dataInputStream.readShort(); - if (logger.isDebugEnabled()) { - logger.debug("Read: {}", req.getHexMessage()); - } - } - } - return req; - } - catch (EOFException eoex) { - throw new ModbusIOException("End of File", true); - } - catch (SocketTimeoutException x) { - throw new ModbusIOException("Timeout reading request", x); - } - catch (SocketException sockex) { - throw new ModbusIOException("Socket Exception", sockex); - } - catch (IOException ex) { - throw new ModbusIOException("I/O exception - failed to read", ex); - } - } - - @Override - public ModbusResponse readResponse() throws ModbusIOException { - try { - ModbusResponse response; - - synchronized (byteInputStream) { - // use same buffer - byte[] buffer = byteInputStream.getBuffer(); - logger.debug("Reading response..."); - if (!headless) { - // All Modbus TCP transactions start with 6 bytes. Get them. - dataInputStream.readFully(buffer, 0, 6); - - /* - * The transaction ID is the first word (offset 0) in the - * data that was just read. It will be echoed back to the - * requester. - * - * The protocol ID is the second word (offset 2) in the - * data. It should always be 0, but I don't check. - * - * The length of the payload is the third word (offset 4) in - * the data that was just read. That's what I need in order - * to read the rest of the response. - */ - int transaction = ModbusUtil.registerToShort(buffer, 0) & 0x0000FFFF; - int protocol = ModbusUtil.registerToShort(buffer, 2); - int count = ModbusUtil.registerToShort(buffer, 4); - - dataInputStream.readFully(buffer, 6, count); - byteInputStream.reset(buffer, (6 + count)); - byteInputStream.reset(); - byteInputStream.skip(7); - int function = byteInputStream.readUnsignedByte(); - response = ModbusResponse.createModbusResponse(function); - - // Rewind the input buffer, then read the data into the - // response. - byteInputStream.reset(); - response.readFrom(byteInputStream); - - response.setTransactionID(transaction); - response.setProtocolID(protocol); - } - else { - // This is a headless response. It has the same format as a - // RTU over Serial response. - int unit = dataInputStream.readByte(); - int function = dataInputStream.readByte(); - - response = ModbusResponse.createModbusResponse(function); - response.setUnitID(unit); - response.setHeadless(); - response.readData(dataInputStream); - - // Now discard the CRC. Which hopefully wasn't needed - // because this is a TCP transport. - dataInputStream.readShort(); - } - } - if (logger.isDebugEnabled()) { - logger.debug("Successfully read: {}", response.getHexMessage()); - } - return response; - } - catch (EOFException ex1) { - throw new ModbusIOException("Premature end of stream (Message truncated) - %s", ex1.getMessage()); - } - catch (SocketTimeoutException ex2) { - throw new ModbusIOException("Socket timeout reading response - %s", ex2.getMessage()); - } - catch (Exception ex3) { - throw new ModbusIOException("General exception - failed to read - %s", ex3.getMessage()); - } - } - - /** - * Prepares the input and output streams of this ModbusTCPTransport - * instance based on the given socket. - * - * @param socket the socket used for communications. - * - * @throws IOException if an I/O related error occurs. - */ - private void prepareStreams(Socket socket) throws IOException { - - // Close any open streams if I'm being called because a new socket was - // set to handle this transport. - try { - if (dataInputStream != null) { - dataInputStream.close(); - } - if (dataOutputStream != null) { - dataOutputStream.close(); - } - } - catch (IOException x) { - // Do nothing. - } - - dataInputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream())); - dataOutputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); - } - - /** - * Writes a ModbusMessage to the - * output stream of this ModbusTransport. - *

- * - * @param msg a ModbusMessage. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * - * @throws ModbusIOException data cannot be - * written properly to the raw output stream of - * this ModbusTransport. - */ - void writeMessage(ModbusMessage msg, boolean useRtuOverTcp) throws ModbusIOException { - try { - if (logger.isDebugEnabled()) { - logger.debug("Sending: {}", msg.getHexMessage()); - } - byte message[] = msg.getMessage(); - - byteOutputStream.reset(); - if (!headless) { - byteOutputStream.writeShort(msg.getTransactionID()); - byteOutputStream.writeShort(msg.getProtocolID()); - byteOutputStream.writeShort((message != null ? message.length : 0) + 2); - } - byteOutputStream.writeByte(msg.getUnitID()); - byteOutputStream.writeByte(msg.getFunctionCode()); - if (message != null && message.length > 0) { - byteOutputStream.write(message); - } - - // Add CRC for RTU over TCP - if (useRtuOverTcp) { - int len = byteOutputStream.size(); - int[] crc = ModbusUtil.calculateCRC(byteOutputStream.getBuffer(), 0, len); - byteOutputStream.writeByte(crc[0]); - byteOutputStream.writeByte(crc[1]); - } - - dataOutputStream.write(byteOutputStream.toByteArray()); - dataOutputStream.flush(); - if (logger.isDebugEnabled()) { - logger.debug("Successfully sent: {}", ModbusUtil.toHex(byteOutputStream.toByteArray())); - } - // write more sophisticated exception handling - } - catch (SocketException ex1) { - if (master != null && !master.isConnected()) { - try { - master.connect(useRtuOverTcp); - } - catch (Exception e) { - // Do nothing. - } - } - throw new ModbusIOException("I/O socket exception - failed to write - %s", ex1.getMessage()); - } - catch (Exception ex2) { - throw new ModbusIOException("General exception - failed to write - %s", ex2.getMessage()); - } - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTransaction.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTransaction.java deleted file mode 100644 index 12c7a93..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusTransaction.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusException; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; - -import java.util.Random; - -/** - * Interface defining a ModbusTransaction. - *

- * A transaction is defined by the sequence of - * sending a request message and receiving a - * related response message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class ModbusTransaction { - - protected AbstractModbusTransport transport; - protected ModbusRequest request; - protected ModbusResponse response; - boolean validityCheck = Modbus.DEFAULT_VALIDITYCHECK; - int retries = Modbus.DEFAULT_RETRIES; - private Random random = new Random(System.nanoTime()); - static int transactionID = Modbus.DEFAULT_TRANSACTION_ID; - - /** - * Returns the ModbusRequest instance - * associated with this ModbusTransaction. - *

- * - * @return the associated ModbusRequest instance. - */ - public ModbusRequest getRequest() { - return request; - } - - /** - * Sets the ModbusRequest for this - * ModbusTransaction.

- * The related ModbusResponse is acquired - * from the passed in ModbusRequest instance.
- *

- * - * @param req a ModbusRequest. - */ - public void setRequest(ModbusRequest req) { - request = req; - if (req != null) { - request.setTransactionID(getTransactionID()); - } - } - - /** - * Returns the ModbusResponse instance - * associated with this ModbusTransaction. - *

- * - * @return the associated ModbusRequest instance. - */ - public ModbusResponse getResponse() { - return response; - } - - /** - * Returns the amount of retries for opening - * the connection for executing the transaction. - *

- * - * @return the amount of retries as int. - */ - int getRetries() { - return retries; - } - - /** - * Set the amount of retries for opening - * the connection for executing the transaction. - *

- * - * @param retries the amount of retries as int. - */ - public void setRetries(int retries) { - this.retries = retries; - } - - /** - * Tests whether the validity of a transaction - * will be checked. - *

- * - * @return true if checking validity, false otherwise. - */ - public boolean isCheckingValidity() { - return validityCheck; - } - - /** - * Sets the flag that controls whether the - * validity of a transaction will be checked. - *

- * - * @param b true if checking validity, false otherwise. - */ - public void setCheckingValidity(boolean b) { - validityCheck = b; - } - - /** - * getTransactionID -- get the next transaction ID to use. - * @return next transaction ID to use - */ - synchronized public int getTransactionID() { - /* - * Ensure that the transaction ID is in the valid range between - * 0 and MAX_TRANSACTION_ID (65534). If not, the value will be forced - * to 0. - */ - if (transactionID < Modbus.DEFAULT_TRANSACTION_ID && isCheckingValidity()) { - transactionID = Modbus.DEFAULT_TRANSACTION_ID; - } - if (transactionID >= Modbus.MAX_TRANSACTION_ID) { - transactionID = Modbus.DEFAULT_TRANSACTION_ID; - } - return transactionID; - } - - /** - * A useful method for getting a random sleep time based on an increment of the retry count and retry sleep time - * - * @param count Retry count - * @return Random sleep time in milliseconds - */ - long getRandomSleepTime(int count) { - return (Modbus.RETRY_SLEEP_TIME / 2) + (long) (random.nextDouble() * Modbus.RETRY_SLEEP_TIME * count); - } - - /** - * Executes this ModbusTransaction. - * Locks the ModbusTransport for sending - * the ModbusRequest and reading the - * related ModbusResponse. - * If reconnecting is activated the connection will - * be opened for the transaction and closed afterwards. - *

- * - * @throws ModbusException if an I/O error occurs, - * or the response is a modbus protocol exception. - */ - public abstract void execute() throws ModbusException; - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusUDPTransaction.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusUDPTransaction.java deleted file mode 100644 index 1ca212c..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusUDPTransaction.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusException; -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.ModbusSlaveException; -import com.ghgande.j2mod.modbus.msg.ExceptionResponse; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.net.AbstractUDPTerminal; -import com.ghgande.j2mod.modbus.net.UDPMasterConnection; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class implementing the ModbusTransaction - * interface for the UDP transport mechanism. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusUDPTransaction extends ModbusTransaction { - - private static final Logger logger = LoggerFactory.getLogger(ModbusUDPTransaction.class); - - //instance attributes and associations - private AbstractUDPTerminal terminal; - private final Object MUTEX = new Object(); - - /** - * Constructs a new ModbusUDPTransaction - * instance. - */ - public ModbusUDPTransaction() { - } - - /** - * Constructs a new ModbusUDPTransaction - * instance with a given ModbusRequest to - * be send when the transaction is executed. - *

- * - * @param request a ModbusRequest instance. - */ - public ModbusUDPTransaction(ModbusRequest request) { - setRequest(request); - } - - /** - * Constructs a new ModbusUDPTransaction - * instance with a given UDPTerminal to - * be used for transactions. - *

- * - * @param terminal a UDPTerminal instance. - */ - public ModbusUDPTransaction(AbstractUDPTerminal terminal) { - setTerminal(terminal); - } - - /** - * Constructs a new ModbusUDPTransaction - * instance with a given ModbusUDPConnection - * to be used for transactions. - *

- * - * @param con a ModbusUDPConnection instance. - */ - public ModbusUDPTransaction(UDPMasterConnection con) { - setTerminal(con.getTerminal()); - } - - /** - * Sets the terminal on which this ModbusTransaction - * should be executed.

- * - * @param terminal a UDPSlaveTerminal. - */ - public void setTerminal(AbstractUDPTerminal terminal) { - this.terminal = terminal; - if (terminal.isActive()) { - transport = terminal.getTransport(); - } - } - - @Override - public void execute() throws ModbusIOException, ModbusSlaveException, ModbusException { - - //1. assert executeability - assertExecutable(); - //2. open the connection if not connected - if (!terminal.isActive()) { - try { - terminal.activate(); - transport = terminal.getTransport(); - } - catch (Exception ex) { - logger.debug("Terminal activation failed.", ex); - throw new ModbusIOException("Activation failed"); - } - } - - //3. Retry transaction retries times, in case of - //I/O Exception problems. - int retryCount = 0; - while (retryCount <= retries) { - try { - //3. write request, and read response, - // while holding the lock on the IO object - synchronized (MUTEX) { - //write request message - transport.writeRequest(request); - //read response message - response = transport.readResponse(); - break; - } - } - catch (ModbusIOException ex) { - retryCount++; - if (retryCount > retries) { - logger.error("Cannot send UDP message", ex); - } - else { - ModbusUtil.sleep(getRandomSleepTime(retryCount)); - } - } - } - - //4. deal with "application level" exceptions - if (response instanceof ExceptionResponse) { - throw new ModbusSlaveException(((ExceptionResponse)response).getExceptionCode()); - } - - //toggle the id - incrementTransactionID(); - } - - /** - * Asserts if this ModbusTCPTransaction is - * executable. - * - * @throws ModbusException if this transaction cannot be - * asserted as executable. - */ - private void assertExecutable() throws ModbusException { - if (request == null || terminal == null) { - throw new ModbusException("Assertion failed, transaction not executable"); - } - } - - /** - * Toggles the transaction identifier, to ensure - * that each transaction has a distinctive - * identifier.
- * When the maximum value of 65535 has been reached, - * the identifiers will start from zero again. - */ - private void incrementTransactionID() { - if (isCheckingValidity()) { - if (transactionID >= Modbus.MAX_TRANSACTION_ID) { - transactionID = Modbus.DEFAULT_TRANSACTION_ID; - } - else { - transactionID++; - } - } - request.setTransactionID(getTransactionID()); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusUDPTransport.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusUDPTransport.java deleted file mode 100644 index 501343c..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/ModbusUDPTransport.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.msg.ModbusMessage; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.net.AbstractUDPTerminal; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.util.Arrays; - -/** - * Class that implements the Modbus UDP transport flavor. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusUDPTransport extends AbstractModbusTransport { - - private static final Logger logger = LoggerFactory.getLogger(ModbusUDPTransport.class); - - //instance attributes - private AbstractUDPTerminal terminal; - private final BytesOutputStream byteOutputStream = new BytesOutputStream(Modbus.MAX_MESSAGE_LENGTH); - private final BytesInputStream byteInputStream = new BytesInputStream(Modbus.MAX_MESSAGE_LENGTH); - - /** - * Constructs a new ModbusTransport instance, - * for a given UDPTerminal. - *

- * - * @param terminal the UDPTerminal used for message transport. - */ - public ModbusUDPTransport(AbstractUDPTerminal terminal) { - this.terminal = terminal; - } - - @Override - public void setTimeout(int time) { - super.setTimeout(time); - if (terminal != null) { - terminal.setTimeout(timeout); - } - } - - @Override - public void close() throws IOException { - } - - @Override - public ModbusTransaction createTransaction() { - ModbusUDPTransaction trans = new ModbusUDPTransaction(); - trans.setTerminal(terminal); - return trans; - } - - @Override - public void writeResponse(ModbusResponse msg) throws ModbusIOException { - writeMessage(msg); - } - - @Override - public void writeRequest(ModbusRequest msg) throws ModbusIOException { - writeMessage(msg); - } - - @Override - public ModbusRequest readRequest(AbstractModbusListener listener) throws ModbusIOException { - try { - ModbusRequest req; - synchronized (byteInputStream) { - byteInputStream.reset(terminal.receiveMessage()); - byteInputStream.skip(7); - int functionCode = byteInputStream.readUnsignedByte(); - byteInputStream.reset(); - req = ModbusRequest.createModbusRequest(functionCode); - req.readFrom(byteInputStream); - } - return req; - } - catch (Exception ex) { - throw new ModbusIOException("I/O exception - failed to read", ex); - } - } - - @Override - public ModbusResponse readResponse() throws ModbusIOException { - - try { - ModbusResponse res; - synchronized (byteInputStream) { - byteInputStream.reset(terminal.receiveMessage()); - byteInputStream.skip(7); - int functionCode = byteInputStream.readUnsignedByte(); - byteInputStream.reset(); - res = ModbusResponse.createModbusResponse(functionCode); - res.readFrom(byteInputStream); - } - return res; - } - catch (InterruptedIOException ioex) { - throw new ModbusIOException("Socket was interrupted", ioex); - } - catch (Exception ex) { - logger.debug("I/O exception while reading modbus response.", ex); - throw new ModbusIOException("I/O exception - failed to read - %s", ex.getMessage()); - } - } - - /** - * Writes the request/response message to the port - * @param msg Message to write - * @throws ModbusIOException If the port cannot be written to - */ - private void writeMessage(ModbusMessage msg) throws ModbusIOException { - try { - synchronized (byteOutputStream) { - int len = msg.getOutputLength(); - byteOutputStream.reset(); - msg.writeTo(byteOutputStream); - byte data[] = byteOutputStream.getBuffer(); - data = Arrays.copyOf(data, len); - terminal.sendMessage(data); - } - } - catch (Exception ex) { - throw new ModbusIOException("I/O exception - failed to write", ex); - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/io/NonWordDataHandler.java b/app/src/main/java/com/ghgande/j2mod/modbus/io/NonWordDataHandler.java deleted file mode 100644 index 29fc3a5..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/io/NonWordDataHandler.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.io; - -import java.io.DataInput; -import java.io.EOFException; -import java.io.IOException; - -/** - * Interface implementing a non word data handler for the read/write multiple - * register commands. - * - * This interface can be used by any class which works with multiple words of - * data for a non-standard data item. For example, message may involve data - * items which are floating point values or string. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - * @deprecated In the interests of keeping the library simple, this will be removed in a future release - */ -@Deprecated -public interface NonWordDataHandler { - - /** - * Returns the intermediate raw non-word data. - * - *

- * An implementation would need to provide a means of converting between the - * raw byte data and the registers that are present in actual messages. - * - * @return the raw data as byte[]. - */ - byte[] getData(); - - /** - * Reads the non-word raw data based on an arbitrary implemented structure. - * - * @param in the DataInput to read from. - * @param reference to specify the offset as int. - * @param count to specify the amount of bytes as int. - * - * @throws IOException if I/O fails. - * @throws EOFException if the stream ends before all data is read. - */ - void readData(DataInput in, int reference, int count) throws IOException, EOFException; - - /** - * Returns the word count of the data. Note that this should be the length - * of the byte array divided by two. - * - * @return the number of words the data consists of. - */ - int getWordCount(); - - /** - * Commits the data if it has been read into an intermediate repository. - * - *

- * This method is called for a message (for example, a - * WriteMultipleRegistersRequest instance) when finished with - * reading, for creating a response. - * - * @return -1 if the commit was successful, a Modbus exception code valid - * for the read/write multiple registers commands otherwise. - */ - int commitUpdate(); - - /** - * Prepares the raw data, putting it together from a backing data store. - * - *

- * This method is called for a message (for example, * ReadMultipleRegistersRequest) when finished with reading, for - * creating a response. - * - * @param reference to specify the offset as int. - * @param count to specify the number of bytes as int. - */ - void prepareData(int reference, int count); -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ExceptionResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ExceptionResponse.java deleted file mode 100644 index b599327..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ExceptionResponse.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing aModbusResponse that represents an exception. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ExceptionResponse extends ModbusResponse { - - // instance attributes - private int exceptionCode = -1; - - /** - * Constructs a new ExceptionResponse instance with a given - * function code and an exception code. The function code will be - * automatically increased with the exception offset. - * - * @param fc the function code as int. - * @param exc the exception code as int. - */ - public ExceptionResponse(int fc, int exc) { - - // One byte of data. - setDataLength(1); - setFunctionCode(fc | Modbus.EXCEPTION_OFFSET); - - exceptionCode = exc; - } - - /** - * Constructs a new ExceptionResponse instance with a given - * function code. ORs the exception offset automatically. - * - * @param fc the function code as int. - */ - public ExceptionResponse(int fc) { - - // One byte of data. - setDataLength(1); - setFunctionCode(fc | Modbus.EXCEPTION_OFFSET); - } - - /** - * Constructs a new ExceptionResponse instance with no function - * or exception code. - */ - public ExceptionResponse() { - - // One byte of data. - setDataLength(1); - } - - /** - * Returns the Modbus exception code of this ExceptionResponse. - *

- * - * @return the exception code as int. - */ - public int getExceptionCode() { - return exceptionCode; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeByte(getExceptionCode()); - } - - /** - * readData() - * - * read the single byte of data, which is the exception code. - * @throws IOException If the data cannot be read from the socket/port - */ - public void readData(DataInput din) throws IOException { - exceptionCode = din.readUnsignedByte(); - } - - /** - * getMessage() - * - * return the exception type, which is the "message" for this response. - * - * @return -- byte array containing the 1 byte exception code. - */ - public byte[] getMessage() { - byte result[] = new byte[1]; - result[0] = (byte)getExceptionCode(); - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalAddressExceptionResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalAddressExceptionResponse.java deleted file mode 100644 index a61456d..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalAddressExceptionResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -/** - * @author Julie - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class IllegalAddressExceptionResponse extends ExceptionResponse { - - /** - * - */ - public IllegalAddressExceptionResponse() { - super(0, Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - public IllegalAddressExceptionResponse(int function) { - super(function, Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - /** - * Sets the function code - * @param fc Function code - */ - public void setFunctionCode(int fc) { - super.setFunctionCode(fc | Modbus.EXCEPTION_OFFSET); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalFunctionExceptionResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalFunctionExceptionResponse.java deleted file mode 100644 index 4f9ce42..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalFunctionExceptionResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -/** - * @author jfhaugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class IllegalFunctionExceptionResponse extends ExceptionResponse { - - /** - * - */ - public IllegalFunctionExceptionResponse() { - super(0, Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - public IllegalFunctionExceptionResponse(int function) { - super(function | Modbus.EXCEPTION_OFFSET, Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * Sets the function code - * @param fc Function code - */ - public void setFunctionCode(int fc) { - super.setFunctionCode(fc | Modbus.EXCEPTION_OFFSET); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalFunctionRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalFunctionRequest.java deleted file mode 100644 index 33503d3..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalFunctionRequest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - *

- * Class implementing a ModbusRequest which is created for illegal or - * non implemented function codes. - * - *

- * This is just a helper class to keep the implementation patterns the same for - * all cases. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class IllegalFunctionRequest extends ModbusRequest { - - /** - * Constructs a new IllegalFunctionRequest instance for a given - * function code. - * - *

Used to implement slave devices when an illegal function code - * has been requested. - * - * @param function the function code as int. - */ - public IllegalFunctionRequest(int function) { - setFunctionCode(function); - } - - /** - * Constructs a new IllegalFunctionRequest instance for a given - * function code. - * - *

Used to implement slave devices when an illegal function code - * has been requested. - * - * @param unit Unit ID - * @param function the function code as int. - */ - public IllegalFunctionRequest(int unit, int function) { - setUnitID(unit); - setFunctionCode(function); - } - - /** - * There is no unit number associated with this exception. - * @return Modbus excepion response - */ - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new IllegalFunctionExceptionResponse(getFunctionCode()), true); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - public void writeData(DataOutput dout) throws IOException { - throw new RuntimeException(); - } - - /** - * Read all of the data that can be read. This is an unsupported - * function, so it may not be possible to know exactly how much data - * needs to be read. - * @throws IOException If the data cannot be read from the socket/port - */ - public void readData(DataInput din) throws IOException { - // skip all following bytes - int length = getDataLength(); - for (int i = 0; i < length; i++) { - din.readByte(); - } - } - - public byte[] getMessage() { - return null; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalValueExceptionResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalValueExceptionResponse.java deleted file mode 100644 index 05549e0..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/IllegalValueExceptionResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -/** - * @author Julie - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class IllegalValueExceptionResponse extends ExceptionResponse { - - /** - * - */ - public IllegalValueExceptionResponse() { - super(0, Modbus.ILLEGAL_VALUE_EXCEPTION); - } - - public IllegalValueExceptionResponse(int function) { - super(function, Modbus.ILLEGAL_VALUE_EXCEPTION); - } - - /** - * Sets the function code - * @param fc Function code - */ - public void setFunctionCode(int fc) { - super.setFunctionCode(fc | Modbus.EXCEPTION_OFFSET); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/MaskWriteRegisterRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/MaskWriteRegisterRequest.java deleted file mode 100644 index 65794c1..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/MaskWriteRegisterRequest.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.procimg.Register; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Mask Write Register request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class MaskWriteRegisterRequest extends ModbusRequest { - private int reference; - private int andMask; - private int orMask; - - /** - * Constructs a new Mask Write Register request. - * - * @param ref Register - * @param andMask AND Mask to use - * @param orMask OR Mask to use - */ - public MaskWriteRegisterRequest(int ref, int andMask, int orMask) { - super(); - - setFunctionCode(Modbus.MASK_WRITE_REGISTER); - setReference(ref); - setAndMask(andMask); - setOrMask(orMask); - - setDataLength(6); - } - - /** - * Constructs a new Mask Write Register request. - * instance. - */ - public MaskWriteRegisterRequest() { - super(); - - setFunctionCode(Modbus.MASK_WRITE_REGISTER); - setDataLength(6); - } - - /** - * getReference - * @return the reference field - */ - public int getReference() { - return reference; - } - - /** - * setReference -- set the reference field. - * @param ref the reference field - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * getAndMask -- return the AND mask value; - * - * @return int - */ - public int getAndMask() { - return andMask; - } - - /** - * setAndMask -- set AND mask - * @param mask AND mask - */ - public void setAndMask(int mask) { - andMask = mask; - } - - /** - * getOrMask -- return the OR mask value; - * - * @return int - */ - public int getOrMask() { - return orMask; - } - - /** - * setOrMask -- set OR mask - * @param mask OR mask - */ - public void setOrMask(int mask) { - orMask = mask; - } - - /** - * getResponse -- create an empty response for this request. - * @return empty response for this request - */ - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new MaskWriteRegisterResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - MaskWriteRegisterResponse response; - - // Get the process image. - ProcessImage procimg = listener.getProcessImage(getUnitID()); - try { - Register register = procimg.getRegister(reference); - - /* - * Get the original value. The AND mask will first be - * applied to clear any bits, then the OR mask will be - * applied to set them. - */ - int value = register.getValue(); - value = (value & andMask) | (orMask & ~andMask); - - // Store the modified value back where it came from. - register.setValue(value); - } - catch (IllegalAddressException iaex) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (MaskWriteRegisterResponse)getResponse(); - response.setReference(reference); - response.setAndMask(andMask); - response.setOrMask(orMask); - - return response; - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written from the socket/port - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- dummy function. There is no data with the request. - * @throws IOException If the data cannot be read from the socket/port - */ - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - andMask = din.readUnsignedShort(); - orMask = din.readUnsignedShort(); - } - - /** - * getMessage -- return an empty array as there is no data for - * this request. - * @return message payload - */ - public byte[] getMessage() { - byte results[] = new byte[6]; - - results[0] = (byte)(reference >> 8); - results[1] = (byte)(reference & 0xFF); - results[2] = (byte)(andMask >> 8); - results[3] = (byte)(andMask & 0xFF); - results[4] = (byte)(orMask >> 8); - results[5] = (byte)(orMask & 0xFF); - - return results; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/MaskWriteRegisterResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/MaskWriteRegisterResponse.java deleted file mode 100644 index f22cb5f..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/MaskWriteRegisterResponse.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadMEIResponse. - * - * Derived from similar class for Read Coils response. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class MaskWriteRegisterResponse - extends ModbusResponse { - - // Message fields. - private int reference; - private int andMask; - private int orMask; - - /** - * Constructs a new ReportSlaveIDResponse - * instance. - */ - public MaskWriteRegisterResponse() { - super(); - setFunctionCode(Modbus.MASK_WRITE_REGISTER); - } - - /** - * getReference - * @return the reference field - */ - public int getReference() { - return reference; - } - - /** - * setReference -- set the reference field. - * @param ref Register value - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * getAndMask -- return the AND mask value; - * - * @return int - */ - public int getAndMask() { - return andMask; - } - - /** - * setAndMask -- set AND mask - * @param mask Mask to use - */ - public void setAndMask(int mask) { - andMask = mask; - } - - /** - * getOrMask -- return the OR mask value; - * - * @return int - */ - public int getOrMask() { - return orMask; - } - - /** - * setOrMask -- set OR mask - * @param mask OR bit mask - */ - public void setOrMask(int mask) { - orMask = mask; - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written to the socket/port - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- input the Modbus message from din. If there was a - * header, such as for Modbus/TCP, it will have been read - * already. - * @throws IOException If the data cannot be read from the socket/port - */ - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - andMask = din.readUnsignedShort(); - orMask = din.readUnsignedShort(); - } - - /** - * getMessage -- format the message into a byte array. - * @return Byte array of the message - */ - public byte[] getMessage() { - byte results[] = new byte[6]; - - results[0] = (byte)(reference >> 8); - results[1] = (byte)(reference & 0xFF); - results[2] = (byte)(andMask >> 8); - results[3] = (byte)(andMask & 0xFF); - results[4] = (byte)(orMask >> 8); - results[5] = (byte)(orMask & 0xFF); - - return results; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusMessage.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusMessage.java deleted file mode 100644 index be5693b..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusMessage.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Interface defining a ModbusMessage. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface ModbusMessage { - - /** - * Check the flag which indicates that this ModbusMessage is for a - * headless (serial, or headless networked) connection. - * @return is for a headless (serial, or headless networked) connection - */ - boolean isHeadless(); - - /** - * Sets the flag that marks this ModbusMessage as headless (for - * serial transport). - */ - void setHeadless(); - - /** - * Returns the transaction identifier of this ModbusMessage as - * int. - * - *

- * The identifier is a 2-byte (short) non negative integer value valid in - * the range of 0-65535. - * - * @return the transaction identifier as int. - */ - int getTransactionID(); - - /** - * Returns the protocol identifier of this ModbusMessage as - * int. - * - *

- * The identifier is a 2-byte (short) non negative integer value valid in - * the range of 0-65535. - * - * @return the protocol identifier as int. - */ - int getProtocolID(); - - /** - * Returns the length of the data appended after the protocol header. - *

- * - * @return the data length as int. - */ - int getDataLength(); - - /** - * Returns the unit identifier of this ModbusMessage as - * int. - * - *

- * The identifier is a 1-byte non negative integer value valid in the range - * of 0-255. - * - * @return the unit identifier as int. - */ - int getUnitID(); - - /** - * Returns the function code of this ModbusMessage as int.
- * The function code is a 1-byte non negative integer value valid in the - * range of 0-127. - * - *

- * Function codes are ordered in conformance classes their values are - * specified in com.ghgande.j2mod.modbus.Modbus. - * - * @return the function code as int. - * - * @see com.ghgande.j2mod.modbus.Modbus - */ - int getFunctionCode(); - - /** - * Returns the raw message as an array of bytes. - *

- * - * @return the raw message as byte[]. - */ - byte[] getMessage(); - - /** - * Returns the raw message as String containing a - * hexadecimal series of bytes. - * - *

- * This method is specially for debugging purposes, allowing the user to log - * the communication in a manner used in the specification document. - * - * @return the raw message as String containing a - * hexadecimal series of bytes. - */ - String getHexMessage(); - - /** - * Returns the number of bytes that will - * be written by {@link #writeTo(DataOutput)}. - * - * @return the number of bytes that will be written as int. - */ - int getOutputLength(); - - /** - * Writes this Transportable to the - * given DataOutput. - * - * @param dout the DataOutput to write to. - * - * @throws IOException if an I/O error occurs. - */ - void writeTo(DataOutput dout) throws IOException; - - /** - * Reads this Transportable from the given - * DataInput. - * - * @param din the DataInput to read from. - * - * @throws IOException if an I/O error occurs or the data - * is invalid. - */ - void readFrom(DataInput din) throws IOException; - - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusMessageImpl.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusMessageImpl.java deleted file mode 100644 index f9ebe20..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusMessageImpl.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.util.ModbusUtil; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Abstract class implementing a ModbusMessage. This class provides - * specialised implementations with the functionality they have in common. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class ModbusMessageImpl implements ModbusMessage { - - // instance attributes - private int transactionID = Modbus.DEFAULT_TRANSACTION_ID; - private int protocolID = Modbus.DEFAULT_PROTOCOL_ID; - private int dataLength; - private int unitID = Modbus.DEFAULT_UNIT_ID; - private int functionCode; - private boolean headless = false; // flag for header-less (serial) - - @Override - public boolean isHeadless() { - return headless; - } - - @Override - public void setHeadless() { - headless = true; - } - - @Override - public int getTransactionID() { - return transactionID & 0x0000FFFF; - } - - /** - * Sets the transaction identifier of this ModbusMessage. - * - *

- * The identifier must be a 2-byte (short) non negative integer value valid - * in the range of 0-65535.
- * - * @param tid the transaction identifier as int. - */ - public void setTransactionID(int tid) { - transactionID = tid & 0x0000FFFF; - } - - @Override - public int getProtocolID() { - return protocolID; - } - - /** - * Sets the protocol identifier of this ModbusMessage. - *

- * The identifier should be a 2-byte (short) non negative integer value - * valid in the range of 0-65535.
- *

- * - * @param pid the protocol identifier as int. - */ - public void setProtocolID(int pid) { - protocolID = pid; - } - - @Override - public int getDataLength() { - return dataLength; - } - - /** - * Sets the length of the data appended after the protocol header. - * - *

- * Note that this library, a bit in contrast to the specification, counts - * the unit identifier and the function code in the header, because it is - * part of each and every message. Thus this method will add two (2) to the - * passed in integer value. - * - *

- * This method does not include the length of a final CRC/LRC for those - * protocols which requirement. - * - * @param length the data length as int. - */ - public void setDataLength(int length) { - if (length < 0 || length + 2 > 255) { - throw new IllegalArgumentException("Invalid length: " + length); - } - - dataLength = length + 2; - } - - @Override - public int getUnitID() { - return unitID; - } - - /** - * Sets the unit identifier of this ModbusMessage.
- * The identifier should be a 1-byte non negative integer value valid in the - * range of 0-255. - * - * @param num the unit identifier number to be set. - */ - public void setUnitID(int num) { - unitID = num; - } - - @Override - public int getFunctionCode() { - return functionCode; - } - - /** - * Sets the function code of this ModbusMessage.
- * The function code should be a 1-byte non negative integer value valid in - * the range of 0-127.
- * Function codes are ordered in conformance classes their values are - * specified in com.ghgande.j2mod.modbus.Modbus. - * - * @param code the code of the function to be set. - * - * @see com.ghgande.j2mod.modbus.Modbus - */ - protected void setFunctionCode(int code) { - functionCode = code; - } - - @Override - public String getHexMessage() { - return ModbusUtil.toHex(this); - } - - /** - * Sets the headless flag of this message. - * - * @param b true if headless, false otherwise. - */ - public void setHeadless(boolean b) { - headless = b; - } - - @Override - public int getOutputLength() { - int l = 2 + getDataLength(); - if (!isHeadless()) { - l = l + 4; - } - return l; - } - - @Override - public void writeTo(DataOutput dout) throws IOException { - - if (!isHeadless()) { - dout.writeShort(getTransactionID()); - dout.writeShort(getProtocolID()); - dout.writeShort(getDataLength()); - } - dout.writeByte(getUnitID()); - dout.writeByte(getFunctionCode()); - - writeData(dout); - } - - @Override - public void readFrom(DataInput din) throws IOException { - if (!isHeadless()) { - setTransactionID(din.readUnsignedShort()); - setProtocolID(din.readUnsignedShort()); - dataLength = din.readUnsignedShort(); - } - setUnitID(din.readUnsignedByte()); - setFunctionCode(din.readUnsignedByte()); - readData(din); - } - - /** - * Writes the subclass specific data to the given DataOutput. - * - * @param dout the DataOutput to be written to. - * - * @throws IOException if an I/O related error occurs. - */ - public abstract void writeData(DataOutput dout) throws IOException; - - /** - * Reads the subclass specific data from the given DataInput instance. - * - * @param din the DataInput to read from. - * - * @throws IOException if an I/O related error occurs. - */ - public abstract void readData(DataInput din) throws IOException; - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusRequest.java deleted file mode 100644 index 286c590..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusRequest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -/** - * Abstract class implementing a ModbusRequest. This class provides - * specialised implementations with the functionality they have in common. - * - * @author Dieter Wimberger - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class ModbusRequest extends ModbusMessageImpl { - - /** - * Factory method creating the required specialized ModbusRequest - * instance. - * - * @param functionCode the function code of the request as int. - * - * @return a ModbusRequest instance specific for the given function type. - */ - public static ModbusRequest createModbusRequest(int functionCode) { - ModbusRequest request; - - switch (functionCode) { - case Modbus.READ_COILS: - request = new ReadCoilsRequest(); - break; - case Modbus.READ_INPUT_DISCRETES: - request = new ReadInputDiscretesRequest(); - break; - case Modbus.READ_MULTIPLE_REGISTERS: - request = new ReadMultipleRegistersRequest(); - break; - case Modbus.READ_INPUT_REGISTERS: - request = new ReadInputRegistersRequest(); - break; - case Modbus.WRITE_COIL: - request = new WriteCoilRequest(); - break; - case Modbus.WRITE_SINGLE_REGISTER: - request = new WriteSingleRegisterRequest(); - break; - case Modbus.WRITE_MULTIPLE_COILS: - request = new WriteMultipleCoilsRequest(); - break; - case Modbus.WRITE_MULTIPLE_REGISTERS: - request = new WriteMultipleRegistersRequest(); - break; - case Modbus.READ_EXCEPTION_STATUS: - request = new ReadExceptionStatusRequest(); - break; - case Modbus.READ_SERIAL_DIAGNOSTICS: - request = new ReadSerialDiagnosticsRequest(); - break; - case Modbus.READ_COMM_EVENT_COUNTER: - request = new ReadCommEventCounterRequest(); - break; - case Modbus.READ_COMM_EVENT_LOG: - request = new ReadCommEventLogRequest(); - break; - case Modbus.REPORT_SLAVE_ID: - request = new ReportSlaveIDRequest(); - break; - case Modbus.READ_FILE_RECORD: - request = new ReadFileRecordRequest(); - break; - case Modbus.WRITE_FILE_RECORD: - request = new WriteFileRecordRequest(); - break; - case Modbus.MASK_WRITE_REGISTER: - request = new MaskWriteRegisterRequest(); - break; - case Modbus.READ_WRITE_MULTIPLE: - request = new ReadWriteMultipleRequest(); - break; - case Modbus.READ_FIFO_QUEUE: - request = new ReadFIFOQueueRequest(); - break; - case Modbus.READ_MEI: - request = new ReadMEIRequest(); - break; - default: - request = new IllegalFunctionRequest(functionCode); - break; - } - return request; - } - - /** - * Returns the ModbusResponse that correlates with this - * ModbusRequest. - * - *

- * The response must include the unit number, function code, as well as any - * transport-specific header information. - * - *

- * This method is used to create an empty response which must be populated - * by the caller. It is commonly used to un-marshal responses from Modbus - * slaves. - * - * @return the corresponding ModbusResponse. - */ - public abstract ModbusResponse getResponse(); - - /** - * Returns the ModbusResponse that represents the answer to this - * ModbusRequest. - * - *

- * The implementation should take care about assembling the reply to this - * ModbusRequest. - * - *

- * This method is used to create responses from the process image associated - * with the listener. It is commonly used to implement Modbus slave - * instances. - * - * @param listener Listener that received the request - * @return the corresponding ModbusResponse. - */ - public abstract ModbusResponse createResponse(AbstractModbusListener listener); - - /** - * Factory method for creating exception responses with the given exception - * code. - * - * @param code the code of the exception. - * - * @return a ModbusResponse instance representing the exception response. - */ - public ModbusResponse createExceptionResponse(int code) { - return updateResponseWithHeader(new ExceptionResponse(getFunctionCode(), code), true); - } - - /** - * Updates the response with the header information to match the request - * - * @param response Response to update - * @return Updated response - */ - ModbusResponse updateResponseWithHeader(ModbusResponse response) { - return updateResponseWithHeader(response, false); - } - - /** - * Updates the response with the header information to match the request - * - * @param response Response to update - * @param ignoreFunctionCode True if the function code should stay unmolested - * @return Updated response - */ - ModbusResponse updateResponseWithHeader(ModbusResponse response, boolean ignoreFunctionCode) { - - // transfer header data - response.setHeadless(isHeadless()); - if (!isHeadless()) { - response.setTransactionID(getTransactionID()); - response.setProtocolID(getProtocolID()); - } - else { - response.setHeadless(); - } - response.setUnitID(getUnitID()); - if (!ignoreFunctionCode) { - response.setFunctionCode(getFunctionCode()); - } - return response; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusResponse.java deleted file mode 100644 index 41d2cea..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ModbusResponse.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import static com.ghgande.j2mod.modbus.msg.ModbusResponse.AuxiliaryMessageTypes.NONE; - -/** - * Abstract class implementing a ModbusResponse. This class provides - * specialised implementations with the functionality they have in common. - * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class ModbusResponse extends ModbusMessageImpl { - - private static final Logger logger = LoggerFactory.getLogger(ModbusResponse.class); - - public enum AuxiliaryMessageTypes { - NONE, UNIT_ID_MISSMATCH - } - private AuxiliaryMessageTypes auxiliaryType = NONE; - - /** - * Factory method creating the required specialized ModbusResponse - * instance. - * - * @param functionCode the function code of the response as int. - * - * @return a ModbusResponse instance specific for the given function code. - */ - public static ModbusResponse createModbusResponse(int functionCode) { - ModbusResponse response; - - switch (functionCode) { - case Modbus.READ_COILS: - response = new ReadCoilsResponse(); - break; - case Modbus.READ_INPUT_DISCRETES: - response = new ReadInputDiscretesResponse(); - break; - case Modbus.READ_MULTIPLE_REGISTERS: - response = new ReadMultipleRegistersResponse(); - break; - case Modbus.READ_INPUT_REGISTERS: - response = new ReadInputRegistersResponse(); - break; - case Modbus.WRITE_COIL: - response = new WriteCoilResponse(); - break; - case Modbus.WRITE_SINGLE_REGISTER: - response = new WriteSingleRegisterResponse(); - break; - case Modbus.WRITE_MULTIPLE_COILS: - response = new WriteMultipleCoilsResponse(); - break; - case Modbus.WRITE_MULTIPLE_REGISTERS: - response = new WriteMultipleRegistersResponse(); - break; - case Modbus.READ_EXCEPTION_STATUS: - response = new ReadExceptionStatusResponse(); - break; - case Modbus.READ_SERIAL_DIAGNOSTICS: - response = new ReadSerialDiagnosticsResponse(); - break; - case Modbus.READ_COMM_EVENT_COUNTER: - response = new ReadCommEventCounterResponse(); - break; - case Modbus.READ_COMM_EVENT_LOG: - response = new ReadCommEventLogResponse(); - break; - case Modbus.REPORT_SLAVE_ID: - response = new ReportSlaveIDResponse(); - break; - case Modbus.READ_FILE_RECORD: - response = new ReadFileRecordResponse(); - break; - case Modbus.WRITE_FILE_RECORD: - response = new WriteFileRecordResponse(); - break; - case Modbus.MASK_WRITE_REGISTER: - response = new MaskWriteRegisterResponse(); - break; - case Modbus.READ_WRITE_MULTIPLE: - response = new ReadWriteMultipleResponse(); - break; - case Modbus.READ_FIFO_QUEUE: - response = new ReadFIFOQueueResponse(); - break; - case Modbus.READ_MEI: - response = new ReadMEIResponse(); - break; - default: - if ((functionCode & 0x80) != 0) { - response = new ExceptionResponse(functionCode); - } - else { - response = new ExceptionResponse(); - } - break; - } - return response; - } - - /** - * Utility method to set the raw data of the message. Should not be used - * except under rare circumstances. - *

- * - * @param msg the byte[] resembling the raw modbus response - * message. - */ - protected void setMessage(byte[] msg) { - try { - readData(new DataInputStream(new ByteArrayInputStream(msg))); - } - catch (IOException ex) { - logger.error("Problem setting response message - {}", ex.getMessage()); - } - } - - /** - * Returns the auxiliary type of this response message - * Useful for adding extra information to the message that can be used by downstream processing - * - * @return Auxiliary type - */ - public AuxiliaryMessageTypes getAuxiliaryType() { - return auxiliaryType; - } - - /** - * Sets the auxiliary type of this response - * - * @param auxiliaryType Type - */ - public void setAuxiliaryType(AuxiliaryMessageTypes auxiliaryType) { - this.auxiliaryType = auxiliaryType; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCoilsRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCoilsRequest.java deleted file mode 100644 index b8bd207..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCoilsRequest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.DigitalOut; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadCoilsRequest. The implementation directly - * correlates with the class 1 function read coils (FC 1). It - * encapsulates the corresponding request message. - * - *

- * Coils are understood as bits that can be manipulated (i.e. set or unset). - * - * @author Dieter Wimberger - * @author jfhaugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadCoilsRequest extends ModbusRequest { - - // instance attributes - private int reference; - private int bitCount; - - /** - * Constructs a new ReadCoilsRequest instance. - */ - public ReadCoilsRequest() { - super(); - - setFunctionCode(Modbus.READ_COILS); - setDataLength(4); - } - - /** - * Constructs a new ReadCoilsRequest instance with a given - * reference and count of coils (i.e. bits) to be read. - *

- * - * @param ref the reference number of the register to read from. - * @param count the number of bits to be read. - */ - public ReadCoilsRequest(int ref, int count) { - super(); - - setFunctionCode(Modbus.READ_COILS); - setDataLength(4); - - setReference(ref); - setBitCount(count); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadCoilsResponse(bitCount)); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ModbusResponse response; - DigitalOut[] douts; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - - // 2. get input discretes range - try { - douts = procimg.getDigitalOutRange(getReference(), getBitCount()); - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = getResponse(); - - // Populate the discrete values from the process image. - for (int i = 0; i < douts.length; i++) { - ((ReadCoilsResponse)response).setCoilStatus(i, douts[i].isSet()); - } - - return response; - } - - /** - * Returns the reference of the register to to start reading from with this - * ReadCoilsRequest. - *

- * - * @return the reference of the register to start reading from as - * int. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register to start reading from with this - * ReadCoilsRequest. - *

- * - * @param ref the reference of the register to start reading from. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * Returns the number of bits (i.e. coils) to be read with this - * ReadCoilsRequest. - *

- * - * @return the number of bits to be read. - */ - public int getBitCount() { - return bitCount; - } - - /** - * Sets the number of bits (i.e. coils) to be read with this - * ReadCoilsRequest. - *

- * - * @param count the number of bits to be read. - */ - public void setBitCount(int count) { - if (count > Modbus.MAX_BITS) { - throw new IllegalArgumentException("Maximum bitcount exceeded"); - } - else { - bitCount = count; - } - } - - @Override - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - @Override - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - bitCount = din.readUnsignedShort(); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)((reference & 0xff)); - result[2] = (byte)((bitCount >> 8) & 0xff); - result[3] = (byte)((bitCount & 0xff)); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCoilsResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCoilsResponse.java deleted file mode 100644 index 33bad4d..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCoilsResponse.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.util.BitVector; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadCoilsResponse. - * The implementation directly correlates with the class 1 - * function read coils (FC 1). It encapsulates - * the corresponding response message. - *

- * Coils are understood as bits that can be manipulated - * (i.e. set or unset). - * - * @author Dieter Wimberger - * @version 1.2rc1 (09/11/2004) - */ - -/** - * Completed re-implementation 1/10/2011 - * - * Created getMessage() method to abstractly create the message - * data. - * Cleaned up the constructors. - * - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadCoilsResponse extends ModbusResponse { - private BitVector coils; - - /** - * ReadCoilsResponse -- create an empty response message to be - * filled in later. - */ - public ReadCoilsResponse() { - setFunctionCode(Modbus.READ_COILS); - setDataLength(1); - coils = null; - } - - /** - * ReadCoilsResponse -- create a response for a given number of - * coils. - * - * @param count the number of bits to be read. - */ - public ReadCoilsResponse(int count) { - setFunctionCode(Modbus.READ_COILS); - coils = new BitVector(count); - setDataLength(coils.byteSize() + 1); - } - - /** - * getBitCount -- return the number of coils - * - * @return number of defined coils - */ - public int getBitCount() { - if (coils == null) { - return 0; - } - else { - return coils.size(); - } - } - - /** - * getCoils -- get the coils bit vector. - * - * The coils vector may be read (when operating as a master) or - * written (when operating as a slave). - * - * @return BitVector containing the coils. - */ - public BitVector getCoils() { - return coils; - } - - /** - * Convenience method that returns the state - * of the bit at the given index. - *

- * - * @param index the index of the coil for which - * the status should be returned. - * - * @return true if set, false otherwise. - * - * @throws IndexOutOfBoundsException if the - * index is out of bounds - */ - public boolean getCoilStatus(int index) throws IndexOutOfBoundsException { - - if (index < 0) { - throw new IllegalArgumentException(index + " < 0"); - } - - if (index > coils.size()) { - throw new IndexOutOfBoundsException(index + " > " + coils.size()); - } - - return coils.getBit(index); - } - - /** - * Sets the status of the given coil. - * - * @param index the index of the coil to be set. - * @param b true if to be set, false for reset. - */ - public void setCoilStatus(int index, boolean b) { - if (index < 0) { - throw new IllegalArgumentException(index + " < 0"); - } - - if (index > coils.size()) { - throw new IndexOutOfBoundsException(index + " > " + coils.size()); - } - - coils.setBit(index, b); - } - - public void writeData(DataOutput output) throws IOException { - byte result[] = getMessage(); - - output.write(result); - } - - public void readData(DataInput input) throws IOException { - int count = input.readUnsignedByte(); - byte[] data = new byte[count]; - - input.readFully(data, 0, count); - coils = BitVector.createBitVector(data); - setDataLength(count + 1); - } - - public byte[] getMessage() { - int len = 1 + coils.byteSize(); - byte result[] = new byte[len]; - - result[0] = (byte)coils.byteSize(); - System.arraycopy(coils.getBytes(), 0, result, 1, coils.byteSize()); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventCounterRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventCounterRequest.java deleted file mode 100644 index 7709439..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventCounterRequest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Read MEI Data request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadCommEventCounterRequest extends ModbusRequest { - - /** - * Constructs a new Report Slave ID request instance. - */ - public ReadCommEventCounterRequest() { - super(); - - setFunctionCode(Modbus.READ_COMM_EVENT_COUNTER); - - // There is no additional data in this request. - setDataLength(0); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadCommEventCounterResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- dummy function. There is no additional data - * to read. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - } - - /** - * getMessage - * @return an empty array as there is no data for this request - */ - public byte[] getMessage() { - - return new byte[0]; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventCounterResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventCounterResponse.java deleted file mode 100644 index c12a709..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventCounterResponse.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadCommEventCounterResponse. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadCommEventCounterResponse extends ModbusResponse { - - // Message fields. - private int status; - private int events; - - /** - * Constructs a new ReportSlaveIDResponse instance. - */ - public ReadCommEventCounterResponse() { - super(); - - setFunctionCode(Modbus.READ_COMM_EVENT_COUNTER); - setDataLength(4); - } - - /** - * getStatus -- get the device's status. - * - * @return int - */ - public int getStatus() { - return status; - } - - /** - * setStatus -- set the device's status. - * - * @param status int - */ - public void setStatus(int status) { - if (status != 0 && status != 0xFFFF) { - throw new IllegalArgumentException("Illegal status value: " + status); - } - - this.status = status; - } - - /** - * getEvents -- get device's event counter. - * @return Event count - */ - public int getEventCount() { - return events; - } - - /** - * setEvents -- set the device's event counter. - * @param count Event count - */ - public void setEventCount(int count) { - events = count; - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- input the Modbus message from din. If there was a header, - * such as for Modbus/TCP, it will have been read already. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - status = din.readUnsignedShort(); - events = din.readUnsignedShort(); - } - - /** - * getMessage -- format the message into a byte array. - * @return Response as byte array - */ - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)(status >> 8); - result[1] = (byte)(status & 0xFF); - result[2] = (byte)(events >> 8); - result[3] = (byte)(events & 0xFF); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventLogRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventLogRequest.java deleted file mode 100644 index 04e27ee..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventLogRequest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Read MEI Data request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadCommEventLogRequest extends ModbusRequest { - - /** - * Constructs a new Get Comm Event Log - * instance. - */ - public ReadCommEventLogRequest() { - super(); - - setFunctionCode(Modbus.READ_COMM_EVENT_LOG); - - // There is no additional data in this request. - setDataLength(0); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadCommEventLogResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- dummy function. There is no data with the request. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - } - - /** - * getMessage - * @return an empty array as there is no data for this request - */ - public byte[] getMessage() { - - return new byte[0]; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventLogResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventLogResponse.java deleted file mode 100644 index 8911aa7..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadCommEventLogResponse.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadCommEventCounterResponse. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadCommEventLogResponse extends ModbusResponse { - - // Message fields. - private int byteCount; - private int status; - private int eventCount; - private int messageCount; - private byte[] events; - - /** - * Constructs a new ReadCommEventLogResponse instance. - */ - public ReadCommEventLogResponse() { - super(); - - setFunctionCode(Modbus.READ_COMM_EVENT_LOG); - setDataLength(7); - } - - /** - * getStatus -- get the device's status. - * - * @return int - */ - public int getStatus() { - return status; - } - - /** - * setStatus -- set the device's status. - * - * @param status Status to set - */ - public void setStatus(int status) { - this.status = status; - } - - /** - * getEvents -- get device's event counter. - * @return Number of events - */ - public int getEventCount() { - return eventCount; - } - - /** - * setEventCount -- set the device's event counter. - * @param count Set the event count - */ - public void setEventCount(int count) { - eventCount = count; - } - - /** - * getMessageCount -- get device's message counter. - * - * @return Number of messages - */ - public int getMessageCount() { - return messageCount; - } - - /** - * setMessageCount -- set device's message counter. - * @param count Number of messages - */ - public void setMessageCount(int count) { - messageCount = count; - } - - /** - * getEvent -- get an event from the event log. - * @param index Index of the event - * @return Event ID - */ - public int getEvent(int index) { - if (events == null || index < 0 || index >= events.length) { - throw new IndexOutOfBoundsException("index = " + index + ", limit = " + (events == null ? "null" : events.length)); - } - - return events[index] & 0xFF; - } - - public byte[] getEvents() { - if (events == null) { - return null; - } - - byte[] result = new byte[events.length]; - System.arraycopy(events, 0, result, 0, events.length); - - return result; - } - - public void setEvents(byte[] events) { - if (events.length > 64) { - throw new IllegalArgumentException("events list too big (> 64 bytes)"); - } - - events = new byte[events.length]; - if (events.length > 0) { - System.arraycopy(events, 0, events, 0, events.length); - } - } - - public void setEvents(int count) { - if (count < 0 || count > 64) { - throw new IllegalArgumentException("invalid event list size (0 <= count <= 64)"); - } - - events = new byte[count]; - } - - /** - * setEvent -- store an event number in the event log - * @param index Event position - * @param event Event ID - */ - public void setEvent(int index, int event) { - if (events == null || index < 0 || index >= events.length) { - throw new IndexOutOfBoundsException("index = " + index + ", limit = " + (events == null ? "null" : events.length)); - } - - events[index] = (byte)event; - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- input the Modbus message from din. If there was a header, - * such as for Modbus/TCP, it will have been read already. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - byteCount = din.readByte(); - status = din.readUnsignedShort(); - eventCount = din.readUnsignedShort(); - messageCount = din.readUnsignedShort(); - - events = new byte[byteCount - 6]; - - if (events.length > 0) { - din.readFully(events, 0, events.length); - } - } - - /** - * getMessage -- format the message into a byte array. - * @return Response as byte array - */ - public byte[] getMessage() { - byte result[] = new byte[events.length + 7]; - - result[0] = (byte)(byteCount = events.length + 6); - result[1] = (byte)(status >> 8); - result[2] = (byte)(status & 0xFF); - result[3] = (byte)(eventCount >> 8); - result[4] = (byte)(eventCount & 0xFF); - result[5] = (byte)(messageCount >> 8); - result[6] = (byte)(messageCount & 0xFF); - - System.arraycopy(events, 0, result, 7, events.length); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadExceptionStatusRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadExceptionStatusRequest.java deleted file mode 100644 index a13c3f5..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadExceptionStatusRequest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Read Exception Status request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadExceptionStatusRequest extends ModbusRequest { - - /** - * Constructs a new Read Exception Status request - * instance. - */ - public ReadExceptionStatusRequest() { - super(); - - setFunctionCode(Modbus.READ_EXCEPTION_STATUS); - - // There is no additional data in this request. - setDataLength(0); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadExceptionStatusResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- dummy function. There is no data with the request. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - } - - /** - * getMessage - * @return an empty array as there is no data for this request - */ - public byte[] getMessage() { - - return new byte[0]; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadExceptionStatusResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadExceptionStatusResponse.java deleted file mode 100644 index 7f26e66..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadExceptionStatusResponse.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadCommEventCounterResponse. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadExceptionStatusResponse extends ModbusResponse { - - // Message fields. - private int status; - - /** - * Constructs a new ReadExceptionStatusResponse instance. - */ - public ReadExceptionStatusResponse() { - super(); - - setFunctionCode(Modbus.READ_EXCEPTION_STATUS); - setDataLength(1); - } - - /** - * getStatus -- get the device's status. - * - * @return int - */ - public int getStatus() { - return status; - } - - /** - * setStatus -- set the device's status. - * - * @param status Status to set - */ - public void setStatus(int status) { - this.status = status; - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- input the Modbus message from din. If there was a header, - * such as for Modbus/TCP, it will have been read already. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - status = din.readByte() & 0xFF; - } - - /** - * getMessage -- format the message into a byte array. - * @return Response as byte array - */ - public byte[] getMessage() { - byte result[] = new byte[1]; - - result[0] = (byte)(status & 0xFF); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFIFOQueueRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFIFOQueueRequest.java deleted file mode 100644 index 86885d7..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFIFOQueueRequest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.procimg.Register; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Read FIFO Queue request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadFIFOQueueRequest extends ModbusRequest { - - private int reference; - - /** - * Constructs a new Read FIFO Queue request instance. - */ - public ReadFIFOQueueRequest() { - super(); - - setFunctionCode(Modbus.READ_FIFO_QUEUE); - setDataLength(2); - } - - /** - * getReference -- get the queue register number. - * - * @return int - */ - public int getReference() { - return reference; - } - - /** - * setReference -- set the queue register number. - * - * @param ref Register - */ - public void setReference(int ref) { - reference = ref; - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadFIFOQueueResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ReadFIFOQueueResponse response; - InputRegister[] registers; - - // Get the process image. - ProcessImage procimg = listener.getProcessImage(getUnitID()); - - try { - // Get the FIFO queue location and read the count of available - // registers. - Register queue = procimg.getRegister(reference); - int count = queue.getValue(); - if (count < 0 || count > 31) { - return createExceptionResponse(Modbus.ILLEGAL_VALUE_EXCEPTION); - } - registers = procimg.getRegisterRange(reference + 1, count); - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (ReadFIFOQueueResponse)getResponse(); - response.setRegisters(registers); - - return response; - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If cannot write - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- read the reference word. - * @throws IOException If cannot read - */ - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - } - - /** - * getMessage - * @return an empty array as there is no data for this request - */ - public byte[] getMessage() { - byte results[] = new byte[2]; - - results[0] = (byte)(reference >> 8); - results[1] = (byte)(reference & 0xFF); - - return results; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFIFOQueueResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFIFOQueueResponse.java deleted file mode 100644 index 5163893..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFIFOQueueResponse.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.procimg.SimpleInputRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Arrays; - -/** - * Class implementing a ReadFIFOQueueResponse. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadFIFOQueueResponse extends ModbusResponse { - - // Message fields. - private int count; - private InputRegister registers[]; - - /** - * Constructs a new ReadFIFOQueueResponse instance. - */ - public ReadFIFOQueueResponse() { - super(); - - setFunctionCode(Modbus.READ_FIFO_QUEUE); - - count = 0; - registers = new InputRegister[0]; - - setDataLength(7); - } - - /** - * getWordCount -- get the queue size. - * - * @return Word count int - */ - synchronized public int getWordCount() { - return count; - } - - /** - * setWordCount -- set the queue size. - * - * @param ref Register - */ - public synchronized void setWordCount(int ref) { - if (ref < 0 || ref > 31) { - throw new IllegalArgumentException(); - } - count = ref; - } - - synchronized public int[] getRegisters() { - int values[] = new int[count]; - - for (int i = 0; i < count; i++) { - values[i] = getRegister(i); - } - - return values; - } - - /** - * setRegisters -- set the device's status. - * - * @param regs Array of registers - */ - public synchronized void setRegisters(InputRegister[] regs) { - if (regs == null) { - registers = null; - count = 0; - return; - } - - registers = Arrays.copyOf(regs, regs.length); - if (regs.length > 31) { - throw new IllegalArgumentException(); - } - - count = regs.length; - } - - public int getRegister(int index) { - return registers[index].getValue(); - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- input the Modbus message from din. If there was a header, - * such as for Modbus/TCP, it will have been read already. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - - /* - * Read and discard the byte count. There's no way to indicate - * the packet was inconsistent, other than throwing an I/O - * exception for an invalid packet format ... - */ - din.readShort(); - - // The first register is the number of registers which - // follow. Save that as count, not as a register. - count = din.readUnsignedShort(); - registers = new InputRegister[count]; - - for (int i = 0; i < count; i++) { - registers[i] = new SimpleInputRegister(din.readShort()); - } - } - - /** - * getMessage -- format the message into a byte array. - * @return Byte array of message - */ - public byte[] getMessage() { - byte result[] = new byte[count * 2 + 4]; - - int len = count * 2 + 2; - result[0] = (byte)(len >> 8); - result[1] = (byte)(len & 0xFF); - result[2] = (byte)(count >> 8); - result[3] = (byte)(count & 0xFF); - - for (int i = 0; i < count; i++) { - byte value[] = registers[i].toBytes(); - result[i * 2 + 4] = value[0]; - result[i * 2 + 5] = value[1]; - } - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFileRecordRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFileRecordRequest.java deleted file mode 100644 index a0c646c..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFileRecordRequest.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.msg.ReadFileRecordResponse.RecordResponse; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.*; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Read File Record request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadFileRecordRequest extends ModbusRequest { - private RecordRequest[] records; - - /** - * Constructs a new Read File Record request instance. - */ - public ReadFileRecordRequest() { - super(); - - setFunctionCode(Modbus.READ_FILE_RECORD); - - // Request size byte is all that is required. - setDataLength(1); - } - - /** - * getRequestSize -- return the total request size. This is useful for - * determining if a new record can be added. - * - * @return size in bytes of response. - */ - public int getRequestSize() { - if (records == null) { - return 1; - } - - int size = 1; - for (RecordRequest record : records) { - size += record.getRequestSize(); - } - - return size; - } - - /** - * getRequestCount - * @return the number of record requests in this message - */ - public int getRequestCount() { - if (records == null) { - return 0; - } - - return records.length; - } - - /** - * getRecord - * @param index Reference - * @return the record request indicated by the reference - */ - public RecordRequest getRecord(int index) { - return records[index]; - } - - /** - * addRequest -- add a new record request. - * @param request Record request to add - */ - public void addRequest(RecordRequest request) { - if (request.getRequestSize() + getRequestSize() > 248) { - throw new IllegalArgumentException(); - } - - if (records == null) { - records = new RecordRequest[1]; - } - else { - RecordRequest old[] = records; - records = new RecordRequest[old.length + 1]; - - System.arraycopy(old, 0, records, 0, old.length); - } - records[records.length - 1] = request; - - setDataLength(getRequestSize()); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadFileRecordResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ReadFileRecordResponse response = (ReadFileRecordResponse)getResponse(); - - // Get the process image. - ProcessImage procimg = listener.getProcessImage(getUnitID()); - - // There is a list of requests to be resolved. - try { - for (int i = 0; i < getRequestCount(); i++) { - RecordRequest recordRequest = getRecord(i); - if (recordRequest.getFileNumber() < 0 || recordRequest.getFileNumber() >= procimg.getFileCount()) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - File file = procimg.getFileByNumber(recordRequest.getFileNumber()); - - if (recordRequest.getRecordNumber() < 0 || recordRequest.getRecordNumber() >= file.getRecordCount()) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - Record record = file.getRecord(recordRequest.getRecordNumber()); - int registers = recordRequest.getWordCount(); - if (record == null && registers != 0) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - short data[] = new short[registers]; - for (int j = 0; j < registers; j++) { - Register register = record.getRegister(j); - if (register == null) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - data[j] = register.toShort(); - } - RecordResponse recordResponse = new RecordResponse(data); - response.addResponse(recordResponse); - } - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - return response; - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- read all the data for this request. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - int byteCount = din.readUnsignedByte(); - - int recordCount = byteCount / 7; - records = new RecordRequest[recordCount]; - - for (int i = 0; i < recordCount; i++) { - if (din.readByte() != 6) { - throw new IOException(); - } - - int file = din.readUnsignedShort(); - int record = din.readUnsignedShort(); - if (record < 0 || record >= 10000) { - throw new IOException(); - } - - int count = din.readUnsignedShort(); - - records[i] = new RecordRequest(file, record, count); - } - } - - /** - * getMessage - * @return the PDU message - */ - public byte[] getMessage() { - byte request[] = new byte[1 + 7 * records.length]; - - int offset = 0; - request[offset++] = (byte)(request.length - 1); - - for (RecordRequest record : records) { - record.getRequest(request, offset); - offset += 7; - } - return request; - } - - public static class RecordRequest { - private int fileNumber; - private int recordNumber; - private int wordCount; - - public RecordRequest(int file, int record, int count) { - fileNumber = file; - recordNumber = record; - wordCount = count; - } - - public int getFileNumber() { - return fileNumber; - } - - public int getRecordNumber() { - return recordNumber; - } - - public int getWordCount() { - return wordCount; - } - - /** - * getRequestSize - * @return the size of the response in bytes - */ - public int getRequestSize() { - return 7 + wordCount * 2; - } - - public void getRequest(byte[] request, int offset) { - request[offset] = 6; - request[offset + 1] = (byte)(fileNumber >> 8); - request[offset + 2] = (byte)(fileNumber & 0xFF); - request[offset + 3] = (byte)(recordNumber >> 8); - request[offset + 4] = (byte)(recordNumber & 0xFF); - request[offset + 5] = (byte)(wordCount >> 8); - request[offset + 6] = (byte)(wordCount & 0xFF); - } - - public byte[] getRequest() { - byte[] request = new byte[7]; - - getRequest(request, 0); - - return request; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFileRecordResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFileRecordResponse.java deleted file mode 100644 index 9dc9054..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadFileRecordResponse.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.procimg.SimpleRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadFileRecordResponse. - * - * @author Julie (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadFileRecordResponse extends ModbusResponse { - - private RecordResponse[] records = null; - - /** - * Constructs a new ReadFileRecordResponse instance. - */ - public ReadFileRecordResponse() { - super(); - - setFunctionCode(Modbus.READ_FILE_RECORD); - } - - /** - * Returns the number of bytes needed for the response. - * - * The response is 1 byte for the total response size, plus - * the sum of the sizes of all the records in the response. - * - * @return the number of bytes in the response. - */ - public int getByteCount() { - if (records == null) { - return 1; - } - - int size = 1; - for (RecordResponse record : records) { - size += record.getResponseSize(); - } - - return size; - } - - /** - * getRecordCount -- return the number of records in the response. - * - * @return count of records in response. - */ - public int getRecordCount() { - if (records == null) { - return 0; - } - - return records.length; - } - - /** - * getRecord - * @param index Record to get - * @return the record response indicated by the reference - */ - public RecordResponse getRecord(int index) { - return records[index]; - } - - /** - * addResponse -- add a new record response. - * @param response Record response to add - */ - public void addResponse(RecordResponse response) { - if (records == null) { - records = new RecordResponse[1]; - } - else { - RecordResponse old[] = records; - records = new RecordResponse[old.length + 1]; - - System.arraycopy(old, 0, records, 0, old.length); - } - records[records.length - 1] = response; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeByte(getByteCount() - 1); - - if (records == null) { - return; - } - - for (RecordResponse record : records) { - dout.write(record.getResponse()); - } - } - - public void readData(DataInput din) throws IOException { - int byteCount = (din.readUnsignedByte() & 0xFF); - - int remainder = byteCount; - while (remainder > 0) { - int length = din.readUnsignedByte(); - remainder--; - - int function = din.readByte(); - remainder--; - - if (function != 6 || (length - 1) > remainder) { - throw new IOException("Invalid response format"); - } - short[] data = new short[(length - 1) / 2]; - for (int i = 0; i < data.length; i++) { - data[i] = din.readShort(); - remainder -= 2; - } - RecordResponse response = new RecordResponse(data); - addResponse(response); - } - setDataLength(byteCount + 1); - } - - public byte[] getMessage() { - byte result[]; - - result = new byte[getByteCount()]; - - int offset = 0; - result[offset++] = (byte)(result.length - 1); - - for (RecordResponse record : records) { - record.getResponse(result, offset); - offset += record.getWordCount() * 2; - } - return result; - } - - public static class RecordResponse { - private int wordCount; - private byte[] data; - - public RecordResponse(short data[]) { - wordCount = data.length; - this.data = new byte[wordCount * 2]; - - int offset = 0; - for (int i = 0; i < wordCount; i++) { - this.data[offset++] = (byte)(data[i] >> 8); - this.data[offset++] = (byte)(data[i] & 0xFF); - } - } - - public int getWordCount() { - return wordCount; - } - - public SimpleRegister getRegister(int register) { - if (register < 0 || register >= wordCount) { - throw new IndexOutOfBoundsException("0 <= " + register + " < " + wordCount); - } - byte b1 = data[register * 2]; - byte b2 = data[register * 2 + 1]; - - return new SimpleRegister(b1, b2); - } - - /** - * getResponseSize -- return the size of the response in bytes. - * - * The response is a byte count, a function code, then wordCount - * words (2 bytes). - * @return the size of the response in bytes - */ - public int getResponseSize() { - return 2 + (wordCount * 2); - } - - /** - * getResponse - return the response data for this record - * - * The response data is the byte size of the response, minus this - * byte, the function code (6), then the raw byte data for the - * registers (wordCount * 2 bytes). - * - * @param request Request message - * @param offset Offset into buffer - */ - public void getResponse(byte[] request, int offset) { - request[offset] = (byte)(1 + (wordCount * 2)); - request[offset + 1] = 6; - System.arraycopy(data, 0, request, offset + 2, data.length); - } - - public byte[] getResponse() { - byte[] request = new byte[getResponseSize()]; - getResponse(request, 0); - return request; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputDiscretesRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputDiscretesRequest.java deleted file mode 100644 index 8258e54..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputDiscretesRequest.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.DigitalIn; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadInputDiscretesRequest. The implementation - * directly correlates with the class 1 function read input discretes (FC - * 2). It encapsulates the corresponding request message. - *

- * Input Discretes are understood as bits that cannot be manipulated (i.e. set - * or unset). - * - * @author Dieter Wimberger - * @author jfhaugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadInputDiscretesRequest extends ModbusRequest { - - // instance attributes - private int reference; - private int bitCount; - - /** - * Constructs a new ReadInputDiscretesRequest instance. - */ - public ReadInputDiscretesRequest() { - super(); - - setFunctionCode(Modbus.READ_INPUT_DISCRETES); - - // Two bytes for count, two bytes for offset. - setDataLength(4); - } - - /** - * Constructs a new ReadInputDiscretesRequest instance with a given - * reference and count of input discretes (i.e. bits) to be read. - *

- * - * @param ref the reference number of the register to read from. - * @param count the number of bits to be read. - */ - public ReadInputDiscretesRequest(int ref, int count) { - super(); - - setFunctionCode(Modbus.READ_INPUT_DISCRETES); - // 4 bytes (unit id and function code is excluded) - setDataLength(4); - setReference(ref); - setBitCount(count); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadInputDiscretesResponse(getBitCount())); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ReadInputDiscretesResponse response; - DigitalIn[] dins; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - // 2. get input discretes range - try { - dins = procimg.getDigitalInRange(getReference(), getBitCount()); - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (ReadInputDiscretesResponse)getResponse(); - - // Populate the discrete values from the process image. - for (int i = 0; i < dins.length; i++) { - response.setDiscreteStatus(i, dins[i].isSet()); - } - - return response; - } - - /** - * Returns the reference of the discrete to to start reading from with - * this ReadInputDiscretesRequest. - * - * @return the reference of the discrete to start reading from as - * int. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register to start reading from with this - * ReadInputDiscretesRequest. - *

- * - * @param ref the reference of the register to start reading from. - */ - public void setReference(int ref) { - if (ref < 0 || bitCount + ref >= 65536) { - throw new IllegalArgumentException(); - } - - reference = ref; - } - - /** - * Returns the number of bits (i.e. input discretes) to be read with this - * ReadInputDiscretesRequest. - *

- * - * @return the number of bits to be read. - */ - public int getBitCount() { - return bitCount; - } - - /** - * Sets the number of bits (i.e. input discretes) to be read with this - * ReadInputDiscretesRequest. - * - * @param count the number of bits to be read. - */ - public void setBitCount(int count) { - if (count < 0 || count > 2000 || count + reference >= 65536) { - throw new IllegalArgumentException(); - } - - bitCount = count; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeShort(reference); - dout.writeShort(bitCount); - } - - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - bitCount = din.readUnsignedShort(); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)((reference & 0xff)); - result[2] = (byte)((bitCount >> 8) & 0xff); - result[3] = (byte)((bitCount & 0xff)); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputDiscretesResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputDiscretesResponse.java deleted file mode 100644 index c6cc891..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputDiscretesResponse.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.util.BitVector; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadInputDiscretesResponse. - * The implementation directly correlates with the class 1 - * function read input discretes (FC 2). It encapsulates - * the corresponding response message. - *

- * Input Discretes are understood as bits that cannot be - * manipulated (i.e. set or unset). - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadInputDiscretesResponse - extends ModbusResponse { - - //instance attributes - private int bitCount; - private BitVector discretes; - - /** - * Constructs a new ReadInputDiscretesResponse - * instance. - */ - public ReadInputDiscretesResponse() { - super(); - setFunctionCode(Modbus.READ_INPUT_DISCRETES); - } - - /** - * Constructs a new ReadInputDiscretesResponse - * instance with a given count of input discretes - * (i.e. bits). - * - * @param count the number of bits to be read. - */ - public ReadInputDiscretesResponse(int count) { - super(); - setFunctionCode(Modbus.READ_INPUT_DISCRETES); - setBitCount(count); - } - - /** - * Returns the number of bits (i.e. input discretes) - * read with the request. - * - * @return the number of bits that have been read. - */ - public int getBitCount() { - return bitCount; - } - - /** - * Sets the number of bits in this response. - * - * @param count the number of response bits as int. - */ - public void setBitCount(int count) { - bitCount = count; - discretes = new BitVector(count); - //set correct length, without counting unitid and fc - setDataLength(discretes.byteSize() + 1); - } - - /** - * Returns the BitVector that stores - * the collection of bits that have been read. - *

- * - * @return the BitVector holding the - * bits that have been read. - */ - public BitVector getDiscretes() { - return discretes; - } - - /** - * Convenience method that returns the state - * of the bit at the given index. - *

- * - * @param index the index of the input discrete - * for which the status should be returned. - * - * @return true if set, false otherwise. - * - * @throws IndexOutOfBoundsException if the - * index is out of bounds - */ - public boolean getDiscreteStatus(int index) throws IndexOutOfBoundsException { - - return discretes.getBit(index); - } - - /** - * Sets the status of the given input discrete. - * - * @param index the index of the input discrete to be set. - * @param b true if to be set, false if to be reset. - * - * @throws IndexOutOfBoundsException if the given index exceeds bounds. - */ - public void setDiscreteStatus(int index, boolean b) throws IndexOutOfBoundsException { - discretes.setBit(index, b); - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeByte(discretes.byteSize()); - dout.write(discretes.getBytes(), 0, discretes.byteSize()); - } - - public void readData(DataInput din) throws IOException { - - int count = din.readUnsignedByte(); - byte[] data = new byte[count]; - for (int k = 0; k < count; k++) { - data[k] = din.readByte(); - } - - //decode bytes into bitvector - discretes = BitVector.createBitVector(data); - if (discretes != null) { - bitCount = discretes.size(); - } - - //update data length - setDataLength(count + 1); - } - - public byte[] getMessage() { - byte result[]; - int len = 1 + discretes.byteSize(); - - result = new byte[len]; - result[0] = (byte)discretes.byteSize(); - System.arraycopy(discretes.getBytes(), 0, result, 1, discretes.byteSize()); - - return result; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputRegistersRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputRegistersRequest.java deleted file mode 100644 index ea13c81..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputRegistersRequest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadInputRegistersRequest. The implementation - * directly correlates with the class 0 function read multiple registers (FC - * 4). It encapsulates the corresponding request message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadInputRegistersRequest extends ModbusRequest { - - // instance attributes - private int reference; - private int wordCount; - - /** - * Constructs a new ReadInputRegistersRequest instance. - */ - public ReadInputRegistersRequest() { - super(); - - setFunctionCode(Modbus.READ_INPUT_REGISTERS); - // 4 bytes (unit id and function code is excluded) - setDataLength(4); - } - - /** - * Constructs a new ReadInputRegistersRequest instance with a given - * reference and count of words to be read. - *

- * - * @param ref the reference number of the register to read from. - * @param count the number of words to be read. - */ - public ReadInputRegistersRequest(int ref, int count) { - super(); - - setFunctionCode(Modbus.READ_INPUT_REGISTERS); - // 4 bytes (unit id and function code is excluded) - setDataLength(4); - - setReference(ref); - setWordCount(count); - } - - public ReadInputRegistersResponse getResponse() { - ReadInputRegistersResponse response = (ReadInputRegistersResponse)updateResponseWithHeader(new ReadInputRegistersResponse()); - response.setWordCount(getWordCount()); - return response; - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ReadInputRegistersResponse response; - InputRegister[] inpregs; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - // 2. get input registers range - try { - inpregs = procimg.getInputRegisterRange(getReference(), getWordCount()); - } - catch (IllegalAddressException iaex) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = getResponse(); - response.setRegisters(inpregs); - - return response; - } - - /** - * Returns the reference of the register to to start reading from with this - * ReadInputRegistersRequest. - *

- * - * @return the reference of the register to start reading from as - * int. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register to start reading from with this - * ReadInputRegistersRequest. - *

- * - * @param ref the reference of the register to start reading from. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * Returns the number of words to be read with this - * ReadInputRegistersRequest. - *

- * - * @return the number of words to be read as int. - */ - public int getWordCount() { - return wordCount; - } - - /** - * Sets the number of words to be read with this - * ReadInputRegistersRequest. - *

- * - * @param count the number of words to be read. - */ - public void setWordCount(int count) { - wordCount = count; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeShort(reference); - dout.writeShort(wordCount); - } - - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - wordCount = din.readUnsignedShort(); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - result[2] = (byte)((wordCount >> 8) & 0xff); - result[3] = (byte)(wordCount & 0xff); - - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputRegistersResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputRegistersResponse.java deleted file mode 100644 index 98549ec..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadInputRegistersResponse.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.procimg.SimpleInputRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Arrays; - -/** - * Class implementing a ReadInputRegistersRequest. The implementation - * directly correlates with the class 0 function read multiple registers (FC - * 4). It encapsulates the corresponding response message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadInputRegistersResponse extends ModbusResponse { - - // instance attributes - private int byteCount; - private InputRegister[] registers; - - /** - * Constructs a new ReadInputRegistersResponse instance. - */ - public ReadInputRegistersResponse() { - super(); - - setFunctionCode(Modbus.READ_INPUT_REGISTERS); - } - - /** - * Constructs a new ReadInputRegistersResponse instance. - * - * @param registers the InputRegister[] holding response input registers. - */ - public ReadInputRegistersResponse(InputRegister[] registers) { - super(); - - setFunctionCode(Modbus.READ_INPUT_REGISTERS); - setDataLength(registers == null ? 0 : (registers.length * 2 + 1)); - - this.registers = registers == null ? null : Arrays.copyOf(registers, registers.length); - byteCount = registers == null ? 0 : (registers.length * 2); - } - - /** - * Returns the number of bytes that have been read. - * - * @return the number of bytes that have been read as int. - */ - public int getByteCount() { - return byteCount; - } - - /** - * Returns the number of words that have been read. The returned value - * should be half as much as the byte count of the response. - * - * @return the number of words that have been read as int. - */ - public int getWordCount() { - return byteCount / 2; - } - - /** - * Set the number of words to be written. - * @param count Number of words in response - */ - public void setWordCount(int count) { - byteCount = count * 2; - } - - /** - * Returns the InputRegister at the given position (relative to the - * reference used in the request). - * - * @param index the relative index of the InputRegister. - * - * @return the register as InputRegister. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public InputRegister getRegister(int index) throws IndexOutOfBoundsException { - if (index < 0) { - throw new IndexOutOfBoundsException(index + " < 0"); - } - - if (index >= getWordCount()) { - throw new IndexOutOfBoundsException(index + " >= " + getWordCount()); - } - - return registers[index]; - } - - /** - * Returns the value of the register at the given position (relative to the - * reference used in the request) interpreted as usigned short. - * - * @param index the relative index of the register for which the value should - * be retrieved. - * - * @return the unsigned short value as an int. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public int getRegisterValue(int index) throws IndexOutOfBoundsException { - return getRegister(index).toUnsignedShort(); - } - - /** - * Returns a reference to the array of input registers read. - * - * @return a InputRegister[] instance. - */ - public synchronized InputRegister[] getRegisters() { - InputRegister[] dest = new InputRegister[registers.length]; - System.arraycopy(registers, 0, dest, 0, dest.length); - return dest; - } - - /** - * Sets the entire block of registers for this response - * @param registers Array of registers - */ - public void setRegisters(InputRegister[] registers) { - setDataLength(registers == null ? 0 : (registers.length * 2 + 1)); - this.registers = registers == null ? null : Arrays.copyOf(registers, registers.length); - byteCount = registers == null ? 0 : (registers.length * 2); - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeByte(byteCount); - - for (int k = 0; k < getWordCount(); k++) { - dout.write(registers[k].toBytes()); - } - } - - public void readData(DataInput din) throws IOException { - byteCount = din.readUnsignedByte(); - - InputRegister[] registers = new InputRegister[getWordCount()]; - for (int k = 0; k < getWordCount(); k++) { - registers[k] = new SimpleInputRegister(din.readByte(), din.readByte()); - } - this.registers = registers; - - setDataLength(byteCount); - } - - public byte[] getMessage() { - byte result[] = new byte[registers.length * 2 + 1]; - result[0] = (byte)(registers.length * 2); - - for (int i = 0; i < registers.length; i++) { - byte value[] = registers[i].toBytes(); - - result[1 + i * 2] = value[0]; - result[2 + i * 2] = value[1]; - } - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMEIRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMEIRequest.java deleted file mode 100644 index a40ea14..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMEIRequest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.EOFException; -import java.io.IOException; - -/** - * Class implementing a Read MEI Data request. - * - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadMEIRequest extends ModbusRequest { - - // instance attributes - private int subCode; - private int fieldLevel; - private int fieldId; - - /** - * Constructs a new Read MEI Data request instance. - */ - public ReadMEIRequest() { - super(); - - setFunctionCode(Modbus.READ_MEI); - subCode = 0x0E; - - // 3 bytes (unit id and function code is excluded) - setDataLength(3); - } - - /** - * Constructs a new Read MEI Data request instance with a given - * reference and count of coils (i.e. bits) to be read. - *

- * - * @param level the reference number of the register to read from. - * @param id the number of bits to be read. - */ - public ReadMEIRequest(int level, int id) { - super(); - - setFunctionCode(Modbus.READ_MEI); - subCode = 0x0E; - - // 3 bytes (unit id and function code is excluded) - setDataLength(3); - setLevel(level); - setFieldId(id); - } - - @Override - public ModbusResponse getResponse() { - - // Any other sub-function is an error. - if (getSubCode() != 0x0E) { - IllegalFunctionExceptionResponse error = new IllegalFunctionExceptionResponse(); - return updateResponseWithHeader(error); - } - return updateResponseWithHeader(new ReadMEIResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * Gets the MEI subcode associated with this request. - * @return The MEI sub code - */ - public int getSubCode() { - return subCode; - } - - /** - * Returns the reference of the register to to start reading from with this - * ReadCoilsRequest. - *

- * - * @return the reference of the register to start reading from as - * int. - */ - public int getLevel() { - return fieldLevel; - } - - /** - * Sets the reference of the register to start reading from with this - * ReadCoilsRequest. - *

- * - * @param level the reference of the register to start reading from. - */ - public void setLevel(int level) { - fieldLevel = level; - } - - /** - * Returns the number of bits (i.e. coils) to be read with this - * ReadCoilsRequest. - *

- * - * @return the number of bits to be read. - */ - public int getFieldId() { - return fieldId; - } - - /** - * Sets the number of bits (i.e. coils) to be read with this - * ReadCoilsRequest. - *

- * - * @param id the number of bits to be read. - */ - public void setFieldId(int id) { - fieldId = id; - } - - public void writeData(DataOutput dout) throws IOException { - byte results[] = new byte[3]; - - results[0] = (byte)subCode; - results[1] = (byte)fieldLevel; - results[2] = (byte)fieldId; - - dout.write(results); - } - - public void readData(DataInput din) throws IOException { - subCode = din.readUnsignedByte(); - - if (subCode != 0xE) { - try { - while (din.readByte() >= 0) { - } - } - catch (EOFException x) { - // do nothing. - } - return; - } - fieldLevel = din.readUnsignedByte(); - fieldId = din.readUnsignedByte(); - } - - public byte[] getMessage() { - byte results[] = new byte[3]; - - results[0] = (byte)subCode; - results[1] = (byte)fieldLevel; - results[2] = (byte)fieldId; - - return results; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMEIResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMEIResponse.java deleted file mode 100644 index 99e9556..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMEIResponse.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadMEIResponse. - * - * Derived from similar class for Read Coils response. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadMEIResponse extends ModbusResponse { - - private static final Logger logger = LoggerFactory.getLogger(ReadMEIResponse.class); - - //instance attributes - private int fieldLevel = 0; - private int conformity = 1; - private int fieldCount = 0; - private String fields[] = new String[64]; - private int fieldIds[] = new int[64]; - private boolean moreFollows = false; - private int nextFieldId; - - /** - * Constructs a new ReadMEIResponse - * instance. - */ - public ReadMEIResponse() { - super(); - setFunctionCode(Modbus.READ_MEI); - } - - /** - * Returns the number of fields - * read with the request. - *

- * - * @return the number of fields that have been read. - */ - public int getFieldCount() { - if (fields == null) { - return 0; - } - else { - return fields.length; - } - } - - /** - * Returns the array of strings that were read - * @return Array of the fields read - */ - public synchronized String[] getFields() { - String[] dest = new String[fields.length]; - System.arraycopy(fields, 0, dest, 0, dest.length); - return dest; - } - - /** - * Convenience method that returns the field - * at the requested index - *

- * - * @param index the index of the field which - * should be returned. - * - * @return requested field - * - * @throws IndexOutOfBoundsException if the - * index is out of bounds - */ - public String getField(int index) throws IndexOutOfBoundsException { - return fields[index]; - } - - /** - * Convenience method that returns the field - * ID at the given index. - *

- * - * @param index the index of the field for which - * the ID should be returned. - * - * @return field ID - * - * @throws IndexOutOfBoundsException if the - * index is out of bounds - */ - public int getFieldId(int index) throws IndexOutOfBoundsException { - return fieldIds[index]; - } - - public void setFieldLevel(int level) { - fieldLevel = level; - } - - public void addField(int id, String text) { - fieldIds[fieldCount] = id; - fields[fieldCount] = text; - fieldCount++; - } - - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - public void readData(DataInput din) throws IOException { - int byteCount; - - int subCode = din.readUnsignedByte(); - if (subCode != 0xE) { - throw new IOException("Invalid sub code"); - } - - fieldLevel = din.readUnsignedByte(); - conformity = din.readUnsignedByte(); - moreFollows = din.readUnsignedByte() == 0xFF; - nextFieldId = din.readUnsignedByte(); - - fieldCount = din.readUnsignedByte(); - - byteCount = 6; - - if (fieldCount > 0) { - fields = new String[fieldCount]; - fieldIds = new int[fieldCount]; - - for (int i = 0; i < fieldCount; i++) { - fieldIds[i] = din.readUnsignedByte(); - int len = din.readUnsignedByte(); - byte data[] = new byte[len]; - din.readFully(data); - fields[i] = new String(data, "UTF-8"); - - byteCount += 2 + len; - } - setDataLength(byteCount); - } - else { - setDataLength(byteCount); - } - } - - public byte[] getMessage() { - int size = 6; - - for (int i = 0; i < fieldCount; i++) { - // Add the field ID - size++; - - // Add the string length byte and the - // actual string length. - size++; - size += fields[i].length(); - } - - byte result[] = new byte[size]; - int offset = 0; - - result[offset++] = 0x0E; - result[offset++] = (byte)fieldLevel; - result[offset++] = (byte)conformity; - result[offset++] = (byte)(moreFollows ? 0xFF : 0); - result[offset++] = (byte)nextFieldId; - result[offset++] = (byte)fieldCount; - - for (int i = 0; i < fieldCount; i++) { - result[offset++] = (byte)fieldIds[i]; - result[offset++] = (byte)fields[i].length(); - try { - System.arraycopy(fields[i].getBytes("US-ASCII"), 0, result, offset, fields[i].length()); - } - catch (Exception e) { - logger.debug("Problem converting bytes to string - {}", e.getMessage()); - } - offset += fields[i].length(); - } - return result; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMultipleRegistersRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMultipleRegistersRequest.java deleted file mode 100644 index a34e3d0..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMultipleRegistersRequest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.procimg.Register; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadMultipleRegistersRequest. The - * implementation directly correlates with the class 0 function read multiple - * registers (FC 3). It encapsulates the corresponding request message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadMultipleRegistersRequest extends ModbusRequest { - - // instance attributes - private int reference; - private int wordCount; - - /** - * Constructs a new ReadMultipleRegistersRequest instance. - */ - public ReadMultipleRegistersRequest() { - super(); - - setFunctionCode(Modbus.READ_MULTIPLE_REGISTERS); - setDataLength(4); - } - - /** - * Constructs a new ReadMultipleRegistersRequest instance with a - * given reference and count of words to be read. This message reads - * from holding (r/w) registers. - * - * @param ref the reference number of the register to read from. - * @param count the number of words to be read. - * - * @see ReadInputRegistersRequest - */ - public ReadMultipleRegistersRequest(int ref, int count) { - super(); - - setFunctionCode(Modbus.READ_MULTIPLE_REGISTERS); - setDataLength(4); - - setReference(ref); - setWordCount(count); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadMultipleRegistersResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ReadMultipleRegistersResponse response; - Register[] regs; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - // 2. get input registers range - try { - regs = procimg.getRegisterRange(getReference(), getWordCount()); - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (ReadMultipleRegistersResponse)getResponse(); - response.setRegisters(regs); - - return response; - } - - /** - * Returns the reference of the register to to start reading from with this - * ReadMultipleRegistersRequest. - *

- * - * @return the reference of the register to start reading from as - * int. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register to start reading from with this - * ReadMultipleRegistersRequest. - *

- * - * @param ref the reference of the register to start reading from. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * Returns the number of words to be read with this - * ReadMultipleRegistersRequest. - *

- * - * @return the number of words to be read as int. - */ - public int getWordCount() { - return wordCount; - } - - /** - * Sets the number of words to be read with this - * ReadMultipleRegistersRequest. - *

- * - * @param count the number of words to be read. - */ - public void setWordCount(int count) { - wordCount = count; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeShort(reference); - dout.writeShort(wordCount); - } - - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - wordCount = din.readUnsignedShort(); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - result[2] = (byte)((wordCount >> 8) & 0xff); - result[3] = (byte)(wordCount & 0xff); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMultipleRegistersResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMultipleRegistersResponse.java deleted file mode 100644 index a84ebae..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadMultipleRegistersResponse.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.procimg.Register; -import com.ghgande.j2mod.modbus.procimg.SimpleRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Arrays; - -/** - * Class implementing a ReadMultipleRegistersResponse. The - * implementation directly correlates with the class 0 function read multiple - * registers (FC 3). It encapsulates the corresponding response message. - * - * @author Dieter Wimberger - * @author Julie (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadMultipleRegistersResponse extends ModbusResponse { - - // instance attributes - private int byteCount; - private Register[] registers; - - /** - * Constructs a new ReadMultipleRegistersResponse instance. - */ - public ReadMultipleRegistersResponse() { - super(); - setFunctionCode(Modbus.READ_MULTIPLE_REGISTERS); - } - - /** - * Constructs a new ReadInputRegistersResponse instance. - * - * @param registers the Register[] holding response registers. - */ - public ReadMultipleRegistersResponse(Register[] registers) { - super(); - - setFunctionCode(Modbus.READ_MULTIPLE_REGISTERS); - setDataLength(registers == null ? 0 : (registers.length * 2 + 1)); - - this.registers = registers == null ? null : Arrays.copyOf(registers, registers.length); - byteCount = registers == null ? 0 : (registers.length * 2); - } - - /** - * Returns the number of bytes that have been read. - * - * @return the number of bytes that have been read as int. - */ - public int getByteCount() { - return byteCount; - } - - /** - * Returns the number of words that have been read. The returned value - * should be half of the the byte count of this - * ReadMultipleRegistersResponse. - * - * @return the number of words that have been read as int. - */ - public int getWordCount() { - return byteCount / 2; - } - - /** - * Returns the Register at the given position (relative to the - * reference used in the request). - * - * @param index the relative index of the Register. - * - * @return the register as Register. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public Register getRegister(int index) { - if (registers == null) { - throw new IndexOutOfBoundsException("No registers defined!"); - } - - if (index < 0) { - throw new IndexOutOfBoundsException("Negative index: " + index); - } - - if (index >= getWordCount()) { - throw new IndexOutOfBoundsException(index + " > " + getWordCount()); - } - - return registers[index]; - } - - /** - * Returns the value of the register at the given position (relative to the - * reference used in the request) interpreted as unsigned short. - * - * @param index the relative index of the register for which the value should - * be retrieved. - * - * @return the value as int. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public int getRegisterValue(int index) throws IndexOutOfBoundsException { - return getRegister(index).toUnsignedShort(); - } - - /** - * Returns the reference to the array of registers read. - * - * @return a Register[] instance. - */ - public synchronized Register[] getRegisters() { - Register[] dest = new Register[registers.length]; - System.arraycopy(registers, 0, dest, 0, dest.length); - return dest; - } - - /** - * Sets the entire block of registers for this response - * @param registers Array of registers to use - */ - public void setRegisters(Register[] registers) { - byteCount = registers == null ? 0 : registers.length * 2; - this.registers = registers == null ? null : Arrays.copyOf(registers, registers.length); - setDataLength(byteCount + 1); - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeByte(byteCount); - - for (int k = 0; k < getWordCount(); k++) { - dout.write(registers[k].toBytes()); - } - } - - public void readData(DataInput din) throws IOException { - byteCount = din.readUnsignedByte(); - - registers = new Register[getWordCount()]; - - for (int k = 0; k < getWordCount(); k++) { - registers[k] = new SimpleRegister(din.readByte(), din.readByte()); - } - - setDataLength(byteCount + 1); - } - - public byte[] getMessage() { - byte result[]; - - result = new byte[getWordCount() * 2 + 1]; - - int offset = 0; - result[offset++] = (byte)byteCount; - - for (Register register : registers) { - byte[] data = register.toBytes(); - - result[offset++] = data[0]; - result[offset++] = data[1]; - } - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadSerialDiagnosticsRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadSerialDiagnosticsRequest.java deleted file mode 100644 index 8b05d75..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadSerialDiagnosticsRequest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadSerialDiagnosticsRequest. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadSerialDiagnosticsRequest extends ModbusRequest { - - // Message fields. - private int function; - private short data; - - /** - * Constructs a new Diagnostics request - * instance. - */ - public ReadSerialDiagnosticsRequest() { - super(); - - setFunctionCode(Modbus.READ_SERIAL_DIAGNOSTICS); - setDataLength(4); - } - - /** - * getFunction -- Get the DIAGNOSTICS sub-function. - * - * @return int - */ - public int getFunction() { - return function; - } - - /** - * setFunction - Set the DIAGNOSTICS sub-function. - * - * @param function - DIAGNOSTICS command sub-function. - */ - public void setFunction(int function) { - this.function = function; - data = 0; - } - - /** - * getWordCount -- get the number of words in data. - * @return Number of words in the data - */ - public int getWordCount() { - return 1; - } - - /** - * getData - * @return the first data item - */ - public int getData() { - return data; - } - - /** - * setData -- Set the optional data value - * @param value Diagnostics value - */ - public void setData(int value) { - data = (short)value; - } - - /** - * getData -- Get the data item at the index. - * - * @param index - Unused, must be 0. - * @return Data at index 0 - * - * @deprecated - */ - public int getData(int index) { - if (index != 0) { - throw new IndexOutOfBoundsException(); - } - return data; - } - - /** - * setData -- Set the data item at the index - * - * @param index - Unused, must be 0. - * @param value - Optional data value for function. - * - * @deprecated - */ - public void setData(int index, int value) { - if (index != 0) { - throw new IndexOutOfBoundsException(); - } - data = (short)value; - } - - @Override - public ModbusResponse getResponse() { - ReadSerialDiagnosticsResponse response = new ReadSerialDiagnosticsResponse(); - - // Copy the sub-function code. - response.setFunction(getFunction()); - - return updateResponseWithHeader(response); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- Read the function code and data value - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - function = din.readUnsignedShort(); - data = (short)(din.readShort() & 0xFFFF); - } - - /** - * getMessage -- Create the DIAGNOSTICS message paylaod. - * @return Response as byte array - */ - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)(function >> 8); - result[1] = (byte)(function & 0xFF); - result[2] = (byte)(data >> 8); - result[3] = (byte)(data & 0xFF); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadSerialDiagnosticsResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadSerialDiagnosticsResponse.java deleted file mode 100644 index 9d2bb8d..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadSerialDiagnosticsResponse.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadSerialDiagnosticsResponse. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadSerialDiagnosticsResponse extends ModbusResponse { - - // Message fields. - private int function; - private short data; - - /** - * Constructs a new Diagnostics response - * instance. - */ - public ReadSerialDiagnosticsResponse() { - super(); - - setFunctionCode(Modbus.READ_SERIAL_DIAGNOSTICS); - setDataLength(4); - } - - /** - * getFunction -- Get the DIAGNOSTICS sub-function. - * - * @return Function code - */ - public int getFunction() { - return function; - } - - /** - * setFunction - Set the DIAGNOSTICS sub-function. - * - * @param function - DIAGNOSTICS command sub-function. - */ - public void setFunction(int function) { - this.function = function; - data = 0; - } - - /** - * getWordCount -- get the number of words in data. - * @return Number of words in the data - */ - public int getWordCount() { - return 1; - } - - /** - * getData - * @return the first data item - */ - public int getData() { - return data; - } - - /** - * setData -- Set the optional data value - * @param value optional data value - */ - public void setData(int value) { - data = (short)value; - } - - /** - * getData -- Get the data item at the index. - * - * @param index - Unused, must be 0. - * @return Data at index 0 - * - * @deprecated - */ - public int getData(int index) { - if (index != 0) { - throw new IndexOutOfBoundsException(); - } - - return data; - } - - /** - * setData -- Set the data item at the index - * - * @param index - Unused, must be 0. - * @param value - Optional data value for function. - * - * @deprecated - */ - public void setData(int index, int value) { - if (index != 0) { - throw new IndexOutOfBoundsException(); - } - - data = (short)value; - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- Read the function code and data value - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - function = din.readUnsignedShort(); - data = (short)(din.readShort() & 0xFFFF); - } - - /** - * getMessage -- Create the DIAGNOSTICS message paylaod. - * @return message paylaod - */ - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)(function >> 8); - result[1] = (byte)(function & 0xFF); - result[2] = (byte)(data >> 8); - result[3] = (byte)(data & 0xFF); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadWriteMultipleRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadWriteMultipleRequest.java deleted file mode 100644 index 98b0e23..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadWriteMultipleRequest.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.NonWordDataHandler; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.*; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Arrays; - -/** - * Class implementing a Read / Write Multiple Registers request. - * - * @author Julie Haugh - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadWriteMultipleRequest extends ModbusRequest { - private NonWordDataHandler nonWordDataHandler; - private int readReference; - private int readCount; - private int writeReference; - private int writeCount; - private Register registers[]; - - /** - * Constructs a new Read/Write Multiple Registers Request instance. - * @param unit Unit ID - * @param readRef Register to read - * @param writeCount Number of registers to write - * @param writeRef Starting register to write - * @param readCount Number of registers to read - */ - public ReadWriteMultipleRequest(int unit, int readRef, int readCount, int writeRef, int writeCount) { - super(); - - setUnitID(unit); - setFunctionCode(Modbus.READ_WRITE_MULTIPLE); - - // There is no additional data in this request. - setDataLength(9 + writeCount * 2); - - readReference = readRef; - this.readCount = readCount; - writeReference = writeRef; - this.writeCount = writeCount; - registers = new Register[writeCount]; - for (int i = 0; i < writeCount; i++) { - registers[i] = new SimpleRegister(0); - } - } - - /** - * Constructs a new Read/Write Multiple Registers Request instance. - * @param unit Unit ID - */ - public ReadWriteMultipleRequest(int unit) { - super(); - - setUnitID(unit); - setFunctionCode(Modbus.READ_WRITE_MULTIPLE); - - // There is no additional data in this request. - setDataLength(9); - } - - /** - * Constructs a new Read/Write Multiple Registers Request instance. - */ - public ReadWriteMultipleRequest() { - super(); - - setFunctionCode(Modbus.READ_WRITE_MULTIPLE); - - // There is no additional data in this request. - setDataLength(9); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReadWriteMultipleResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - ReadWriteMultipleResponse response; - InputRegister[] readRegs; - Register[] writeRegs; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - - // 2. get input registers range - try { - // First the write - writeRegs = procimg.getRegisterRange(getWriteReference(), getWriteWordCount()); - for (int i = 0; i < writeRegs.length; i++) { - writeRegs[i].setValue(getRegister(i).getValue()); - } - - // And then the read - readRegs = procimg.getRegisterRange(getReadReference(), getReadWordCount()); - InputRegister[] dummy = new InputRegister[readRegs.length]; - for (int i = 0; i < readRegs.length; i++) { - dummy[i] = new SimpleInputRegister(readRegs[i].getValue()); - } - readRegs = dummy; - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (ReadWriteMultipleResponse)getResponse(); - response.setRegisters(readRegs); - - return response; - } - /** - * getReadReference - Returns the reference of the register to start writing - * to with this ReadWriteMultipleRequest. - *

- * - * @return the reference of the register to start writing to as int - * . - */ - public int getReadReference() { - return readReference; - } - - /** - * setReadReference - Sets the reference of the register to writing to with - * this ReadWriteMultipleRequest. - *

- * - * @param ref the reference of the register to start writing to as - * int. - */ - public void setReadReference(int ref) { - readReference = ref; - } - - /** - * getWriteReference - Returns the reference of the register to start - * writing to with this ReadWriteMultipleRequest. - *

- * - * @return the reference of the register to start writing to as int - * . - */ - public int getWriteReference() { - return writeReference; - } - - /** - * setWriteReference - Sets the reference of the register to write to with - * this ReadWriteMultipleRequest. - *

- * - * @param ref the reference of the register to start writing to as - * int. - */ - public void setWriteReference(int ref) { - writeReference = ref; - } - - /** - * getRegisters - Returns the registers to be written with this - * ReadWriteMultipleRequest. - *

- * - * @return the registers to be read as Register[]. - */ - public synchronized Register[] getRegisters() { - Register[] dest = new Register[registers.length]; - System.arraycopy(registers, 0, dest, 0, dest.length); - return dest; - } - - /** - * setRegisters - Sets the registers to be written with this - * ReadWriteMultipleRequest. - *

- * - * @param registers the registers to be written as Register[]. - */ - public void setRegisters(Register[] registers) { - writeCount = registers != null ? registers.length : 0; - this.registers = registers != null ? Arrays.copyOf(registers, registers.length) : null; - } - - /** - * getRegister - Returns the specified Register. - * - * @param index the index of the Register. - * - * @return the register as Register. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public Register getRegister(int index) throws IndexOutOfBoundsException { - if (index < 0) { - throw new IndexOutOfBoundsException(index + " < 0"); - } - - if (index >= getWriteWordCount()) { - throw new IndexOutOfBoundsException(index + " > " + getWriteWordCount()); - } - - return registers[index]; - } - - /** - * getReadRegisterValue - Returns the value of the specified register - * interpreted as unsigned short. - * - * @param index the relative index of the register for which the value should - * be retrieved. - * - * @return the value as int. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public int getReadRegisterValue(int index) throws IndexOutOfBoundsException { - return getRegister(index).toUnsignedShort(); - } - - /** - * getByteCount - Returns the number of bytes representing the values to be - * written. - * - * @return the number of bytes to be written as int. - */ - public int getByteCount() { - return getWriteWordCount() * 2; - } - - /** - * getWriteWordCount - Returns the number of words to be written. - * - * @return the number of words to be written as int. - */ - public int getWriteWordCount() { - return writeCount; - } - - /** - * setWriteWordCount - Sets the number of words to be written. - * - * @param count the number of words to be written as int. - */ - public void setWriteWordCount(int count) { - writeCount = count; - } - - /** - * getReadWordCount - Returns the number of words to be read. - * - * @return the number of words to be read as int. - */ - public int getReadWordCount() { - return readCount; - } - - /** - * setReadWordCount - Sets the number of words to be read. - * - * @param count the number of words to be read as int. - */ - public void setReadWordCount(int count) { - readCount = count; - } - - /** - * getNonWordDataHandler - Returns the actual non word data handler. - * - * @return the actual NonWordDataHandler. - */ - public NonWordDataHandler getNonWordDataHandler() { - return nonWordDataHandler; - } - - /** - * setNonWordDataHandler - Sets a non word data handler. A non-word data - * handler is responsible for converting words from a Modbus packet into the - * non-word values associated with the actual device's registers. - * - * @param dhandler a NonWordDataHandler instance. - */ - public void setNonWordDataHandler(NonWordDataHandler dhandler) { - nonWordDataHandler = dhandler; - } - - /** - * writeData -- output this Modbus message to dout. - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- read the values of the registers to be written, along with - * the reference and count for the registers to be read. - */ - public void readData(DataInput input) throws IOException { - readReference = input.readUnsignedShort(); - readCount = input.readUnsignedShort(); - writeReference = input.readUnsignedShort(); - writeCount = input.readUnsignedShort(); - int byteCount = input.readUnsignedByte(); - - if (nonWordDataHandler == null) { - byte buffer[] = new byte[byteCount]; - input.readFully(buffer, 0, byteCount); - - int offset = 0; - registers = new Register[writeCount]; - - for (int register = 0; register < writeCount; register++) { - registers[register] = new SimpleRegister(buffer[offset], buffer[offset + 1]); - offset += 2; - } - } - else { - nonWordDataHandler.readData(input, writeReference, writeCount); - } - } - - /** - * getMessage -- return a prepared message. - * @return prepared message - */ - public byte[] getMessage() { - byte results[] = new byte[9 + 2 * getWriteWordCount()]; - - results[0] = (byte)(readReference >> 8); - results[1] = (byte)(readReference & 0xFF); - results[2] = (byte)(readCount >> 8); - results[3] = (byte)(readCount & 0xFF); - results[4] = (byte)(writeReference >> 8); - results[5] = (byte)(writeReference & 0xFF); - results[6] = (byte)(writeCount >> 8); - results[7] = (byte)(writeCount & 0xFF); - results[8] = (byte)(writeCount * 2); - - int offset = 9; - for (int i = 0; i < writeCount; i++) { - Register reg = getRegister(i); - byte[] bytes = reg.toBytes(); - - results[offset++] = bytes[0]; - results[offset++] = bytes[1]; - } - return results; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadWriteMultipleResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadWriteMultipleResponse.java deleted file mode 100644 index e61526a..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReadWriteMultipleResponse.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.procimg.InputRegister; -import com.ghgande.j2mod.modbus.procimg.Register; -import com.ghgande.j2mod.modbus.procimg.SimpleRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Arrays; - -/** - * Class implementing a ReadWriteMultipleResponse. - * - * @author Julie (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReadWriteMultipleResponse extends ModbusResponse { - - private int byteCount; - private InputRegister[] registers; - - /** - * Constructs a new ReadWriteMultipleResponse instance. - * - * @param registers the Register[] holding response registers. - */ - public ReadWriteMultipleResponse(InputRegister[] registers) { - super(); - - setFunctionCode(Modbus.READ_WRITE_MULTIPLE); - setDataLength(registers.length * 2 + 1); - - this.registers = Arrays.copyOf(registers, registers.length); - byteCount = registers.length * 2; - } - - /** - * Constructs a new ReadWriteMultipleResponse instance. - * - * @param count the number of Register[] holding response registers. - */ - public ReadWriteMultipleResponse(int count) { - super(); - - setFunctionCode(Modbus.READ_WRITE_MULTIPLE); - setDataLength(count * 2 + 1); - - registers = new InputRegister[count]; - byteCount = count * 2; - } - - /** - * Constructs a new ReadWriteMultipleResponse instance. - */ - public ReadWriteMultipleResponse() { - super(); - - setFunctionCode(Modbus.READ_WRITE_MULTIPLE); - } - - /** - * Returns the number of bytes that have been read. - * - * @return the number of bytes that have been read as int. - */ - public int getByteCount() { - return byteCount; - } - - /** - * Returns the number of words that have been read. The returned value - * should be half of the the byte count of this - * ReadWriteMultipleResponse. - * - * @return the number of words that have been read as int. - */ - public int getWordCount() { - return byteCount / 2; - } - - /** - * Returns the Register at the given position (relative to the - * reference used in the request). - * - * @param index the relative index of the InputRegister. - * - * @return the register as InputRegister. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public InputRegister getRegister(int index) { - if (registers == null) { - throw new IndexOutOfBoundsException("No registers defined!"); - } - - if (index < 0) { - throw new IndexOutOfBoundsException("Negative index: " + index); - } - - if (index >= getWordCount()) { - throw new IndexOutOfBoundsException(index + " > " + getWordCount()); - } - - return registers[index]; - } - - /** - * Returns the value of the register at the given position (relative to the - * reference used in the request) interpreted as unsigned short. - * - * @param index the relative index of the register for which the value should - * be retrieved. - * - * @return the value as int. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public int getRegisterValue(int index) throws IndexOutOfBoundsException { - return getRegister(index).toUnsignedShort(); - } - - /** - * Returns the reference to the array of registers read. - * - * @return a InputRegister[] instance. - */ - public synchronized InputRegister[] getRegisters() { - InputRegister[] dest = new InputRegister[registers.length]; - System.arraycopy(registers, 0, dest, 0, dest.length); - return dest; - } - - /** - * Sets the entire block of registers for this response - * @param registers Array of registers - */ - public void setRegisters(InputRegister[] registers) { - byteCount = registers.length * 2; - setDataLength(byteCount + 1); - - this.registers = Arrays.copyOf(registers, registers.length); - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeByte(byteCount); - - for (int k = 0; k < getWordCount(); k++) { - dout.write(registers[k].toBytes()); - } - } - - public void readData(DataInput din) throws IOException { - byteCount = din.readUnsignedByte(); - - registers = new Register[getWordCount()]; - - for (int k = 0; k < getWordCount(); k++) { - registers[k] = new SimpleRegister(din.readByte(), din.readByte()); - } - - setDataLength(byteCount + 1); - } - - public byte[] getMessage() { - byte result[]; - - result = new byte[getWordCount() * 2 + 1]; - - int offset = 0; - result[offset++] = (byte)byteCount; - - for (InputRegister register : registers) { - byte[] data = register.toBytes(); - - result[offset++] = data[0]; - result[offset++] = data[1]; - } - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReportSlaveIDRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReportSlaveIDRequest.java deleted file mode 100644 index c5d6cd6..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReportSlaveIDRequest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Read MEI Data request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author jfhaugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReportSlaveIDRequest extends ModbusRequest { - - /** - * Constructs a new Report Slave ID request - * instance. - */ - public ReportSlaveIDRequest() { - super(); - - setFunctionCode(Modbus.REPORT_SLAVE_ID); - - // There is no additional data in this request. - setDataLength(0); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new ReportSlaveIDResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - return createExceptionResponse(Modbus.ILLEGAL_FUNCTION_EXCEPTION); - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- dummy function. There is no data with the request. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - } - - /** - * getMessage - * @return an empty array as there is no data for this request - */ - public byte[] getMessage() { - - return new byte[0]; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReportSlaveIDResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReportSlaveIDResponse.java deleted file mode 100644 index eaf41ee..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/ReportSlaveIDResponse.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a ReadMEIResponse. - * - * Derived from similar class for Read Coils response. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ReportSlaveIDResponse extends ModbusResponse { - - // Message fields. - int m_length; - byte m_data[]; - int m_status; - int m_slaveId; - - /** - * Constructs a new ReportSlaveIDResponse - * instance. - */ - public ReportSlaveIDResponse() { - super(); - setFunctionCode(Modbus.REPORT_SLAVE_ID); - } - - /** - * getSlaveID -- return the slave identifier field. - * @return slave identifier field - */ - public int getSlaveID() { - return m_slaveId; - } - - /** - * setSlaveID -- initialize the slave identifier when constructing - * a response message. - * @param unitID UnitID of the slave - */ - public void setSlaveID(int unitID) { - m_slaveId = unitID; - } - - /** - * getStatus -- get the slave's "run" status. - * - * @return boolean - */ - public boolean getStatus() { - return m_status != 0; - } - - /** - * setStatus -- initialize the slave's "run" status when constructing - * a response message. - * - * @param b Status value - */ - public void setStatus(boolean b) { - m_status = b ? 0xff : 0x00; - } - - /** - * getData -- get the device-depending data for the slave. - * - * @return byte array - */ - public byte[] getData() { - byte[] result = new byte[m_length - 2]; - System.arraycopy(m_data, 0, result, 0, m_length - 2); - - return result; - } - - /** - * setData -- initialize the slave's device dependent data when - * initializing a response. - * - * @param data byte array - */ - public void setData(byte[] data) { - // There are always two bytes of payload in the message -- the - // slave ID and the run status indicator. - if (data == null) { - m_length = 2; - m_data = new byte[0]; - - return; - } - - if (data.length > 249) { - throw new IllegalArgumentException("data length limit exceeded"); - } - - m_length = data.length + 2; - - m_data = new byte[data.length]; - System.arraycopy(data, 0, m_data, 0, data.length); - } - - /** - * writeData -- output the completed Modbus message to dout - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- input the Modbus message from din. If there was a - * header, such as for Modbus/TCP, it will have been read - * already. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - - // Get the size of any device-specific data. - m_length = din.readUnsignedByte(); - if (m_length < 2 || m_length > 255) { - return; - } - - // Get the run status and device identifier. - m_slaveId = din.readUnsignedByte(); - m_status = din.readUnsignedByte(); - - /* - * The device-specific data is two bytes shorter than the - * length read previously. That length includes the run status - * and slave ID. - */ - m_data = new byte[m_length - 2]; - if (m_length > 2) { - din.readFully(m_data, 0, m_length - 2); - } - } - - /** - * getMessage -- format the message into a byte array. - * @return Byte array of message - */ - public byte[] getMessage() { - byte result[] = new byte[3 + m_length]; - int offset = 0; - - result[offset++] = (byte)(m_length + 2); - result[offset++] = (byte)m_slaveId; - result[offset++] = (byte)m_status; - if (m_length > 0) { - System.arraycopy(m_data, 0, result, offset, m_length - 2); - } - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteCoilRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteCoilRequest.java deleted file mode 100644 index 67ac0af..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteCoilRequest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.DigitalOut; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteCoilRequest. The implementation directly - * correlates with the class 0 function write coil (FC 5). It - * encapsulates the corresponding request message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteCoilRequest extends ModbusRequest { - - // instance attributes - private int reference; - private boolean coil; - - /** - * Constructs a new WriteCoilRequest instance. - */ - public WriteCoilRequest() { - super(); - - setFunctionCode(Modbus.WRITE_COIL); - setDataLength(4); - } - - /** - * Constructs a new WriteCoilRequest instance with a given - * reference and state to be written. - * - * @param ref the reference number of the register to read from. - * @param b true if the coil should be set of false if it should be unset. - */ - public WriteCoilRequest(int ref, boolean b) { - super(); - - setFunctionCode(Modbus.WRITE_COIL); - setDataLength(4); - - setReference(ref); - setCoil(b); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new WriteCoilResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - WriteCoilResponse response; - DigitalOut dout; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - // 2. get coil - try { - dout = procimg.getDigitalOut(getReference()); - // 3. set coil - dout.set(getCoil()); - } - catch (IllegalAddressException iaex) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (WriteCoilResponse)getResponse(); - response.setReference(getReference()); - response.setCoil(getCoil()); - - return response; - } - - /** - * Returns the reference of the register of the coil that should be written - * to with this ReadCoilsRequest. - * - * @return the reference of the coil's register. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register of the coil that should be written to - * with this ReadCoilsRequest. - *

- * - * @param ref the reference of the coil's register. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * Returns the state that should be written with this - * WriteCoilRequest. - * - * @return true if the coil should be set of false if it should be unset. - */ - public boolean getCoil() { - return coil; - } - - /** - * Sets the state that should be written with this WriteCoilRequest. - * - * @param b true if the coil should be set of false if it should be unset. - */ - public void setCoil(boolean b) { - coil = b; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeShort(reference); - - if (coil) { - dout.write(Modbus.COIL_ON_BYTES, 0, 2); - } - else { - dout.write(Modbus.COIL_OFF_BYTES, 0, 2); - } - } - - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - - if (din.readByte() == Modbus.COIL_ON) { - coil = true; - } - else { - coil = false; - } - - // discard the next byte. - din.readByte(); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - if (coil) { - result[2] = Modbus.COIL_ON_BYTES[0]; - result[3] = Modbus.COIL_ON_BYTES[1]; - } - else { - result[2] = Modbus.COIL_OFF_BYTES[0]; - result[3] = Modbus.COIL_OFF_BYTES[1]; - } - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteCoilResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteCoilResponse.java deleted file mode 100644 index 81702c4..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteCoilResponse.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteCoilResponse. The implementation directly - * correlates with the class 0 function write coil (FC 5). It - * encapsulates the corresponding response message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteCoilResponse extends ModbusResponse { - private boolean coil = false; - private int reference; - - /** - * Constructs a new WriteCoilResponse instance. - */ - public WriteCoilResponse() { - super(); - - setFunctionCode(Modbus.WRITE_COIL); - setDataLength(4); - } - - /** - * Constructs a new WriteCoilResponse instance. - * - * @param reference the offset were writing was started from. - * @param b the state of the coil; true set, false reset. - */ - public WriteCoilResponse(int reference, boolean b) { - super(); - - setFunctionCode(Modbus.WRITE_COIL); - setDataLength(4); - - setReference(reference); - setCoil(b); - } - - /** - * Gets the state that has been returned in this WriteCoilRequest. - * - * @return true if the coil is set, false if unset. - */ - public boolean getCoil() { - return coil; - } - - /** - * Sets the state that has been returned in the raw response. - * - * @param b true if the coil should be set of false if it should be unset. - */ - public void setCoil(boolean b) { - coil = b; - } - - /** - * Returns the reference of the register of the coil that has been written - * to with the request. - *

- * - * @return the reference of the coil's register. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register of the coil that has been written to - * with the request. - *

- * - * @param ref the reference of the coil's register. - */ - public void setReference(int ref) { - reference = ref; - } - - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - public void readData(DataInput din) throws IOException { - byte data[] = new byte[4]; - din.readFully(data); - - setReference(((data[0] << 8) | (data[1] & 0xff))); - setCoil(data[2] == Modbus.COIL_ON); - - setDataLength(4); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - if (coil) { - result[2] = Modbus.COIL_ON_BYTES[0]; - result[3] = Modbus.COIL_ON_BYTES[1]; - } - else { - result[2] = Modbus.COIL_OFF_BYTES[0]; - result[3] = Modbus.COIL_OFF_BYTES[1]; - } - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteFileRecordRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteFileRecordRequest.java deleted file mode 100644 index 413a745..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteFileRecordRequest.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.msg.WriteFileRecordResponse.RecordResponse; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.*; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a Write File Record request. - * - * @author Julie Haugh (jfh@ghgande.com) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteFileRecordRequest extends ModbusRequest { - private RecordRequest[] records; - - /** - * Constructs a new Write File Record request - * instance. - */ - public WriteFileRecordRequest() { - super(); - - setFunctionCode(Modbus.WRITE_FILE_RECORD); - - // Set up space for the initial header. - setDataLength(1); - } - - /** - * getRequestSize -- return the total request size. This is useful - * for determining if a new record can be added. - * - * @return size in bytes of response. - */ - public int getRequestSize() { - if (records == null) { - return 1; - } - - int size = 1; - for (RecordRequest record : records) { - size += record.getRequestSize(); - } - - return size; - } - - /** - * getRequestCount -- return the number of record requests in this - * message. - * @return number of record requests in this message - */ - public int getRequestCount() { - if (records == null) { - return 0; - } - - return records.length; - } - - /** - * getRecord -- return the record request indicated by the reference - * @param reference Register reference - * @return the record request indicated by the reference - */ - public RecordRequest getRecord(int reference) { - return records[reference]; - } - - /** - * addRequest -- add a new record request. - * @param request Request record - */ - public void addRequest(RecordRequest request) { - if (request.getRequestSize() + getRequestSize() > 248) { - throw new IllegalArgumentException(); - } - - if (records == null) { - records = new RecordRequest[1]; - } - else { - RecordRequest old[] = records; - records = new RecordRequest[old.length + 1]; - - System.arraycopy(old, 0, records, 0, old.length); - } - records[records.length - 1] = request; - - setDataLength(getRequestSize()); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new WriteFileRecordResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - WriteFileRecordResponse response = (WriteFileRecordResponse)getResponse(); - - // Get the process image. - ProcessImage procimg = listener.getProcessImage(getUnitID()); - - // There is a list of requests to be resolved. - try { - for (int i = 0; i < getRequestCount(); i++) { - RecordRequest recordRequest = getRecord(i); - if (recordRequest.getFileNumber() < 0 || recordRequest.getFileNumber() >= procimg.getFileCount()) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - File file = procimg.getFileByNumber(recordRequest.getFileNumber()); - - if (recordRequest.getRecordNumber() < 0 || recordRequest.getRecordNumber() >= file.getRecordCount()) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - Record record = file.getRecord(recordRequest.getRecordNumber()); - int registers = recordRequest.getWordCount(); - if (record == null && registers != 0) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - short data[] = new short[registers]; - for (int j = 0; j < registers; j++) { - Register register = record.getRegister(j); - if (register == null) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - - register.setValue(recordRequest.getRegister(j).getValue()); - data[j] = recordRequest.getRegister(j).toShort(); - } - RecordResponse recordResponse = new RecordResponse(file.getFileNumber(), record == null ? 0 : record.getRecordNumber(), data); - response.addResponse(recordResponse); - } - } - catch (IllegalAddressException e) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - return response; - } - - /** - * writeData -- output this Modbus message to dout. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - /** - * readData -- convert the byte stream into a request. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - int byteCount = din.readUnsignedByte(); - - records = new RecordRequest[0]; - - for (int offset = 1; offset + 7 < byteCount; ) { - int function = din.readUnsignedByte(); - int file = din.readUnsignedShort(); - int record = din.readUnsignedShort(); - int count = din.readUnsignedShort(); - - offset += 7; - - if (function != 6) { - throw new IOException(); - } - - if (record < 0 || record >= 10000) { - throw new IOException(); - } - - if (count < 0 || count >= 126) { - throw new IOException(); - } - - short registers[] = new short[count]; - for (int j = 0; j < count; j++) { - registers[j] = din.readShort(); - offset += 2; - } - RecordRequest dummy[] = new RecordRequest[records.length + 1]; - if (records.length > 0) { - System.arraycopy(records, 0, dummy, 0, records.length); - } - - records = dummy; - records[records.length - 1] = new RecordRequest(file, record, registers); - } - } - - /** - * getMessage -- return the raw binary message. - * @return the raw binary message - */ - public byte[] getMessage() { - byte results[] = new byte[getRequestSize()]; - - results[0] = (byte)(getRequestSize() - 1); - - int offset = 1; - for (RecordRequest record : records) { - record.getRequest(results, offset); - offset += record.getRequestSize(); - } - return results; - } - - public static class RecordRequest { - private int fileNumber; - private int recordNumber; - private int wordCount; - private byte data[]; - - public RecordRequest(int file, int record, short[] values) { - fileNumber = file; - recordNumber = record; - wordCount = values.length; - data = new byte[wordCount * 2]; - - int offset = 0; - for (int i = 0; i < wordCount; i++) { - data[offset++] = (byte)(values[i] >> 8); - data[offset++] = (byte)(values[i] & 0xFF); - } - } - - public int getFileNumber() { - return fileNumber; - } - - public int getRecordNumber() { - return recordNumber; - } - - public int getWordCount() { - return wordCount; - } - - public SimpleRegister getRegister(int register) { - if (register < 0 || register >= wordCount) { - throw new IllegalAddressException("0 <= " + register + " < " + wordCount); - } - byte b1 = data[register * 2]; - byte b2 = data[register * 2 + 1]; - - return new SimpleRegister(b1, b2); - } - - /** - * getRequestSize -- return the size of the response in bytes. - * @return the size of the response in bytes - */ - public int getRequestSize() { - return 7 + wordCount * 2; - } - - public void getRequest(byte[] request, int offset) { - request[offset++] = 6; - request[offset++] = (byte)(fileNumber >> 8); - request[offset++] = (byte)(fileNumber & 0xFF); - request[offset++] = (byte)(recordNumber >> 8); - request[offset++] = (byte)(recordNumber & 0xFF); - request[offset++] = (byte)(wordCount >> 8); - request[offset++] = (byte)(wordCount & 0xFF); - - System.arraycopy(data, 0, request, offset, data.length); - } - - public byte[] getRequest() { - byte[] request = new byte[7 + 2 * wordCount]; - - getRequest(request, 0); - - return request; - } - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteFileRecordResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteFileRecordResponse.java deleted file mode 100644 index 3b3d5bc..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteFileRecordResponse.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.procimg.SimpleRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteFileRecordResponse. - * - * @author Julie - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteFileRecordResponse extends ModbusResponse { - private RecordResponse[] records; - - /** - * Constructs a new WriteFileRecordResponse instance. - */ - public WriteFileRecordResponse() { - super(); - - setFunctionCode(Modbus.WRITE_FILE_RECORD); - setDataLength(7); - } - - /** - * getRequestSize -- return the total request size. This is useful - * for determining if a new record can be added. - * - * @return size in bytes of response. - */ - public int getResponseSize() { - if (records == null) { - return 1; - } - - int size = 1; - for (RecordResponse record : records) { - size += record.getResponseSize(); - } - - return size; - } - - /** - * getRequestCount -- return the number of record requests in this - * message. - * @return the number of record requests in this message - */ - public int getRequestCount() { - if (records == null) { - return 0; - } - - return records.length; - } - - /** - * getRecord -- return the record request indicated by the reference - * @param index Record to get - * @return the record request indicated by the reference - */ - public RecordResponse getRecord(int index) { - return records[index]; - } - - /** - * addResponse -- add a new record response. - * @param response Add record response - */ - public void addResponse(RecordResponse response) { - if (response.getResponseSize() + getResponseSize() > 248) { - throw new IllegalArgumentException(); - } - - if (records == null) { - records = new RecordResponse[1]; - } - else { - RecordResponse old[] = records; - records = new RecordResponse[old.length + 1]; - - System.arraycopy(old, 0, records, 0, old.length); - } - records[records.length - 1] = response; - - setDataLength(getResponseSize()); - } - - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - public void readData(DataInput din) throws IOException { - int byteCount = din.readUnsignedByte(); - - records = new RecordResponse[0]; - - for (int offset = 1; offset + 7 < byteCount; ) { - int function = din.readUnsignedByte(); - int file = din.readUnsignedShort(); - int record = din.readUnsignedShort(); - int count = din.readUnsignedShort(); - - offset += 7; - - if (function != 6) { - throw new IOException(); - } - - if (record < 0 || record >= 10000) { - throw new IOException(); - } - - if (count < 0 || count >= 126) { - throw new IOException(); - } - - short registers[] = new short[count]; - for (int j = 0; j < count; j++) { - registers[j] = din.readShort(); - offset += 2; - } - RecordResponse dummy[] = new RecordResponse[records.length + 1]; - if (records.length > 0) { - System.arraycopy(records, 0, dummy, 0, records.length); - } - - records = dummy; - records[records.length - 1] = new RecordResponse(file, record, registers); - } - } - - public byte[] getMessage() { - byte results[] = new byte[getResponseSize()]; - - results[0] = (byte)(getResponseSize() - 1); - - int offset = 1; - for (RecordResponse record : records) { - record.getResponse(results, offset); - offset += record.getResponseSize(); - } - return results; - } - - public static class RecordResponse { - private int fileNumber; - private int recordNumber; - private int wordCount; - private byte data[]; - - public RecordResponse(int file, int record, short[] values) { - fileNumber = file; - recordNumber = record; - wordCount = values.length; - data = new byte[wordCount * 2]; - - int offset = 0; - for (int i = 0; i < wordCount; i++) { - data[offset++] = (byte)(values[i] >> 8); - data[offset++] = (byte)(values[i] & 0xFF); - } - } - - public int getFileNumber() { - return fileNumber; - } - - public int getRecordNumber() { - return recordNumber; - } - - public int getWordCount() { - return wordCount; - } - - public SimpleRegister getRegister(int register) { - if (register < 0 || register >= wordCount) { - throw new IndexOutOfBoundsException("0 <= " + register + " < " + wordCount); - } - byte b1 = data[register * 2]; - byte b2 = data[register * 2 + 1]; - - return new SimpleRegister(b1, b2); - } - - /** - * getResponseSize -- return the size of the response in bytes. - * @return the size of the response in bytes - */ - public int getResponseSize() { - return 7 + wordCount * 2; - } - - public void getResponse(byte[] response, int offset) { - response[offset++] = 6; - response[offset++] = (byte)(fileNumber >> 8); - response[offset++] = (byte)(fileNumber & 0xFF); - response[offset++] = (byte)(recordNumber >> 8); - response[offset++] = (byte)(recordNumber & 0xFF); - response[offset++] = (byte)(wordCount >> 8); - response[offset++] = (byte)(wordCount & 0xFF); - - System.arraycopy(data, 0, response, offset, data.length); - } - - public byte[] getResponse() { - byte[] response = new byte[7 + 2 * wordCount]; - - getResponse(response, 0); - - return response; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleCoilsRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleCoilsRequest.java deleted file mode 100644 index 4658cf6..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleCoilsRequest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.DigitalOut; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.util.BitVector; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteMultipleCoilsRequest. The implementation - * directly correlates with the class 1 function write multiple coils (FC - * 15). It encapsulates the corresponding request message. - * - *

- * Coils are understood as bits that can be manipulated (i.e. set or cleared). - *

- * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteMultipleCoilsRequest extends ModbusRequest { - - // instance attributes - private int reference; - private BitVector coils; - - /** - * Constructs a new WriteMultipleCoilsRequest instance with the - * given reference and coil values. - * - * @param ref the index of the first coil to be written. - * @param bv the coil values to be written. - */ - public WriteMultipleCoilsRequest(int ref, BitVector bv) { - super(); - - setFunctionCode(Modbus.WRITE_MULTIPLE_COILS); - setDataLength(bv.byteSize() + 5); - - setReference(ref); - coils = bv; - } - - /** - * Constructs a new WriteMultipleCoilsRequest instance with a given - * reference and count of coils to be written, followed by the actual byte - * count, and then count number of bytes. - * - * @param ref the index of the first coil to be written. - * @param count the number of coils to be written. - */ - public WriteMultipleCoilsRequest(int ref, int count) { - super(); - - setFunctionCode(Modbus.WRITE_MULTIPLE_COILS); - setDataLength((count + 7) / 8 + 5); - - setReference(ref); - coils = new BitVector(count); - } - - /** - * Constructs a new WriteMultipleCoilsRequest instance. - * - *

- * A minimal message contains the reference to the first coil as a - * short, the number of coils as a short, and not less - * than one byte of coil data. - */ - public WriteMultipleCoilsRequest() { - super(); - - setFunctionCode(Modbus.WRITE_MULTIPLE_COILS); - setDataLength(5); - - coils = new BitVector(1); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new WriteMultipleCoilsResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - WriteMultipleCoilsResponse response; - DigitalOut douts[]; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - // 2. get coil range - try { - douts = procimg.getDigitalOutRange(reference, coils.size()); - // 3. set coils - for (int i = 0; i < douts.length; i++) { - douts[i].set(coils.getBit(i)); - } - } - catch (IllegalAddressException iaex) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (WriteMultipleCoilsResponse)getResponse(); - response.setBitCount(coils.size()); - response.setReference(reference); - - return response; - } - - /** - * getReference - Returns the reference of the coil to to start writing to - * with this WriteMultipleCoilsRequest. - * - * @return the reference of the coil to start writing to as an int. - */ - public int getReference() { - return reference; - } - - /** - * setReference - Sets the reference of the coil to start writing to with - * this WriteMultipleCoilsRequest. - * - * @param ref the reference of the coil to start writing to. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * getBitCount - Returns the number of coils written with the request. - * - * @return the number of coils that have been written. - */ - public int getBitCount() { - if (coils == null) { - return 0; - } - else { - return coils.size(); - } - } - - /** - * getByteCount - Returns the number of bytes required for packing the - * coils. - * - * @return the number of bytes required for packing the coils. - */ - public int getByteCount() { - return coils.byteSize(); - } - - /** - * getCoilStatus - Returns the status of the specified coil. - * - * @param index the index of the coil to be tested. - * - * @return true if set, false otherwise. - * - * @throws IndexOutOfBoundsException if the given index is out of bounds. - */ - public boolean getCoilStatus(int index) throws IndexOutOfBoundsException { - return coils.getBit(index); - } - - /** - * setCoilStatus - Sets the status of the specified coil. - * - * @param index the index of the coil to be set/reset. - * @param b true if to be set, false for reset. - * - * @throws IndexOutOfBoundsException if the given index is out of bounds. - */ - public void setCoilStatus(int index, boolean b) throws IndexOutOfBoundsException { - coils.setBit(index, b); - } - - /** - * getCoils - Returns the BitVector instance holding coil status - * information. - * - * @return the coils status as a BitVector instance. - */ - public BitVector getCoils() { - return coils; - } - - /** - * setCoils - Sets the BitVector instance holding coil status - * information. - * - * @param bv a BitVector instance holding coil status info. - */ - public void setCoils(BitVector bv) { - coils = bv; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeShort(reference); - dout.writeShort(coils.size()); - - dout.writeByte(coils.byteSize()); - dout.write(coils.getBytes()); - } - - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - int bitcount = din.readUnsignedShort(); - int coilBytes = din.readUnsignedByte(); - byte[] data = new byte[coilBytes]; - - for (int k = 0; k < coilBytes; k++) { - data[k] = din.readByte(); - } - - // decode bytes into BitVector, sets data and bitcount - coils = BitVector.createBitVector(data, bitcount); - - // update data length - setDataLength(coilBytes + 5); - } - - public byte[] getMessage() { - int len = coils.byteSize() + 5; - byte result[] = new byte[len]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - - result[2] = (byte)((coils.size() >> 8) & 0xff); - result[3] = (byte)(coils.size() & 0xff); - - result[4] = (byte)coils.byteSize(); - - System.arraycopy(coils.getBytes(), 0, result, 5, coils.byteSize()); - - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleCoilsResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleCoilsResponse.java deleted file mode 100644 index 7288618..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleCoilsResponse.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteMultipleCoilsResponse. The implementation - * directly correlates with the class 1 function write multiple coils (FC - * 15). It encapsulates the corresponding response message. - *

- * Coils are understood as bits that can be manipulated (i.e. set or cleared). - * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteMultipleCoilsResponse extends ModbusResponse { - - // instance attributes - private int reference; - private int bitCount; - - /** - * Constructs a new WriteMultipleCoilsResponse instance with a - * given count of coils and starting reference. - *

- * - * @param ref the offset to begin writing from. - * @param count the number of coils to be written. - */ - public WriteMultipleCoilsResponse(int ref, int count) { - super(); - reference = ref; - bitCount = count; - setDataLength(4); - } - - /** - * Constructs a new WriteMultipleCoilsResponse instance. - */ - public WriteMultipleCoilsResponse() { - super(); - setDataLength(4); - } - - /** - * getReference - Returns the reference of the coil to start reading from - * with this WriteMultipleCoilsResponse. - *

- * - * @return the reference of the coil to start reading from as int. - */ - public int getReference() { - return reference; - } - - /** - * setReference - Sets the reference to the coil that is the first coil in - * this response. - * - * @param ref Rgister address of coil - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * getBitCount - Returns the quantity of coils written with the request. - *

- * - * @return the quantity of coils that have been written. - */ - public int getBitCount() { - return bitCount; - } - - /** - * setBitCount - Sets the number of coils that will be in a response. - * - * @param count the number of coils in the response. - */ - public void setBitCount(int count) { - bitCount = count; - } - - /** - * writeData - Copy the attribute values for this message to the output - * buffer. - * @throws IOException If the data cannot be written - */ - public void writeData(DataOutput dout) throws IOException { - - dout.writeShort(reference); - dout.writeShort(bitCount); - } - - /** - * readData - Initialize the attribute values for this message from the - * input buffer. - * @throws IOException If the data cannot be read - */ - public void readData(DataInput din) throws IOException { - - reference = din.readUnsignedShort(); - bitCount = din.readUnsignedShort(); - } - - public byte[] getMessage() { - byte results[] = new byte[4]; - - results[0] = (byte)((reference >> 8) & 0xff); - results[1] = (byte)(reference & 0xff); - results[2] = (byte)((bitCount >> 8) & 0xff); - results[3] = (byte)(bitCount & 0xff); - - return results; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleRegistersRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleRegistersRequest.java deleted file mode 100644 index 6d7c32e..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleRegistersRequest.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.NonWordDataHandler; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.procimg.Register; -import com.ghgande.j2mod.modbus.procimg.SimpleRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Arrays; - -/** - * Class implementing a WriteMultipleRegistersRequest. The - * implementation directly correlates with the class 0 function write - * multiple registers (FC 16). It encapsulates the corresponding request - * message. - * - * @author Dieter Wimberger - * @author jfhaugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteMultipleRegistersRequest extends ModbusRequest { - private int reference; - private Register[] registers; - private NonWordDataHandler nonWordDataHandler = null; - - /** - * Constructs a new WriteMultipleRegistersRequest instance with a - * given starting reference and values to be written. - *

- * - * @param first -- the address of the first register to write to. - * @param registers -- the registers to be written. - */ - public WriteMultipleRegistersRequest(int first, Register[] registers) { - setFunctionCode(Modbus.WRITE_MULTIPLE_REGISTERS); - - setReference(first); - setRegisters(registers); - } - - /** - * Constructs a new WriteMultipleRegistersRequest instance. - */ - public WriteMultipleRegistersRequest() { - setFunctionCode(Modbus.WRITE_MULTIPLE_REGISTERS); - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new WriteMultipleRegistersResponse()); - } - - /** - * createResponse - Returns the WriteMultipleRegistersResponse that - * represents the answer to this WriteMultipleRegistersRequest. - * - * The implementation should take care about assembling the reply to this - * WriteMultipleRegistersRequest. - * - * This method is used to create responses from the process image associated - * with the listener. It is commonly used to implement Modbus - * slave instances. - * - * @return the corresponding ModbusResponse. - *

- * - * createResponse() must be able to handle the case where the word - * data that is in the response is actually non-word data. That is, - * where the slave device has data which are not actually - * short values in the range of registers being processed. - */ - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - WriteMultipleRegistersResponse response; - - if (nonWordDataHandler == null) { - Register[] regs; - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - // 2. get registers - try { - regs = procimg.getRegisterRange(getReference(), getWordCount()); - // 3. set Register values - for (int i = 0; i < regs.length; i++) { - regs[i].setValue(this.getRegister(i).getValue()); - } - } - catch (IllegalAddressException iaex) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - response = (WriteMultipleRegistersResponse)getResponse(); - response.setReference(getReference()); - response.setWordCount(getWordCount()); - } - else { - int result = nonWordDataHandler.commitUpdate(); - if (result > 0) { - return createExceptionResponse(result); - } - - response = (WriteMultipleRegistersResponse)getResponse(); - response.setReference(getReference()); - response.setWordCount(nonWordDataHandler.getWordCount()); - } - - return response; - } - - /** - * setReference - Returns the reference of the register to start writing to - * with this WriteMultipleRegistersRequest. - *

- * - * @return the reference of the register to start writing to as int - * . - */ - public int getReference() { - return reference; - } - - /** - * setReference - Sets the reference of the register to write to with this - * WriteMultipleRegistersRequest. - *

- * - * @param ref the reference of the register to start writing to as an - * int. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * getRegisters - Returns the registers to be written with this - * WriteMultipleRegistersRequest. - *

- * - * @return the registers to be written as Register[]. - */ - public synchronized Register[] getRegisters() { - Register[] dest = new Register[registers.length]; - System.arraycopy(registers, 0, dest, 0, dest.length); - return dest; - } - - /** - * setRegisters - Sets the registers to be written with this - * WriteMultipleRegistersRequest. - *

- * - * @param registers the registers to be written as Register[]. - */ - public void setRegisters(Register[] registers) { - this.registers = registers == null ? null : Arrays.copyOf(registers, registers.length); - } - - /** - * getRegister - Returns the Register at the given position. - * - * @param index the relative index of the Register. - * - * @return the register as Register. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public Register getRegister(int index) throws IndexOutOfBoundsException { - if (index < 0) { - throw new IndexOutOfBoundsException(index + " < 0"); - } - - if (index >= getWordCount()) { - throw new IndexOutOfBoundsException(index + " > " + getWordCount()); - } - - return registers[index]; - } - - /** - * getRegisterValue - Returns the value of the specified register. - *

- * - * @param index the index of the desired register. - * - * @return the value as an int. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public int getRegisterValue(int index) throws IndexOutOfBoundsException { - return getRegister(index).toUnsignedShort(); - } - - /** - * getByteCount - Returns the number of bytes representing the values to be - * written. - *

- * - * @return the number of bytes to be written as int. - */ - public int getByteCount() { - return getWordCount() * 2; - } - - /** - * getWordCount - Returns the number of words to be written. - * - * @return the number of words to be written as int. - */ - public int getWordCount() { - if (registers == null) { - return 0; - } - - return registers.length; - } - - /** - * getNonWordDataHandler - Returns the actual non word data handler. - * - * @return the actual NonWordDataHandler. - */ - public NonWordDataHandler getNonWordDataHandler() { - return nonWordDataHandler; - } - - /** - * setNonWordHandler - Sets a non word data handler. A non-word data handler - * is responsible for converting words from a Modbus packet into the - * non-word values associated with the actual device's registers. - * - * @param dhandler a NonWordDataHandler instance. - */ - public void setNonWordDataHandler(NonWordDataHandler dhandler) { - nonWordDataHandler = dhandler; - } - - public void writeData(DataOutput output) throws IOException { - output.write(getMessage()); - } - - public void readData(DataInput input) throws IOException { - reference = input.readUnsignedShort(); - int registerCount = input.readUnsignedShort(); - int byteCount = input.readUnsignedByte(); - - if (nonWordDataHandler == null) { - byte buffer[] = new byte[byteCount]; - input.readFully(buffer, 0, byteCount); - - int offset = 0; - registers = new Register[registerCount]; - - for (int register = 0; register < registerCount; register++) { - registers[register] = new SimpleRegister(buffer[offset], buffer[offset + 1]); - offset += 2; - } - } - else { - nonWordDataHandler.readData(input, reference, registerCount); - } - } - - public byte[] getMessage() { - int len = 5; - - if (registers != null) { - len += registers.length * 2; - } - - byte result[] = new byte[len]; - int registerCount = registers != null ? registers.length : 0; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - result[2] = (byte)((registerCount >> 8) & 0xff); - result[3] = (byte)(registerCount & 0xff); - result[4] = (byte)(registerCount * 2); - - int offset = 5; - - if (nonWordDataHandler == null) { - for (int i = 0; i < registerCount; i++) { - byte bytes[] = registers[i].toBytes(); - result[offset++] = bytes[0]; - result[offset++] = bytes[1]; - } - } - else { - nonWordDataHandler.prepareData(reference, registerCount); - byte bytes[] = nonWordDataHandler.getData(); - if (bytes != null) { - int nonWordBytes = bytes.length; - if (nonWordBytes > registerCount * 2) { - nonWordBytes = registerCount * 2; - } - - System.arraycopy(bytes, 0, result, offset, nonWordBytes); - } - } - return result; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleRegistersResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleRegistersResponse.java deleted file mode 100644 index 846585f..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteMultipleRegistersResponse.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteMultipleRegistersResponse. The - * implementation directly correlates with the class 0 function read multiple - * registers (FC 16). It encapsulates the corresponding response message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteMultipleRegistersResponse extends ModbusResponse { - // instance attributes - private int wordCount; - private int reference; - - /** - * Constructs a new WriteMultipleRegistersResponse instance. - */ - public WriteMultipleRegistersResponse() { - super(); - - setFunctionCode(Modbus.WRITE_MULTIPLE_REGISTERS); - setDataLength(4); - } - - /** - * Constructs a new WriteMultipleRegistersResponse instance. - * - * @param reference the offset to start reading from. - * @param wordCount the number of words (registers) to be read. - */ - public WriteMultipleRegistersResponse(int reference, int wordCount) { - super(); - - setFunctionCode(Modbus.WRITE_MULTIPLE_REGISTERS); - setDataLength(4); - - this.reference = reference; - this.wordCount = wordCount; - } - - /** - * Returns the reference of the register to start writing to with this - * WriteMultipleRegistersResponse. - *

- * - * @return the reference of the register to start writing to as int - * . - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register to start writing to with this - * WriteMultipleRegistersResponse. - *

- * - * @param ref the reference of the register to start writing to as - * int. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * Returns the number of bytes that have been written. - * - * @return the number of bytes that have been read as int. - */ - public int getByteCount() { - return wordCount * 2; - } - - /** - * Returns the number of words that have been read. The returned value - * should be half of the byte count of the response. - *

- * - * @return the number of words that have been read as int. - */ - public int getWordCount() { - return wordCount; - } - - /** - * Sets the number of words that have been returned. - * - * @param count the number of words as int. - */ - public void setWordCount(int count) { - wordCount = count; - } - - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - public void readData(DataInput din) throws IOException { - setReference(din.readUnsignedShort()); - setWordCount(din.readUnsignedShort()); - - setDataLength(4); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - result[2] = (byte)((wordCount >> 8) & 0xff); - result[3] = (byte)(wordCount & 0xff); - - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteSingleRegisterRequest.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteSingleRegisterRequest.java deleted file mode 100644 index f8036cf..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteSingleRegisterRequest.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.procimg.IllegalAddressException; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.procimg.Register; -import com.ghgande.j2mod.modbus.procimg.SimpleRegister; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteSingleRegisterRequest. The implementation - * directly correlates with the class 0 function write single register (FC - * 6). It encapsulates the corresponding request message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteSingleRegisterRequest extends ModbusRequest { - - // instance attributes - private int reference; - private Register register; - - /** - * Constructs a new WriteSingleRegisterRequest instance. - */ - public WriteSingleRegisterRequest() { - super(); - - setFunctionCode(Modbus.WRITE_SINGLE_REGISTER); - setDataLength(4); - } - - /** - * Constructs a new WriteSingleRegisterRequest instance with a - * given reference and value to be written. - * - * @param ref the reference number of the register to read from. - * @param reg the register containing the data to be written. - */ - public WriteSingleRegisterRequest(int ref, Register reg) { - super(); - - setFunctionCode(Modbus.WRITE_SINGLE_REGISTER); - setDataLength(4); - - reference = ref; - register = reg; - } - - @Override - public ModbusResponse getResponse() { - return updateResponseWithHeader(new WriteSingleRegisterResponse()); - } - - @Override - public ModbusResponse createResponse(AbstractModbusListener listener) { - Register reg; - - // 1. get process image - ProcessImage procimg = listener.getProcessImage(getUnitID()); - - // 2. get register - try { - reg = procimg.getRegister(reference); - - // 3. set Register - reg.setValue(register.toBytes()); - } - catch (IllegalAddressException iaex) { - return createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - } - return updateResponseWithHeader(new WriteSingleRegisterResponse(this.getReference(), reg.getValue())); - } - - /** - * Returns the reference of the register to be written to with this - * WriteSingleRegisterRequest. - * - * @return the reference of the register to be written to. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register to be written to with this - * WriteSingleRegisterRequest. - * - * @param ref the reference of the register to be written to. - */ - public void setReference(int ref) { - reference = ref; - } - - /** - * Returns the register to be written with this - * WriteSingleRegisterRequest. - * - * @return the value to be written to the register. - */ - public Register getRegister() { - return register; - } - - /** - * Sets the value that should be written to the register with this - * WriteSingleRegisterRequest. - * - * @param reg the register to be written. - */ - public void setRegister(Register reg) { - register = reg; - } - - public void writeData(DataOutput dout) throws IOException { - dout.writeShort(reference); - dout.write(register.toBytes()); - } - - public void readData(DataInput din) throws IOException { - reference = din.readUnsignedShort(); - register = new SimpleRegister(din.readByte(), din.readByte()); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - result[2] = (byte)((register.getValue() >> 8) & 0xff); - result[3] = (byte)(register.getValue() & 0xff); - - return result; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteSingleRegisterResponse.java b/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteSingleRegisterResponse.java deleted file mode 100644 index e5fee12..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/msg/WriteSingleRegisterResponse.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.msg; - -import com.ghgande.j2mod.modbus.Modbus; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Class implementing a WriteSingleRegisterResponse. - * The implementation directly correlates with the class 0 - * function write single register (FC 6). It - * encapsulates the corresponding response message. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class WriteSingleRegisterResponse - extends ModbusResponse { - - //instance attributes - private int reference; - private int registerValue; - - /** - * Constructs a new WriteSingleRegisterResponse - * instance. - */ - public WriteSingleRegisterResponse() { - super(); - setDataLength(4); - setFunctionCode(Modbus.WRITE_SINGLE_REGISTER); - } - - /** - * Constructs a new WriteSingleRegisterResponse - * instance. - * - * @param reference the offset of the register written. - * @param value the value of the register. - */ - public WriteSingleRegisterResponse(int reference, int value) { - super(); - setReference(reference); - setRegisterValue(value); - setDataLength(4); - setFunctionCode(Modbus.WRITE_SINGLE_REGISTER); - } - - /** - * Returns the value that has been returned in - * this WriteSingleRegisterResponse. - *

- * - * @return the value of the register. - */ - public int getRegisterValue() { - return registerValue; - } - - /** - * Sets the value that has been returned in the - * response message. - *

- * - * @param value the returned register value. - */ - private void setRegisterValue(int value) { - registerValue = value; - } - - /** - * Returns the reference of the register - * that has been written to. - *

- * - * @return the reference of the written register. - */ - public int getReference() { - return reference; - } - - /** - * Sets the reference of the register that has - * been written to. - *

- * - * @param ref the reference of the written register. - */ - private void setReference(int ref) { - reference = ref; - //setChanged(true); - } - - public void writeData(DataOutput dout) throws IOException { - dout.write(getMessage()); - } - - public void readData(DataInput din) throws IOException { - setReference(din.readUnsignedShort()); - setRegisterValue(din.readUnsignedShort()); - //update data length - setDataLength(4); - } - - public byte[] getMessage() { - byte result[] = new byte[4]; - - result[0] = (byte)((reference >> 8) & 0xff); - result[1] = (byte)(reference & 0xff); - result[2] = (byte)((registerValue >> 8) & 0xff); - result[3] = (byte)(registerValue & 0xff); - - return result; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractModbusListener.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractModbusListener.java deleted file mode 100644 index 7334ed0..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractModbusListener.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import com.ghgande.j2mod.modbus.msg.ModbusRequest; -import com.ghgande.j2mod.modbus.msg.ModbusResponse; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.slave.ModbusSlave; -import com.ghgande.j2mod.modbus.slave.ModbusSlaveFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; - -/** - * Definition of a listener class - * - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class AbstractModbusListener implements Runnable { - - private static final Logger logger = LoggerFactory.getLogger(AbstractModbusListener.class); - protected int port = Modbus.DEFAULT_PORT; - protected boolean listening; - protected InetAddress address; - protected String error; - protected int timeout = Modbus.DEFAULT_TIMEOUT; - - /** - * Main execution loop for this Modbus interface listener - this is called by - * starting the main listening thread - */ - public abstract void run(); - - /** - * Stop the listener thread for this ModbusListener instance. - */ - public abstract void stop(); - - /** - * Sets the port to be listened to. - * - * @param port the number of the IP port as int. - */ - public void setPort(int port) { - this.port = ((port > 0) ? port : Modbus.DEFAULT_PORT); - } - - /** - * Returns the port being listened on - * - * @return Port number > 0 - */ - public int getPort() { - return port; - } - - /** - * Sets the address of the interface to be listened to. - * - * @param addr an InetAddress instance. - */ - public void setAddress(InetAddress addr) { - address = addr; - } - - /** - * Returns the address bound to this socket - * - * @return Bound address - */ - public InetAddress getAddress() { - return address; - } - - /** - * Tests if this ModbusTCPListener is listening and accepting - * incoming connections. - * - * @return true if listening (and accepting incoming connections), false - * otherwise. - */ - public boolean isListening() { - return listening; - } - - /** - * Set the listening state of this ModbusTCPListener object. - * A ModbusTCPListener will silently drop any requests if the - * listening state is set to false. - * - * @param b listening state - */ - public void setListening(boolean b) { - listening = b; - } - - /** - * Returns any startup errors that may have aoccurred - * - * @return Error string - */ - public String getError() { - return error; - } - - /** - * Get the socket timeout - * - * @return Socket timeout in milliseconds - */ - public int getTimeout() { - return timeout; - } - - /** - * Sets the socket timeout - * - * @param timeout Timeout in milliseconds - */ - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - /** - * Reads the request, checks it is valid and that the unit ID is ok - * and sends back a response - * - * @param transport Transport to read request from - * @param listener Listener that the request was received by - * @throws ModbusIOException If there is an issue with the transport or transmission - */ - void handleRequest(AbstractModbusTransport transport, AbstractModbusListener listener) throws ModbusIOException { - - // Get the request from the transport. It will be processed - // using an associated process image - - if (transport == null) { - throw new ModbusIOException("No transport specified"); - } - ModbusRequest request = transport.readRequest(listener); - if (request == null) { - throw new ModbusIOException("Request for transport %s is invalid (null)", transport.getClass().getSimpleName()); - } - ModbusResponse response; - - // Test if Process image exists for this Unit ID - ProcessImage spi = getProcessImage(request.getUnitID()); - if (spi == null) { - response = request.createExceptionResponse(Modbus.ILLEGAL_ADDRESS_EXCEPTION); - response.setAuxiliaryType(ModbusResponse.AuxiliaryMessageTypes.UNIT_ID_MISSMATCH); - } - else { - response = request.createResponse(this); - } - if (logger.isDebugEnabled()) { - logger.debug("Request:{}", request.getHexMessage()); - logger.debug("Response:{}", response.getHexMessage()); - } - - // Write the response - transport.writeResponse(response); - } - - /** - * Returns the related process image for this listener and Unit Id - * - * @param unitId Unit ID - * @return Process image associated with this listener and Unit ID - */ - public ProcessImage getProcessImage(int unitId) { - ModbusSlave slave = ModbusSlaveFactory.getSlave(this); - if (slave != null) { - return slave.getProcessImage(unitId); - } - return null; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractSerialConnection.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractSerialConnection.java deleted file mode 100644 index 60346ea..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractSerialConnection.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; - -import java.io.IOException; -import java.util.Set; - -/** - * Interface that represents a public abstract serial port connection - * - * @author Felipe Herranz - * @version 2.0 (March 2016) - */ -public abstract class AbstractSerialConnection { - - /** - * Parity values - */ - public static final int NO_PARITY = 0; - public static final int ODD_PARITY = 1; - public static final int EVEN_PARITY = 2; - public static final int MARK_PARITY = 3; - public static final int SPACE_PARITY = 4; - - /** - * Stop bits values - */ - public static final int ONE_STOP_BIT = 1; - public static final int ONE_POINT_FIVE_STOP_BITS = 2; - public static final int TWO_STOP_BITS = 3; - - /** - * Flow control values - */ - public static final int FLOW_CONTROL_DISABLED = 0; - public static final int FLOW_CONTROL_RTS_ENABLED = 1; - public static final int FLOW_CONTROL_CTS_ENABLED = 16; - public static final int FLOW_CONTROL_DSR_ENABLED = 256; - public static final int FLOW_CONTROL_DTR_ENABLED = 4096; - public static final int FLOW_CONTROL_XONXOFF_IN_ENABLED = 65536; - public static final int FLOW_CONTROL_XONXOFF_OUT_ENABLED = 1048576; - - /** - * Open delay (msec) - */ - public static final int OPEN_DELAY = 0; - - /** - * Timeout - */ - static final public int TIMEOUT_NONBLOCKING = 0x00000000; - static final public int TIMEOUT_READ_SEMI_BLOCKING = 0x00000001; - static final public int TIMEOUT_WRITE_SEMI_BLOCKING = 0x00000010; - static final public int TIMEOUT_READ_BLOCKING = 0x00000100; - static final public int TIMEOUT_WRITE_BLOCKING = 0x00001000; - static final public int TIMEOUT_SCANNER = 0x00010000; - - /** - * Returns the ModbusTransport instance to be used for receiving - * and sending messages. - * - * @throws IOException If the port is not available or cannot be opened - */ - public abstract void open() throws IOException; - - /** - * Returns the ModbusTransport instance to be used for receiving - * and sending messages. - * - * @return a ModbusTransport instance. - */ - public abstract AbstractModbusTransport getModbusTransport(); - - /** - * Read a specified number of bytes from the serial port - * - * @param buffer Buffer to recieve bytes from the port - * @param bytesToRead Number of bytes to read - * @return number of currently bytes read. - */ - public abstract int readBytes(byte[] buffer, long bytesToRead); - - /** - * Write a specified number of bytes to the serial port - * - * @param buffer Bytes to send to the port - * @param bytesToWrite How many bytes to send - * @return number of currently bytes written - */ - public abstract int writeBytes(byte[] buffer, long bytesToWrite); - - /** - * Bytes available to read - * - * @return number of bytes currently available to read - */ - public abstract int bytesAvailable(); - - /** - * Sets the connection parameters to the setting in the parameters object. - * If set fails return the parameters object to original settings and throw - * exception. - */ - public abstract void setConnectionParameters(); - - /** - * Close the port and clean up associated elements. - */ - public abstract void close(); - - /** - * Returns current baud rate - * - * @return Baud rate - */ - public abstract int getBaudRate(); - - /** - * Set new baud rate - * - * @param newBaudRate Baud rate - */ - public abstract void setBaudRate(int newBaudRate); - - /** - * Returns current data bits value - * - * @return Number of data bits - */ - public abstract int getNumDataBits(); - - /** - * Returns current stop bits - * - * @return Number of stop bits - */ - public abstract int getNumStopBits(); - - /** - * Returns current parity - * - * @return Parity type - */ - public abstract int getParity(); - - /** - * Returns a descriptive name of the current port - * - * @return a String instance. - */ - public abstract String getDescriptivePortName(); - - /** - * Set port timeouts - * - * @param newTimeoutMode Timeout mode - * @param newReadTimeout Read timeout - * @param newWriteTimeout Write timeout - */ - public abstract void setComPortTimeouts(int newTimeoutMode, int newReadTimeout, int newWriteTimeout); - - /** - * Reports the open status of the port. - * - * @return true if port is open, false if port is closed. - */ - public abstract boolean isOpen(); - - /** - * Returns the timeout for this UDPMasterConnection. - * - * @return the timeout as int. - */ - public abstract int getTimeout(); - - /** - * Sets the timeout for this UDPMasterConnection. - * - * @param timeout the timeout as int. - */ - public abstract void setTimeout(int timeout); - - /** - * Returns a set of all the available comm port names - * - * @return Set of comm port names - */ - public abstract Set getCommPorts(); - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractUDPTerminal.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractUDPTerminal.java deleted file mode 100644 index 106b7d3..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/AbstractUDPTerminal.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.ModbusUDPTransport; - -import java.net.DatagramSocket; -import java.net.InetAddress; - -/** - * Interface defining a UDPTerminal. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class AbstractUDPTerminal { - - protected InetAddress address; - protected ModbusUDPTransport transport; - protected boolean active; - protected int port = Modbus.DEFAULT_PORT; - protected int timeout = Modbus.DEFAULT_TIMEOUT; - protected DatagramSocket socket; - - /** - * Gets the local adapter address - * - * @return Adapter address - */ - public InetAddress getAddress() { - return address; - } - - /** - * Returns the local port the terminal is listening on - * - * @return Port number - */ - public synchronized int getPort() { - return port; - } - - /** - * Sets the local port the terminal is running on - * - * @param port Local port - */ - protected synchronized void setPort(int port) { - this.port = port; - } - - /** - * Tests if this UDPSlaveTerminal is active. - * - * @return true if active, false otherwise. - */ - public boolean isActive() { - return active; - } - - /** - * Sets the timeout in milliseconds for this UDPSlaveTerminal. - * - * @param timeout the timeout as int. - */ - public synchronized void setTimeout(int timeout) { - this.timeout = timeout; - } - - /** - * Get the transport - * @return Transport - */ - public ModbusUDPTransport getTransport() { - return transport; - } - - /** - * Activate this UDPTerminal. - * - * @throws Exception if there is a network failure. - */ - public abstract void activate() throws Exception; - - /** - * Deactivates this UDPTerminal. - */ - public abstract void deactivate(); - - /** - * Sends the given message. - * - * @param msg the message as byte[]. - * - * @throws Exception if sending the message fails. - */ - public abstract void sendMessage(byte[] msg) throws Exception; - - /** - * Receives and returns a message. - * - * @return the message as a newly allocated byte[]. - * - * @throws Exception if receiving a message fails. - */ - public abstract byte[] receiveMessage() throws Exception; - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/ModbusTCPListener.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/ModbusTCPListener.java deleted file mode 100644 index 7403d5b..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/ModbusTCPListener.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.util.ThreadPool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.*; - -/** - * Class that implements a ModbusTCPListener. - *

- * If listening, it accepts incoming requests passing them on to be handled. - * If not listening, silently drops the requests. - * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusTCPListener extends AbstractModbusListener { - - private static final Logger logger = LoggerFactory.getLogger(ModbusTCPListener.class); - - private ServerSocket serverSocket = null; - private ThreadPool threadPool; - private Thread listener; - private boolean useRtuOverTcp; - - /** - * Constructs a ModbusTCPListener instance.
- * - * @param poolsize the size of the ThreadPool used to handle incoming - * requests. - * @param addr the interface to use for listening. - */ - public ModbusTCPListener(int poolsize, InetAddress addr) { - this(poolsize, addr, false); - } - - /** - * Constructs a ModbusTCPListener instance.
- * - * @param poolsize the size of the ThreadPool used to handle incoming - * requests. - * @param addr the interface to use for listening. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - */ - public ModbusTCPListener(int poolsize, InetAddress addr, boolean useRtuOverTcp) { - threadPool = new ThreadPool(poolsize); - address = addr; - this.useRtuOverTcp = useRtuOverTcp; - } - - /** - * /** - * Constructs a ModbusTCPListener instance. This interface is created - * to listen on the wildcard address (0.0.0.0), which will accept TCP packets - * on all available adapters/interfaces - * - * @param poolsize the size of the ThreadPool used to handle incoming - * requests. - */ - public ModbusTCPListener(int poolsize) { - this(poolsize, false); - } - - /** - * /** - * Constructs a ModbusTCPListener instance. This interface is created - * to listen on the wildcard address (0.0.0.0), which will accept TCP packets - * on all available adapters/interfaces - * - * @param poolsize the size of the ThreadPool used to handle incoming - * requests. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - */ - public ModbusTCPListener(int poolsize, boolean useRtuOverTcp) { - threadPool = new ThreadPool(poolsize); - try { - address = InetAddress.getByAddress(new byte[]{0, 0, 0, 0}); - } - catch (UnknownHostException ex) { - // Can't happen -- size is fixed. - } - this.useRtuOverTcp = useRtuOverTcp; - } - - @Override - public void setTimeout(int timeout) { - super.setTimeout(timeout); - if (serverSocket != null && listening) { - try { - serverSocket.setSoTimeout(timeout); - } - catch (SocketException e) { - logger.error("Cannot set socket timeout", e); - } - } - } - - @Override - public void run() { - try { - /* - * A server socket is opened with a connectivity queue of a size - * specified in int floodProtection. Concurrent login handling under - * normal circumstances should be alright, denial of service - * attacks via massive parallel program logins can probably be - * prevented. - */ - int floodProtection = 100; - serverSocket = new ServerSocket(port, floodProtection, address); - serverSocket.setSoTimeout(timeout); - logger.debug("Listening to {} (Port {})", serverSocket.toString(), port); - } - - // Catch any fatal errors and set the listening flag to false to indicate an error - catch (Exception e) { - error = String.format("Cannot start TCP listener - %s", e.getMessage()); - listening = false; - return; - } - - listener = Thread.currentThread(); - listening = true; - try { - - // Infinite loop, taking care of resources in case of a lot of - // parallel logins - while (listening) { - Socket incoming; - try { - incoming = serverSocket.accept(); - } - catch (SocketTimeoutException e) { - continue; - } - logger.debug("Making new connection {}", incoming.toString()); - if (listening) { - TCPSlaveConnection slave = new TCPSlaveConnection(incoming, useRtuOverTcp); - slave.setTimeout(timeout); - threadPool.execute(new TCPConnectionHandler(this, slave)); - } - else { - incoming.close(); - } - } - } - catch (IOException e) { - error = String.format("Problem starting listener - %s", e.getMessage()); - } - } - - @Override - public void stop() { - listening = false; - try { - if (serverSocket != null) { - serverSocket.close(); - } - if (listener != null) { - listener.join(); - } - if (threadPool != null) { - threadPool.close(); - } - } - catch (Exception ex) { - logger.error("Error while stopping ModbusTCPListener", ex); - } - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/ModbusUDPListener.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/ModbusUDPListener.java deleted file mode 100644 index 9dbca0a..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/ModbusUDPListener.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.io.ModbusUDPTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Class that implements a ModbusUDPListener.
- * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusUDPListener extends AbstractModbusListener { - - private static final Logger logger = LoggerFactory.getLogger(ModbusUDPListener.class); - private UDPSlaveTerminal terminal; - - /** - * Create a new ModbusUDPListener instance listening to the given - * interface address. - * - * @param ifc an InetAddress instance. - */ - public ModbusUDPListener(InetAddress ifc) { - address = ifc; - listening = true; - } - - /** - * Constructs a new ModbusUDPListener instance. The address will be set to a - * default value of the wildcard local address and the default Modbus port. - */ - public ModbusUDPListener() { - try { - address = InetAddress.getByAddress(new byte[]{0, 0, 0, 0}); - } - catch (UnknownHostException e) { - // Can't happen -- length is fixed by code. - } - } - - @Override - public void setTimeout(int timeout) { - super.setTimeout(timeout); - if (terminal != null && listening) { - terminal.setTimeout(timeout); - } - } - - /** - * Starts this ModbusUDPListener. - */ - @Override - public void run() { - ModbusUDPTransport transport; - try { - if (address == null) { - terminal = new UDPSlaveTerminal(InetAddress.getByAddress(new byte[]{0, 0, 0, 0})); - } - else { - terminal = new UDPSlaveTerminal(address); - } - terminal.setTimeout(timeout); - terminal.setPort(port); - terminal.activate(); - transport = new ModbusUDPTransport(terminal); - } - - // Catch any fatal errors and set the listening flag to false to indicate an error - catch (Exception e) { - error = String.format("Cannot start UDP listener - %s", e.getMessage()); - listening = false; - return; - } - - listening = true; - try { - while (listening) { - handleRequest(transport, this); - } - } - catch (ModbusIOException ex1) { - if (!ex1.isEOF()) { - logger.error("Exception occurred before EOF while handling request", ex1); - } - } - finally { - try { - terminal.deactivate(); - transport.close(); - } - catch (Exception ex) { - // ignore - } - } - } - - @Override - public void stop() { - terminal.deactivate(); - listening = false; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPConnectionHandler.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPConnectionHandler.java deleted file mode 100644 index 805bc20..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPConnectionHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.ModbusIOException; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class implementing a handler for incoming Modbus/TCP requests. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class TCPConnectionHandler implements Runnable { - - private static final Logger logger = LoggerFactory.getLogger(TCPConnectionHandler.class); - - private TCPSlaveConnection connection; - private AbstractModbusTransport transport; - private AbstractModbusListener listener; - - /** - * Constructs a new TCPConnectionHandler instance. - * - *

- * The connections will be handling using the ModbusCouple class - * and a ProcessImage which provides the interface between the - * slave implementation and the TCPSlaveConnection. - * - * @param listener the listener that handled the incoming request - * @param connection an incoming connection. - */ - public TCPConnectionHandler(AbstractModbusListener listener, TCPSlaveConnection connection) { - this.listener = listener; - this.connection = connection; - transport = this.connection.getModbusTransport(); - } - - @Override - public void run() { - try { - do { - listener.handleRequest(transport, listener); - } while (!Thread.currentThread().isInterrupted()); - } - catch (ModbusIOException ex) { - if (!ex.isEOF()) { - logger.debug(ex.getMessage()); - } - } - finally { - connection.close(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPMasterConnection.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPMasterConnection.java deleted file mode 100644 index 07a8885..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPMasterConnection.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import com.ghgande.j2mod.modbus.io.ModbusRTUTCPTransport; -import com.ghgande.j2mod.modbus.io.ModbusTCPTransport; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; - -/** - * Class that implements a TCPMasterConnection. - * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class TCPMasterConnection { - - private static final Logger logger = LoggerFactory.getLogger(TCPMasterConnection.class); - - // instance attributes - private Socket socket; - private int timeout = Modbus.DEFAULT_TIMEOUT; - private boolean connected; - - private InetAddress address; - private int port = Modbus.DEFAULT_PORT; - - private ModbusTCPTransport transport; - - private boolean useRtuOverTcp = false; - - /** - * useUrgentData - sent a byte of urgent data when testing the TCP - * connection. - */ - private boolean useUrgentData = false; - - /** - * Constructs a TCPMasterConnection instance with a given - * destination address. - * - * @param adr the destination InetAddress. - */ - public TCPMasterConnection(InetAddress adr) { - address = adr; - } - - /** - * Prepares the associated ModbusTransport of this - * TCPMasterConnection for use. - * - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * - * @throws IOException if an I/O related error occurs. - */ - private void prepareTransport(boolean useRtuOverTcp) throws IOException { - - // If we don't have a transport, or the transport type has changed - if (transport == null || (this.useRtuOverTcp != useRtuOverTcp)) { - - // Save the flag to tell us which transport type to use - this.useRtuOverTcp = useRtuOverTcp; - - // Select the correct transport - if (useRtuOverTcp) { - logger.trace("prepareTransport() -> using RTU over TCP transport."); - transport = new ModbusRTUTCPTransport(socket); - transport.setMaster(this); - } - else { - logger.trace("prepareTransport() -> using standard TCP transport."); - transport = new ModbusTCPTransport(socket); - transport.setMaster(this); - } - } - else { - logger.trace("prepareTransport() -> using custom transport: {}", transport.getClass().getSimpleName()); - transport.setSocket(socket); - } - transport.setTimeout(timeout); - } - - /** - * Opens this TCPMasterConnection. - * - * @throws Exception if there is a network failure. - */ - public synchronized void connect() throws Exception { - connect(useRtuOverTcp); - } - - /** - * Opens this TCPMasterConnection. - * - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * - * @throws Exception if there is a network failure. - */ - public synchronized void connect(boolean useRtuOverTcp) throws Exception { - if (!isConnected()) { - logger.debug("connect()"); - - // Create a socket without auto-connecting - - socket = new Socket(); - socket.setReuseAddress(true); - socket.setSoLinger(true, 1); - socket.setKeepAlive(true); - setTimeout(timeout); - - // Connect - only wait for the timeout number of milliseconds - - socket.connect(new InetSocketAddress(address, port), timeout); - - // Prepare the transport - - prepareTransport(useRtuOverTcp); - connected = true; - } - } - - /** - * Tests if this TCPMasterConnection is connected. - * - * @return true if connected, false otherwise. - */ - public synchronized boolean isConnected() { - if (connected && socket != null) { - if (!socket.isConnected() || socket.isClosed() || socket.isInputShutdown() || socket.isOutputShutdown()) { - try { - socket.close(); - } - catch (IOException e) { - logger.error("Socket exception", e); - } - finally { - connected = false; - } - } - else { - /* - * When useUrgentData is set, a byte of urgent data - * will be sent to the server to test the connection. If - * the connection is actually broken, an IException will - * occur and the connection will be closed. - * - * Note: RFC 6093 has decreed that we stop using urgent - * data. - */ - if (useUrgentData) { - try { - socket.sendUrgentData(0); - ModbusUtil.sleep(5); - } - catch (IOException e) { - connected = false; - try { - socket.close(); - } - catch (IOException e1) { - // Do nothing. - } - } - } - } - } - return connected; - } - - /** - * Closes this TCPMasterConnection. - */ - public void close() { - if (connected) { - try { - transport.close(); - } - catch (IOException ex) { - logger.debug("close()", ex); - } - finally { - connected = false; - } - } - } - - /** - * Returns the ModbusTransport associated with this - * TCPMasterConnection. - * - * @return the connection's ModbusTransport. - */ - public AbstractModbusTransport getModbusTransport() { - return transport; - } - - /** - * Set the ModbusTransport associated with this - * TCPMasterConnection - * @param trans associated transport - */ - public void setModbusTransport(ModbusTCPTransport trans) { - transport = trans; - } - - /** - * Returns the timeout (msec) for this TCPMasterConnection. - * - * @return the timeout as int. - */ - public synchronized int getTimeout() { - return timeout; - } - - /** - * Sets the timeout (msec) for this TCPMasterConnection. This is both the - * connection timeout and the transaction timeout - * - * @param timeout - the timeout in milliseconds as an int. - */ - public synchronized void setTimeout(int timeout) { - try { - this.timeout = timeout; - if (socket != null) { - socket.setSoTimeout(timeout); - } - } - catch (IOException ex) { - logger.warn("Could not set timeout to value " + timeout, ex); - } - } - - /** - * Returns the destination port of this TCPMasterConnection. - * - * @return the port number as int. - */ - public int getPort() { - return port; - } - - /** - * Sets the destination port of this TCPMasterConnection. The - * default is defined as Modbus.DEFAULT_PORT. - * - * @param port the port number as int. - */ - public void setPort(int port) { - this.port = port; - } - - /** - * Returns the destination InetAddress of this - * TCPMasterConnection. - * - * @return the destination address as InetAddress. - */ - public InetAddress getAddress() { - return address; - } - - /** - * Sets the destination InetAddress of this - * TCPMasterConnection. - * - * @param adr the destination address as InetAddress. - */ - public void setAddress(InetAddress adr) { - address = adr; - } - - /** - * Gets the current setting of the flag which controls sending - * urgent data to test a network connection. - * - * @return Status - */ - public boolean getUseUrgentData() { - return useUrgentData; - } - - /** - * Set the flag which controls sending urgent data to test a - * network connection. - * - * @param useUrgentData - Connections are testing using urgent data. - */ - public void setUseUrgentData(boolean useUrgentData) { - this.useUrgentData = useUrgentData; - } - - /** - * Returns true if this connection is an RTU over TCP type - * - * @return True if RTU over TCP - */ - public boolean isUseRtuOverTcp() { - return useRtuOverTcp; - } - - /** - * Sets the transport type to use - * Normally set during the connection but can also be set after a connection has been established - * - * @param useRtuOverTcp True if the transport should be interpreted as RTU over tCP - * - * @throws Exception If the connection is not valid - */ - public void setUseRtuOverTcp(boolean useRtuOverTcp) throws Exception { - this.useRtuOverTcp = useRtuOverTcp; - if (isConnected()) { - prepareTransport(useRtuOverTcp); - } - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPSlaveConnection.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPSlaveConnection.java deleted file mode 100644 index 654d9be..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/TCPSlaveConnection.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import com.ghgande.j2mod.modbus.io.ModbusRTUTCPTransport; -import com.ghgande.j2mod.modbus.io.ModbusTCPTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; - -/** - * Class that implements a TCPSlaveConnection. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class TCPSlaveConnection { - - private static final Logger logger = LoggerFactory.getLogger(TCPSlaveConnection.class); - - // instance attributes - private Socket socket; - private int timeout = Modbus.DEFAULT_TIMEOUT; - private boolean connected; - private ModbusTCPTransport transport; - - /** - * Constructs a TCPSlaveConnection instance using a given socket - * instance. - * - * @param socket the socket instance to be used for communication. - */ - public TCPSlaveConnection(Socket socket) { - this(socket, false); - } - - /** - * Constructs a TCPSlaveConnection instance using a given socket - * instance. - * - * @param socket the socket instance to be used for communication. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - */ - public TCPSlaveConnection(Socket socket, boolean useRtuOverTcp) { - try { - setSocket(socket, useRtuOverTcp); - } - catch (IOException ex) { - logger.debug("TCPSlaveConnection::Socket invalid"); - - throw new IllegalStateException("Socket invalid", ex); - } - } - - /** - * Closes this TCPSlaveConnection. - */ - public void close() { - if (connected) { - try { - transport.close(); - socket.close(); - } - catch (IOException ex) { - logger.warn("Could not close socket", ex); - } - connected = false; - } - } - - /** - * Returns the ModbusTransport associated with this - * TCPMasterConnection. - * - * @return the connection's ModbusTransport. - */ - public AbstractModbusTransport getModbusTransport() { - return transport; - } - - /** - * Prepares the associated ModbusTransport of this - * TCPMasterConnection for use. - * - * @param socket the socket to be used for communication. - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @throws IOException if an I/O related error occurs. - */ - private void setSocket(Socket socket, boolean useRtuOverTcp) throws IOException { - this.socket = socket; - - if (transport == null) { - if (useRtuOverTcp) { - logger.trace("setSocket() -> using RTU over TCP transport."); - transport = new ModbusRTUTCPTransport(socket); - } - else { - logger.trace("setSocket() -> using standard TCP transport."); - transport = new ModbusTCPTransport(socket); - } - } - else { - transport.setSocket(socket); - } - - connected = true; - } - - /** - * Returns the timeout for this TCPSlaveConnection. - * - * @return the timeout as int. - */ - public int getTimeout() { - return timeout; - } - - /** - * Sets the timeout for this TCPSlaveConnection. - * - * @param timeout the timeout in milliseconds as int. - */ - public void setTimeout(int timeout) { - this.timeout = timeout; - - try { - socket.setSoTimeout(timeout); - } - catch (IOException ex) { - logger.warn("Could not set timeout to " + timeout, ex); - } - } - - /** - * Returns the destination port of this TCPSlaveConnection. - * - * @return the port number as int. - */ - public int getPort() { - return socket.getLocalPort(); - } - - /** - * Returns the destination InetAddress of this - * TCPSlaveConnection. - * - * @return the destination address as InetAddress. - */ - public InetAddress getAddress() { - return socket.getLocalAddress(); - } - - /** - * Tests if this TCPSlaveConnection is connected. - * - * @return true if connected, false otherwise. - */ - public boolean isConnected() { - return connected; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPMasterConnection.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPMasterConnection.java deleted file mode 100644 index 04357db..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPMasterConnection.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.AbstractModbusTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; - -/** - * Class that implements a UDPMasterConnection. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class UDPMasterConnection { - - private static final Logger logger = LoggerFactory.getLogger(UDPMasterConnection.class); - - //instance attributes - private UDPMasterTerminal terminal; - private int timeout = Modbus.DEFAULT_TIMEOUT; - private boolean connected; - - private InetAddress address; - private int port = Modbus.DEFAULT_PORT; - - /** - * Constructs a UDPMasterConnection instance - * with a given destination address. - * - * @param adr the destination InetAddress. - */ - public UDPMasterConnection(InetAddress adr) { - address = adr; - } - - /** - * Opens this UDPMasterConnection. - * - * @throws Exception if there is a network failure. - */ - public synchronized void connect() throws Exception { - if (!connected) { - terminal = new UDPMasterTerminal(address); - terminal.setPort(port); - terminal.setTimeout(timeout); - terminal.activate(); - connected = true; - } - } - - /** - * Closes this UDPMasterConnection. - */ - public void close() { - if (connected) { - try { - terminal.deactivate(); - } - catch (Exception ex) { - logger.debug("Exception occurred while closing UDPMasterConnection", ex); - } - connected = false; - } - } - - /** - * Returns the ModbusTransport associated with this - * UDPMasterConnection. - * - * @return the connection's ModbusTransport. - */ - public AbstractModbusTransport getModbusTransport() { - return terminal == null ? null : terminal.getTransport(); - } - - /** - * Returns the terminal used for handling the package traffic. - * - * @return a UDPTerminal instance. - */ - public AbstractUDPTerminal getTerminal() { - return terminal; - } - - /** - * Returns the timeout for this UDPMasterConnection. - * - * @return the timeout as int. - */ - public synchronized int getTimeout() { - return timeout; - } - - /** - * Sets the timeout for this UDPMasterConnection. - * - * @param timeout the timeout as int. - */ - public synchronized void setTimeout(int timeout) { - this.timeout = timeout; - if (terminal != null) { - terminal.setTimeout(timeout); - } - } - - /** - * Returns the destination port of this - * UDPMasterConnection. - * - * @return the port number as int. - */ - public int getPort() { - return port; - } - - /** - * Sets the destination port of this - * UDPMasterConnection. - * The default is defined as Modbus.DEFAULT_PORT. - * - * @param port the port number as int. - */ - public void setPort(int port) { - this.port = port; - } - - /** - * Returns the destination InetAddress of this - * UDPMasterConnection. - * - * @return the destination address as InetAddress. - */ - public InetAddress getAddress() { - return address; - } - - /** - * Sets the destination InetAddress of this - * UDPMasterConnection. - * - * @param adr the destination address as InetAddress. - */ - public void setAddress(InetAddress adr) { - address = adr; - } - - /** - * Tests if this UDPMasterConnection is connected. - * - * @return true if connected, false otherwise. - */ - public boolean isConnected() { - return connected; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPMasterTerminal.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPMasterTerminal.java deleted file mode 100644 index c765972..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPMasterTerminal.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.io.ModbusUDPTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; - -/** - * Class implementing a UDPMasterTerminal. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -class UDPMasterTerminal extends AbstractUDPTerminal { - - private static final Logger logger = LoggerFactory.getLogger(UDPMasterTerminal.class); - - /** - * Create a UDP master connection to the specified Internet address. - * - * @param addr Remote address to connect to - */ - UDPMasterTerminal(InetAddress addr) { - address = addr; - } - - /** - * Create an uninitialized UDP master connection. - */ - public UDPMasterTerminal() { - } - - @Override - public synchronized void activate() throws Exception { - if (!isActive()) { - if (socket == null) { - socket = new DatagramSocket(); - } - logger.debug("UDPMasterTerminal::haveSocket():{}", socket.toString()); - logger.debug("UDPMasterTerminal::raddr=:{}:rport:{}", address.toString(), port); - - socket.setReceiveBufferSize(1024); - socket.setSendBufferSize(1024); - socket.setSoTimeout(timeout); - - transport = new ModbusUDPTransport(this); - active = true; - } - logger.debug("UDPMasterTerminal::activated"); - } - - @Override - public synchronized void deactivate() { - try { - logger.debug("UDPMasterTerminal::deactivate()"); - if (socket != null) { - socket.close(); - } - transport = null; - active = false; - } - catch (Exception ex) { - logger.error("Error closing socket", ex); - } - } - - @Override - public synchronized void sendMessage(byte[] msg) throws Exception { - DatagramPacket req = new DatagramPacket(msg, msg.length, address, port); - socket.send(req); - } - - @Override - public synchronized byte[] receiveMessage() throws Exception { - - // The longest possible DatagramPacket is 256 bytes (Modbus message - // limit) plus the 6 byte header. - byte[] buffer = new byte[262]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - socket.setSoTimeout(timeout); - socket.receive(packet); - return buffer; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPSlaveTerminal.java b/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPSlaveTerminal.java deleted file mode 100644 index 15ff4b0..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/net/UDPSlaveTerminal.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.net; - -import com.ghgande.j2mod.modbus.io.ModbusUDPTransport; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.util.Hashtable; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * Class implementing a UDPSlaveTerminal. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -class UDPSlaveTerminal extends AbstractUDPTerminal { - - private static final Logger logger = LoggerFactory.getLogger(UDPSlaveTerminal.class); - protected Hashtable requests = new Hashtable(342); - private LinkedBlockingQueue sendQueue = new LinkedBlockingQueue(); - private LinkedBlockingQueue receiveQueue = new LinkedBlockingQueue(); - private PacketSender packetSender; - private PacketReceiver packetReceiver; - - /** - * Creates a slave terminal on the specified adapter address - * Use 0.0.0.0 to listen on all adapters - * - * @param localaddress Local address to bind to - */ - protected UDPSlaveTerminal(InetAddress localaddress) { - address = localaddress; - } - - @Override - public synchronized void activate() throws Exception { - if (!isActive()) { - logger.debug("UDPSlaveTerminal.activate()"); - if (address != null && port != -1) { - socket = new DatagramSocket(port, address); - } - else { - socket = new DatagramSocket(); - port = socket.getLocalPort(); - address = socket.getLocalAddress(); - } - logger.debug("UDPSlaveTerminal::haveSocket():{}", socket.toString()); - logger.debug("UDPSlaveTerminal::addr=:{}:port={}", address.toString(), port); - - socket.setReceiveBufferSize(1024); - socket.setSendBufferSize(1024); - - // Never timeout the receive - socket.setSoTimeout(0); - - // Start a sender - packetSender = new PacketSender(socket); - new Thread(packetSender).start(); - logger.debug("UDPSlaveTerminal::sender started()"); - - // Start a receiver - - packetReceiver = new PacketReceiver(socket); - new Thread(packetReceiver).start(); - logger.debug("UDPSlaveTerminal::receiver started()"); - - // Create a transport to use - - transport = new ModbusUDPTransport(this); - logger.debug("UDPSlaveTerminal::transport created"); - active = true; - } - logger.debug("UDPSlaveTerminal::activated"); - } - - @Override - public synchronized void deactivate() { - try { - if (active) { - // Stop receiver - this will stop and close the socket - packetReceiver.stop(); - - // Stop sender gracefully - packetSender.stop(); - - transport = null; - active = false; - } - } - catch (Exception ex) { - logger.error("Error deactivating UDPSlaveTerminal", ex); - } - } - - @Override - public void sendMessage(byte[] msg) throws Exception { - sendQueue.add(msg); - } - - @Override - public byte[] receiveMessage() throws Exception { - return receiveQueue.take(); - } - - /** - * The background thread that is responsible for sending messages in response to requests - */ - class PacketSender implements Runnable { - - private boolean running; - private boolean closed; - private Thread thread; - private DatagramSocket socket; - - /** - * Constructs a sender with th socket - * - * @param socket Socket to use - */ - public PacketSender(DatagramSocket socket) { - running = true; - this.socket = socket; - } - - /** - * Stops the sender - */ - public void stop() { - running = false; - thread.interrupt(); - while (!closed) { - ModbusUtil.sleep(100); - } - } - - /** - * Thread loop that sends messages - */ - public void run() { - closed = false; - thread = Thread.currentThread(); - do { - try { - // Pickup the message and corresponding request - byte[] message = sendQueue.take(); - DatagramPacket req = requests.remove(ModbusUtil.registersToInt(message)); - - // Create new Package with corresponding address and port - if (req != null) { - DatagramPacket res = new DatagramPacket(message, message.length, req.getAddress(), req.getPort()); - socket.send(res); - logger.debug("Sent package from queue"); - } - } - catch (Exception ex) { - // Ignore the error if we are no longer listening - - if (running) { - logger.error("Problem reading UDP socket", ex); - } - } - } while (running); - closed = true; - } - - } - - /** - * The background thread that receives messages and adds them to the process list - * for further analysis - */ - class PacketReceiver implements Runnable { - - private boolean running; - private boolean closed; - private DatagramSocket socket; - - /** - * A receiver thread for reception of UDP messages - * - * @param socket Socket to use - */ - public PacketReceiver(DatagramSocket socket) { - running = true; - this.socket = socket; - } - - /** - * Stops the thread - */ - public void stop() { - running = false; - socket.close(); - while (!closed) { - ModbusUtil.sleep(100); - } - } - - /** - * Background thread for reading UDP messages - */ - public void run() { - closed = false; - do { - try { - // 1. Prepare buffer and receive package - byte[] buffer = new byte[256];// max size - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - socket.receive(packet); - - // 2. Extract TID and remember request - Integer tid = ModbusUtil.registersToInt(buffer); - requests.put(tid, packet); - - // 3. place the data buffer in the queue - receiveQueue.put(buffer); - logger.debug("Received package to queue"); - } - catch (Exception ex) { - // Ignore the error if we are no longer listening - - if (running) { - logger.error("Problem reading UDP socket", ex); - } - } - } while (running); - closed = true; - } - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/AbstractRegister.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/AbstractRegister.java deleted file mode 100644 index 8eda8c9..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/AbstractRegister.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Abstract class for a register. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class AbstractRegister implements Register { - - /** - * The word (byte[2]) holding the register content. - */ - protected byte[] register = new byte[2]; - - public int getValue() { - return ((register[0] & 0xff) << 8 | (register[1] & 0xff)); - } - - public final int toUnsignedShort() { - return ((register[0] & 0xff) << 8 | (register[1] & 0xff)); - } - - public final short toShort() { - return (short)((register[0] << 8) | (register[1] & 0xff)); - } - - public synchronized byte[] toBytes() { - byte[] dest = new byte[register.length]; - System.arraycopy(register, 0, dest, 0, dest.length); - return dest; - } - - public final void setValue(short s) { - register[0] = (byte)(0xff & (s >> 8)); - register[1] = (byte)(0xff & s); - } - - public final void setValue(byte[] bytes) { - if (bytes.length < 2) { - throw new IllegalArgumentException(); - } - else { - register[0] = bytes[0]; - register[1] = bytes[1]; - } - } - - public final void setValue(int v) { - register[0] = (byte)(0xff & (v >> 8)); - register[1] = (byte)(0xff & v); - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DefaultProcessImageFactory.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DefaultProcessImageFactory.java deleted file mode 100644 index aef428c..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DefaultProcessImageFactory.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * The default ProcessImageFactory. It creates a new SimpleProcessImage - * each time createProcessImageImplementation() is invoked. - * - * @author Dieter Wimberger - * @author jfhaugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class DefaultProcessImageFactory implements ProcessImageFactory { - - /** - * Returns a new SimpleProcessImage instance. - * - * @return a SimpleProcessImage instance. - */ - public ProcessImageImplementation createProcessImageImplementation() { - return new SimpleProcessImage(); - } - - /** - * Returns a new SimpleDigitalIn instance. - * - * @return a SimpleDigitalIn instance. - */ - public DigitalIn createDigitalIn() { - return new SimpleDigitalIn(); - } - - /** - * Returns a new DigitalIn instance with the given state. - * - * @param state true if set, false otherwise. - * - * @return a SimpleDigitalIn instance. - */ - public DigitalIn createDigitalIn(boolean state) { - return new SimpleDigitalIn(state); - } - - /** - * Returns a new SimpleDigitalOut instance. - * - * @return a SimpleDigitalOut instance. - */ - public DigitalOut createDigitalOut() { - return new SimpleDigitalOut(); - } - - /** - * Returns a new DigitalOut instance with the given state. - * - * @param b true if set, false otherwise. - * - * @return a SimpleDigitalOut instance. - */ - public DigitalOut createDigitalOut(boolean b) { - return new SimpleDigitalOut(b); - } - - /** - * Returns a new SimpleInputRegister instance. - * - * @return a SimpleInputRegister instance. - */ - public InputRegister createInputRegister() { - return new SimpleInputRegister(); - } - - /** - * Returns a new InputRegister instance with a given value. - * - * @param b1 the first byte. - * @param b2 the second byte. - * - * @return an InputRegister instance. - */ - public InputRegister createInputRegister(byte b1, byte b2) { - return new SimpleInputRegister(b1, b2); - } - - /** - * Creates a new SimpleRegister instance. - * - * @return a SimpleRegister instance. - */ - public Register createRegister() { - return new SimpleRegister(); - } - - /** - * Returns a new Register instance with a given value. - * - * @param b1 the first byte. - * @param b2 the second byte. - * - * @return a Register instance. - */ - public Register createRegister(byte b1, byte b2) { - return new SimpleRegister(b1, b2); - } - - /** - * Returns a new InputRegister instance with a given value. - * - * @param value the value of the register as an int - * - * @return an InputRegister instance. - */ - public InputRegister createInputRegister(int value) { - return new SimpleInputRegister(value); - } - - /** - * Creates a new SimpleRegister instance. - * - * @param value initial value of the register - * @return a SimpleRegister instance. - */ - public Register createRegister(int value) { - return new SimpleRegister(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DigitalIn.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DigitalIn.java deleted file mode 100644 index beacb8e..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DigitalIn.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining a digital input. - *

- * In Modbus terms this represents an - * input discrete, it is read only from - * the slave side. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface DigitalIn { - - /** - * Tests if this DigitalIn is set. - *

- * - * @return true if set, false otherwise. - */ - boolean isSet(); - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DigitalOut.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DigitalOut.java deleted file mode 100644 index e0dcb04..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/DigitalOut.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining a digital output. - *

- * In Modbus terms this represents a - * coil, which is read-write from slave and - * master or device side.
- * Therefor implementations have to be carefully - * designed for concurrency. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface DigitalOut { - - /** - * Tests if this DigitalOut is set. - *

- * - * @return true if set, false otherwise. - */ - boolean isSet(); - - /** - * Sets the state of this DigitalOut. - *

- * - * @param b true if to be set, false otherwise. - */ - void set(boolean b); - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/FIFO.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/FIFO.java deleted file mode 100644 index d5f1b72..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/FIFO.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Vector; - -/** - * @author Julie - * - * FIFO -- an abstraction of a Modbus FIFO, as supported by the - * READ FIFO command. - * - * The FIFO class is only intended to be used for testing purposes and does - * not reflect the actual behavior of a FIFO in a real Modbus device. In an - * actual Modbus device, the FIFO is mapped within a fixed address. - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class FIFO { - - private static final Logger logger = LoggerFactory.getLogger(FIFO.class); - - private int address; - private int registerCount; - private Vector registers; - - public FIFO(int address) { - this.address = address; - registerCount = 0; - registers = new Vector(); - } - - public synchronized int getRegisterCount() { - return registerCount; - } - - public synchronized Register[] getRegisters() { - Register result[] = new Register[registerCount + 1]; - - result[0] = new SimpleRegister(registerCount); - for (int i = 0; i < registerCount; i++) { - result[i + 1] = registers.get(i); - } - - return result; - } - - public synchronized void pushRegister(Register register) { - if (registerCount == 31) { - registers.remove(0); - } - else { - registerCount++; - } - - registers.add(new SimpleRegister(register.getValue())); - } - - public synchronized void resetRegisters() { - registers.removeAllElements(); - registerCount = 0; - } - - public int getAddress() { - return address; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/File.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/File.java deleted file mode 100644 index 4728706..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/File.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Julie - * - * File -- an abstraction of a Modbus File, as supported by the - * READ FILE RECORD and WRITE FILE RECORD commands. - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class File { - - private static final Logger logger = LoggerFactory.getLogger(File.class); - - private int fileNumber; - private int record_Count; - private Record records[]; - - public File(int fileNumber, int records) { - this.fileNumber = fileNumber; - record_Count = records; - this.records = new Record[records]; - } - - public int getFileNumber() { - return fileNumber; - } - - public int getRecordCount() { - return record_Count; - } - - public Record getRecord(int i) { - if (i < 0 || i >= record_Count) { - throw new IllegalAddressException(); - } - - return records[i]; - } - - public File setRecord(int i, Record record) { - if (i < 0 || i >= record_Count) { - throw new IllegalAddressException(); - } - - records[i] = record; - - return this; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/IllegalAddressException.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/IllegalAddressException.java deleted file mode 100644 index 79c19eb..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/IllegalAddressException.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Class implementing an IllegalAddressException. This exception is - * thrown when a non-existant spot in the process image was addressed. - *

- * Note that this is a runtime exception, as it is similar to the - * IndexOutOfBoundsException - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class IllegalAddressException extends RuntimeException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Constructs a new IllegalAddressException. - */ - public IllegalAddressException() { - } - - /** - * Constructs a new IllegalAddressException with the given message. - * - * @param message a message as String. - */ - public IllegalAddressException(String message) { - super(message); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/InputRegister.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/InputRegister.java deleted file mode 100644 index eee394b..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/InputRegister.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining an input register. - *

- * This register is read only from the slave side. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface InputRegister { - - /** - * Returns the value of this InputRegister. The value is stored as - * int but should be treated like a 16-bit word. - * - * @return the value as int. - */ - int getValue(); - - /** - * Returns the content of this Register as unsigned 16-bit value - * (unsigned short). - * - * @return the content as unsigned short (int). - */ - int toUnsignedShort(); - - /** - * Returns the content of this Register as signed 16-bit value - * (short). - * - * @return the content as short. - */ - short toShort(); - - /** - * Returns the content of this Register as bytes. - * - * @return a byte[] with length 2. - */ - byte[] toBytes(); - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ObservableDigitalOut.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ObservableDigitalOut.java deleted file mode 100644 index 67b1d66..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ObservableDigitalOut.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -import com.ghgande.j2mod.modbus.util.Observable; - -/** - * Class implementing an observable digital output. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ObservableDigitalOut extends Observable implements DigitalOut { - - /** - * A boolean holding the state of this digital out. - */ - protected boolean set; - - /** - * Determine if the digital output is set. - * - * @return the boolean value of the digital output. - */ - public boolean isSet() { - return set; - } - - /** - * Set or clear the digital output. Will notify any registered - * observers. - */ - public void set(boolean b) { - set = b; - notifyObservers("value"); - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ObservableRegister.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ObservableRegister.java deleted file mode 100644 index 1722734..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ObservableRegister.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -import com.ghgande.j2mod.modbus.util.Observable; - -/** - * Class implementing an observable register. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ObservableRegister extends Observable implements Register { - - /** - * The word holding the content of this register. - */ - protected short register; - - synchronized public int getValue() { - return register & 0xFFFF; - } - - public final int toUnsignedShort() { - return register & 0xFFFF; - } - - public final short toShort() { - return register; - } - - public synchronized byte[] toBytes() { - return new byte[]{(byte)(register >> 8), (byte)(register & 0xFF)}; - } - - public final synchronized void setValue(short s) { - register = s; - notifyObservers("value"); - } - - public final synchronized void setValue(byte[] bytes) { - if (bytes.length < 2) { - throw new IllegalArgumentException(); - } - else { - register = (short)(((short)((bytes[0] << 8))) | (((short)(bytes[1])) & 0xFF)); - notifyObservers("value"); - } - } - - public final synchronized void setValue(int v) { - register = (short)v; - notifyObservers("value"); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImage.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImage.java deleted file mode 100644 index 3da266c..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImage.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining a process image in an object oriented manner. - *

- * The process image is understood as a shared memory area used form - * communication between slave and master or device side. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface ProcessImage { - - /** - * Returns a range of DigitalOut instances. - * - * @param offset the start offset. - * @param count the amount of DigitalOut from the offset. - * - * @return an array of DigitalOut instances. - * - * @throws IllegalAddressException if the range from offset to offset+count is non existant. - */ - DigitalOut[] getDigitalOutRange(int offset, int count) throws IllegalAddressException; - - /** - * Returns the DigitalOut instance at the given reference. - * - * @param ref the reference. - * - * @return the DigitalOut instance at the given address. - * - * @throws IllegalAddressException if the reference is invalid. - */ - DigitalOut getDigitalOut(int ref) throws IllegalAddressException; - - /** - * Returns the number of DigitalOut instances in this - * ProcessImage. - * - * @return the number of digital outs as int. - */ - int getDigitalOutCount(); - - /** - * Returns a range of DigitalIn instances. - * - * @param offset the start offset. - * @param count the amount of DigitalIn from the offset. - * - * @return an array of DigitalIn instances. - * - * @throws IllegalAddressException if the range from offset to offset+count is non existant. - */ - DigitalIn[] getDigitalInRange(int offset, int count) throws IllegalAddressException; - - /** - * Returns the DigitalIn instance at the given reference. - * - * @param ref the reference. - * - * @return the DigitalIn instance at the given address. - * - * @throws IllegalAddressException if the reference is invalid. - */ - DigitalIn getDigitalIn(int ref) throws IllegalAddressException; - - /** - * Returns the number of DigitalIn instances in this - * ProcessImage. - * - * @return the number of digital ins as int. - */ - int getDigitalInCount(); - - /** - * Returns a range of InputRegister instances. - * - * @param offset the start offset. - * @param count the amount of InputRegister from the offset. - * - * @return an array of InputRegister instances. - * - * @throws IllegalAddressException if the range from offset to offset+count is non existant. - */ - InputRegister[] getInputRegisterRange(int offset, int count) throws IllegalAddressException; - - /** - * Returns the InputRegister instance at the given reference. - * - * @param ref the reference. - * - * @return the InputRegister instance at the given address. - * - * @throws IllegalAddressException if the reference is invalid. - */ - InputRegister getInputRegister(int ref) throws IllegalAddressException; - - /** - * Returns the number of InputRegister instances in this - * ProcessImage. - * - *

- * This is not the same as the value of the highest addressable register. - * - * @return the number of input registers as int. - */ - int getInputRegisterCount(); - - /** - * Returns a range of Register instances. - * - * @param offset the start offset. - * @param count the amount of Register from the offset. - * - * @return an array of Register instances. - * - * @throws IllegalAddressException if the range from offset to offset+count is non existant. - */ - Register[] getRegisterRange(int offset, int count) throws IllegalAddressException; - - /** - * Returns the Register instance at the given reference. - *

- * - * @param ref the reference. - * - * @return the Register instance at the given address. - * - * @throws IllegalAddressException if the reference is invalid. - */ - Register getRegister(int ref) throws IllegalAddressException; - - /** - * Returns the number of Register instances in this - * ProcessImage. - * - *

- * This is not the same as the value of the highest addressable register. - * - * @return the number of registers as int. - */ - int getRegisterCount(); - - /** - * Returns the File instance at the given reference. - *

- * - * @param ref the reference. - * - * @return the File instance at the given address. - * - * @throws IllegalAddressException if the reference is invalid. - */ - File getFile(int ref) throws IllegalAddressException; - - /** - * Returns the File instance having the specified file number. - * - * @param ref The file number for the File object to be returned. - * - * @return the File instance having the given number. - * - * @throws IllegalAddressException if a File with the given number does not exist. - */ - File getFileByNumber(int ref) throws IllegalAddressException; - - /** - * Returns the number of File instances in this - * ProcessImage. - * - *

- * This is not the same as the value of the highest addressable register. - * - * @return the number of registers as int. - */ - int getFileCount(); - - /** - * Returns the FIFO instance in the list of all FIFO objects - * in this ProcessImage. - * - * @param ref the reference. - * - * @return the File instance at the given address. - * - * @throws IllegalAddressException if the reference is invalid. - */ - FIFO getFIFO(int ref) throws IllegalAddressException; - - /** - * Returns the FIFO instance having the specified base address. - * - * @param ref The address for the FIFO object to be returned. - * - * @return the FIFO instance having the given base address - * - * @throws IllegalAddressException if a File with the given number does not exist. - */ - FIFO getFIFOByAddress(int ref) throws IllegalAddressException; - - /** - * Returns the number of File instances in this - * ProcessImage. - * - *

- * This is not the same as the value of the highest addressable register. - * - * @return the number of registers as int. - */ - int getFIFOCount(); -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImageFactory.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImageFactory.java deleted file mode 100644 index 2e1cd80..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImageFactory.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining the factory methods for - * the process image and it's elements. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface ProcessImageFactory { - - /** - * Returns a new ProcessImageImplementation instance. - * - * @return a ProcessImageImplementation instance. - */ - ProcessImageImplementation createProcessImageImplementation(); - - /** - * Returns a new DigitalIn instance. - * - * @return a DigitalIn instance. - */ - DigitalIn createDigitalIn(); - - /** - * Returns a new DigitalIn instance with the given state. - * - * @param state true if set, false otherwise. - * - * @return a DigitalIn instance. - */ - DigitalIn createDigitalIn(boolean state); - - /** - * Returns a new DigitalOut instance. - * - * @return a DigitalOut instance. - */ - DigitalOut createDigitalOut(); - - /** - * Returns a new DigitalOut instance with the - * given state. - * - * @param b true if set, false otherwise. - * - * @return a DigitalOut instance. - */ - DigitalOut createDigitalOut(boolean b); - - /** - * Returns a new InputRegister instance. - * - * @return an InputRegister instance. - */ - InputRegister createInputRegister(); - - /** - * Returns a new InputRegister instance with a - * given value. - * - * @param b1 the first byte. - * @param b2 the second byte. - * - * @return an InputRegister instance. - */ - InputRegister createInputRegister(byte b1, byte b2); - - /** - * Creates a new Register instance. - * - * @return a Register instance. - */ - Register createRegister(); - - /** - * Returns a new Register instance with a - * given value. - * - * @param b1 the first byte. - * @param b2 the second byte. - * - * @return a Register instance. - */ - Register createRegister(byte b1, byte b2); - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImageImplementation.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImageImplementation.java deleted file mode 100644 index b6a5da7..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/ProcessImageImplementation.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining implementation specific details of the - * ProcessImage, adding mechanisms for creating and modifying the - * actual "process image". - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface ProcessImageImplementation extends ProcessImage { - - /** - * Defines the set state (i.e. true) of a digital input or output. - */ - byte DIG_TRUE = 1; - /** - * Defines the unset state (i.e. false) of a digital input or output. - */ - byte DIG_FALSE = 0; - /** - * Defines the invalid (unset, neither true nor false) state of a digital - * input or output. - */ - byte DIG_INVALID = -1; - - /** - * Sets a new DigitalOut instance at the given reference. - * - * @param ref the reference as int. - * @param out the new DigitalOut instance to be set. - * - * @throws IllegalAddressException if the reference is invalid. - */ - void setDigitalOut(int ref, DigitalOut out) throws IllegalAddressException; - - /** - * Adds a new DigitalOut instance. - * - * @param out the DigitalOut instance to be added. - */ - void addDigitalOut(DigitalOut out); - - /** - * Adds a new DigitalOut instance at the given reference. - * - * @param ref - the reference for the instance. - * @param out - the DigitalOut instance to be added. - */ - void addDigitalOut(int ref, DigitalOut out); - - /** - * Removes a given DigitalOut instance. - * - * @param out the DigitalOut instance to be removed. - */ - void removeDigitalOut(DigitalOut out); - - /** - * Sets a new DigitalIn instance at the given reference. - * - * @param ref the reference as int. - * @param di the new DigitalIn instance to be set. - * - * @throws IllegalAddressException if the reference is invalid. - */ - void setDigitalIn(int ref, DigitalIn di) throws IllegalAddressException; - - /** - * Adds a new DigitalIn instance. - * - * @param di the DigitalIn instance to be added. - */ - void addDigitalIn(DigitalIn di); - - /** - * Adds a new DigitalIn instance at the given reference, possibly - * creating a hole between the last existing reference and the new object. - * - * @param ref - the reference for the new instance. - * @param di the DigitalIn instance to be added. - */ - void addDigitalIn(int ref, DigitalIn di); - - /** - * Removes a given DigitalIn instance. - * - * @param di the DigitalIn instance to be removed. - */ - void removeDigitalIn(DigitalIn di); - - /** - * Sets a new InputRegister instance at the given reference. - * - * @param ref the reference as int. - * @param reg the new InputRegister instance to be set. - * - * @throws IllegalAddressException if the reference is invalid. - */ - void setInputRegister(int ref, InputRegister reg) throws IllegalAddressException; - - /** - * Adds a new InputRegister instance. - * - * @param reg the InputRegister instance to be added. - */ - void addInputRegister(InputRegister reg); - - /** - * Adds a new InputRegister instance, possibly - * creating a hole between the last existing reference and the new object. - * - * @param ref - The reference for the new instance. - * @param reg the InputRegister instance to be added. - */ - void addInputRegister(int ref, InputRegister reg); - - /** - * Removes a given InputRegister instance. - * - * @param reg the InputRegister instance to be removed. - */ - void removeInputRegister(InputRegister reg); - - /** - * Sets a new Register instance at the given reference. - * - * @param ref the reference as int. - * @param reg the new Register instance to be set. - * - * @throws IllegalAddressException if the reference is invalid. - */ - void setRegister(int ref, Register reg) throws IllegalAddressException; - - /** - * Adds a new Register instance. - * - * @param reg the Register instance to be added. - */ - void addRegister(Register reg); - - /** - * Adds a new Register instance, possibly - * creating a hole between the last existing reference and the new object. - * - * @param ref - the reference for the new instance. - * @param reg the Register instance to be added. - */ - void addRegister(int ref, Register reg); - - /** - * Removes a given Register instance. - * - * @param reg the Register instance to be removed. - */ - void removeRegister(Register reg); - - /** - * Sets a new File instance at the given reference. - * - * @param ref the reference as int. - * @param reg the new File instance to be set. - * - * @throws IllegalAddressException if the reference is invalid. - */ - void setFile(int ref, File reg) throws IllegalAddressException; - - /** - * Adds a new File instance. - * - * @param reg the File instance to be added. - */ - void addFile(File reg); - - /** - * Adds a new File instance, possibly - * creating a hole between the last existing reference and the new object. - * - * @param ref - the reference for the new isntance. - * @param reg the File instance to be added. - */ - void addFile(int ref, File reg); - - /** - * Removes a given File instance. - * - * @param reg the File instance to be removed. - */ - void removeFile(File reg); - - /** - * Sets a new FIFO instance at the given reference. - * - * @param ref the reference as int. - * @param reg the new FIFO instance to be set. - * - * @throws IllegalAddressException if the reference is invalid. - */ - void setFIFO(int ref, FIFO reg) throws IllegalAddressException; - - /** - * Adds a new FIFO instance. - * - * @param reg the FIFO instance to be added. - */ - void addFIFO(FIFO reg); - - /** - * Adds a new FIFO instance, possibly - * creating a hole between the last existing reference and the new object. - * - * @param ref - the reference for the new instance. - * @param reg the FIFO instance to be added. - */ - void addFIFO(int ref, FIFO reg); - - /** - * Removes a given FIFO instance. - * - * @param reg the FIFO instance to be removed. - */ - void removeFIFO(FIFO reg); -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/Record.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/Record.java deleted file mode 100644 index 924988b..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/Record.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author Julie - * - * File -- an abstraction of a Modbus Record, as supported by the - * READ FILE RECORD and WRITE FILE RECORD commands. - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class Record { - - private static final Logger logger = LoggerFactory.getLogger(Record.class); - - private int recordNumber; - private int registerCount; - private Register registers[]; - - public Record(int recordNumber, int registers) { - this.recordNumber = recordNumber; - registerCount = registers; - this.registers = new Register[registers]; - - for (int i = 0; i < registerCount; i++) { - this.registers[i] = new SimpleRegister(0); - } - } - - public int getRecordNumber() { - return recordNumber; - } - - public int getRegisterCount() { - return registerCount; - } - - public Register getRegister(int register) { - if (register < 0 || register >= registerCount) { - throw new IllegalAddressException(); - } - - return registers[register]; - } - - public Record setRegister(int ref, Register register) { - if (ref < 0 || ref >= registerCount) { - throw new IllegalAddressException(); - } - - registers[ref] = register; - - return this; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/Register.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/Register.java deleted file mode 100644 index 31dc153..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/Register.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Interface defining a register. - * - *

- * A register is read-write from slave and master or device side. Therefore - * implementations have to be carefully designed for concurrency. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface Register extends InputRegister { - - /** - * Sets the content of this Register from the given unsigned 16-bit - * value (unsigned short). - * - * @param v the value as unsigned short (int). - */ - void setValue(int v); - - /** - * Sets the content of this register from the given signed 16-bit value - * (short). - * - * @param s the value as short. - */ - void setValue(short s); - - /** - * Sets the content of this register from the given raw bytes. - * - * @param bytes the raw data as byte[]. - */ - void setValue(byte[] bytes); -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleDigitalIn.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleDigitalIn.java deleted file mode 100644 index fdbca84..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleDigitalIn.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Class implementing a simple DigitalIn. - *

- * The set method is synchronized, which ensures atomic - * access, but no specific access order. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class SimpleDigitalIn implements DigitalIn { - - /** - * Field for the digital in state. - */ - protected boolean set = false; - - /** - * Constructs a new SimpleDigitalIn instance. - */ - public SimpleDigitalIn() { - } - - /** - * Constructs a new SimpleDigitalIn instance - * with a given valid state. - * - * @param b true if to be set, false otherwise. - */ - public SimpleDigitalIn(boolean b) { - set(b); - } - - public boolean isSet() { - return set; - } - - /** - * Sets the state of this SimpleDigitalIn. - * This method should only be used from master/device - * side. - * - * @param b true if to be set, false otherwise. - */ - public synchronized void set(boolean b) { - set = b; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleDigitalOut.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleDigitalOut.java deleted file mode 100644 index b88e690..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleDigitalOut.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Class implementing a simple DigitalOut. - *

- * The set method is synchronized, which ensures atomic - * access, but no specific access order. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class SimpleDigitalOut implements DigitalOut { - - /** - * Field for the digital out state. - */ - protected boolean set; - - /** - * Constructs a new SimpleDigitalOut instance. - * It's state will be invalid. - */ - public SimpleDigitalOut() { - } - - /** - * Constructs a new SimpleDigitalOut instance - * with the given state. - * - * @param b true if set, false otherwise. - */ - public SimpleDigitalOut(boolean b) { - set(b); - } - - public boolean isSet() { - return set; - } - - public synchronized void set(boolean b) { - set = b; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleInputRegister.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleInputRegister.java deleted file mode 100644 index 96cce0c..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleInputRegister.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Class implementing a simple InputRegister. - *

- * The setValue() method is synchronized, which ensures atomic access, * but no specific access order. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class SimpleInputRegister extends SynchronizedAbstractRegister implements InputRegister { - - /** - * Constructs a new SimpleInputRegister instance. It's state will - * be invalid. - */ - public SimpleInputRegister() { - } - - /** - * Constructs a new SimpleInputRegister instance. - * - * @param b1 the first (hi) byte of the word. - * @param b2 the second (low) byte of the word. - */ - public SimpleInputRegister(byte b1, byte b2) { - register[0] = b1; - register[1] = b2; - } - - /** - * Constructs a new SimpleInputRegister instance with the given - * value. - * - * @param value the value of this SimpleInputRegister as int - * . - */ - public SimpleInputRegister(int value) { - setValue(value); - }// constructor(int) - - public String toString() { - if (register == null) { - return "invalid"; - } - - return getValue() + ""; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleProcessImage.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleProcessImage.java deleted file mode 100644 index 69ef723..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleProcessImage.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -import java.util.Vector; - -/** - * Class implementing a simple process image to be able to run unit tests or - * handle simple cases. - * - *

- * The image has a simple linear address space for, analog, digital and file - * objects. Holes may be created by adding a object with a reference after the - * last object reference of that type. - * - * @author Dieter Wimberger - * @author Julie Added support for files of records. - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class SimpleProcessImage implements ProcessImageImplementation { - - // instance attributes - protected final Vector digitalIns = new Vector(); - protected final Vector digitalOuts = new Vector(); - protected final Vector inputRegisters = new Vector(); - protected final Vector registers = new Vector(); - protected final Vector files = new Vector(); - protected final Vector fifos = new Vector(); - protected boolean locked = false; - protected int unitID = 0; - - /** - * Constructs a new SimpleProcessImage instance. - */ - public SimpleProcessImage() { - } - - /** - * Constructs a new SimpleProcessImage instance having a - * (potentially) non-zero unit ID. - * @param unit Unit ID of this image - */ - public SimpleProcessImage(int unit) { - unitID = unit; - } - - /** - * The process image is locked to prevent changes. - * - * @return whether or not the process image is locked. - */ - public synchronized boolean isLocked() { - return locked; - } - - /** - * setLocked -- lock or unlock the process image. It is an error (false - * return value) to attempt to lock the process image when it is already - * locked. - * - *

- * Compatability Note: jamod did not enforce this restriction, so it is - * being handled in a way which is backwards compatible. If you wish to - * determine if you acquired the lock, check the return value. If your code - * is still based on the jamod paradigm, you will ignore the return value - * and your code will function as before. - *

- * @param locked True if the image is to be locked - * @return setting lock succeded - */ - public synchronized boolean setLocked(boolean locked) { - if (this.locked && locked) { - return false; - } - - this.locked = locked; - return true; - } - - public int getUnitID() { - return unitID; - } - - public DigitalOut[] getDigitalOutRange(int ref, int count) { - // ensure valid reference range - if (ref < 0 || ref + count > digitalOuts.size()) { - throw new IllegalAddressException(); - } - else { - DigitalOut[] douts = new DigitalOut[count]; - for (int i = 0; i < douts.length; i++) { - douts[i] = getDigitalOut(ref + i); - } - return douts; - } - } - - public DigitalOut getDigitalOut(int ref) throws IllegalAddressException { - try { - DigitalOut result = digitalOuts.elementAt(ref); - if (result == null) { - throw new IllegalAddressException(); - } - return result; - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - - public int getDigitalOutCount() { - return digitalOuts.size(); - } - - public DigitalIn[] getDigitalInRange(int ref, int count) { - // ensure valid reference range - if (ref < 0 || ref + count > digitalIns.size()) { - throw new IllegalAddressException(); - } - else { - DigitalIn[] dins = new DigitalIn[count]; - for (int i = 0; i < dins.length; i++) { - dins[i] = getDigitalIn(ref + i); - } - return dins; - } - } - - public DigitalIn getDigitalIn(int ref) throws IllegalAddressException { - try { - DigitalIn result = digitalIns.elementAt(ref); - if (result == null) { - throw new IllegalAddressException(); - } - return result; - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - - public int getDigitalInCount() { - return digitalIns.size(); - } - - public InputRegister[] getInputRegisterRange(int ref, int count) { - // ensure valid reference range - if (ref < 0 || ref + count > inputRegisters.size()) { - throw new IllegalAddressException(); - } - - InputRegister[] iregs = new InputRegister[count]; - for (int i = 0; i < iregs.length; i++) { - iregs[i] = getInputRegister(ref + i); - } - - return iregs; - } - - public InputRegister getInputRegister(int ref) throws IllegalAddressException { - try { - InputRegister result = inputRegisters.elementAt(ref); - if (result == null) { - throw new IllegalAddressException(); - } - - return result; - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - - public int getInputRegisterCount() { - return inputRegisters.size(); - } - - public Register[] getRegisterRange(int ref, int count) { - if (ref < 0 || ref + count > registers.size()) { - throw new IllegalAddressException(); - } - else { - Register[] iregs = new Register[count]; - for (int i = 0; i < iregs.length; i++) { - iregs[i] = getRegister(ref + i); - } - return iregs; - } - } - - public Register getRegister(int ref) throws IllegalAddressException { - try { - Register result = registers.elementAt(ref); - if (result == null) { - throw new IllegalAddressException(); - } - - return result; - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - - public int getRegisterCount() { - return registers.size(); - } - - public File getFile(int fileNumber) { - try { - File result = files.elementAt(fileNumber); - if (result == null) { - throw new IllegalAddressException(); - } - - return result; - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - - public File getFileByNumber(int ref) { - if (ref < 0 || ref >= 10000 || files == null) { - throw new IllegalAddressException(); - } - - synchronized (files) { - for (File file : files) { - if (file.getFileNumber() == ref) { - return file; - } - } - } - - throw new IllegalAddressException(); - } - - public int getFileCount() { - return files.size(); - } - - public FIFO getFIFO(int fifoNumber) { - try { - FIFO result = fifos.elementAt(fifoNumber); - if (result == null) { - throw new IllegalAddressException(); - } - - return result; - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - - public FIFO getFIFOByAddress(int ref) { - for (FIFO fifo : fifos) { - if (fifo.getAddress() == ref) { - return fifo; - } - } - - return null; - } - - public int getFIFOCount() { - if (fifos == null) { - return 0; - } - - return fifos.size(); - } - - public void setDigitalOut(int ref, DigitalOut _do) throws IllegalAddressException { - if (!isLocked()) { - try { - if (digitalOuts.get(ref) == null) { - throw new IllegalAddressException(); - } - digitalOuts.setElementAt(_do, ref); - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - } - - public void addDigitalOut(DigitalOut _do) { - if (!isLocked()) { - digitalOuts.addElement(_do); - } - } - - public void addDigitalOut(int ref, DigitalOut dout) { - if (ref < 0 || ref >= 65536) { - throw new IllegalArgumentException(); - } - - if (!isLocked()) { - synchronized (digitalOuts) { - if (ref < digitalOuts.size()) { - digitalOuts.setElementAt(dout, ref); - return; - } - digitalOuts.setSize(ref + 1); - digitalOuts.setElementAt(dout, ref); - } - } - } - - public void removeDigitalOut(DigitalOut _do) { - if (!isLocked()) { - digitalOuts.removeElement(_do); - } - } - - public void setDigitalIn(int ref, DigitalIn di) throws IllegalAddressException { - if (!isLocked()) { - try { - if (digitalIns.get(ref) == null) { - throw new IllegalAddressException(); - } - digitalIns.setElementAt(di, ref); - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - } - - public void addDigitalIn(DigitalIn di) { - if (!isLocked()) { - digitalIns.addElement(di); - } - } - - public void addDigitalIn(int ref, DigitalIn d1) { - if (ref < 0 || ref >= 65536) { - throw new IllegalArgumentException(); - } - - if (!isLocked()) { - synchronized (digitalIns) { - if (ref < digitalIns.size()) { - digitalIns.setElementAt(d1, ref); - return; - } - digitalIns.setSize(ref + 1); - digitalIns.setElementAt(d1, ref); - } - } - } - - public void removeDigitalIn(DigitalIn di) { - if (!isLocked()) { - digitalIns.removeElement(di); - } - } - - public void setInputRegister(int ref, InputRegister reg) throws IllegalAddressException { - if (!isLocked()) { - try { - if (inputRegisters.get(ref) == null) { - throw new IllegalAddressException(); - } - - inputRegisters.setElementAt(reg, ref); - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - } - - public void addInputRegister(InputRegister reg) { - if (!isLocked()) { - inputRegisters.addElement(reg); - } - } - - public void addInputRegister(int ref, InputRegister inReg) { - if (ref < 0 || ref >= 65536) { - throw new IllegalArgumentException(); - } - - if (!isLocked()) { - synchronized (inputRegisters) { - if (ref < inputRegisters.size()) { - inputRegisters.setElementAt(inReg, ref); - return; - } - inputRegisters.setSize(ref + 1); - inputRegisters.setElementAt(inReg, ref); - } - } - } - - public void removeInputRegister(InputRegister reg) { - if (!isLocked()) { - inputRegisters.removeElement(reg); - } - } - - public void setRegister(int ref, Register reg) throws IllegalAddressException { - if (!isLocked()) { - try { - if (registers.get(ref) == null) { - throw new IllegalAddressException(); - } - - registers.setElementAt(reg, ref); - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - } - - public void addRegister(Register reg) { - if (!isLocked()) { - registers.addElement(reg); - } - } - - public void addRegister(int ref, Register reg) { - if (ref < 0 || ref >= 65536) { - throw new IllegalArgumentException(); - } - - if (!isLocked()) { - synchronized (registers) { - if (ref < registers.size()) { - registers.setElementAt(reg, ref); - return; - } - registers.setSize(ref + 1); - registers.setElementAt(reg, ref); - } - } - } - - public void removeRegister(Register reg) { - if (!isLocked()) { - registers.removeElement(reg); - } - } - - public void setFile(int fileNumber, File file) { - if (!isLocked()) { - try { - if (files.get(fileNumber) == null) { - throw new IllegalAddressException(); - } - - files.setElementAt(file, fileNumber); - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - } - - public void addFile(File newFile) { - if (!isLocked()) { - files.add(newFile); - } - } - - public void addFile(int ref, File newFile) { - if (ref < 0 || ref >= 65536) { - throw new IllegalArgumentException(); - } - - if (!isLocked()) { - synchronized (files) { - if (ref < files.size()) { - files.setElementAt(newFile, ref); - return; - } - files.setSize(ref + 1); - files.setElementAt(newFile, ref); - } - } - } - - public void removeFile(File oldFile) { - if (!isLocked()) { - files.removeElement(oldFile); - } - } - - public void setFIFO(int fifoNumber, FIFO fifo) { - if (!isLocked()) { - try { - if (fifos.get(fifoNumber) == null) { - throw new IllegalAddressException(); - } - - fifos.setElementAt(fifo, fifoNumber); - } - catch (IndexOutOfBoundsException ex) { - throw new IllegalAddressException(); - } - } - } - - public void addFIFO(FIFO fifo) { - if (!isLocked()) { - fifos.add(fifo); - } - } - - public void addFIFO(int ref, FIFO newFIFO) { - if (ref < 0 || ref >= 65536) { - throw new IllegalArgumentException(); - } - - if (!isLocked()) { - synchronized (fifos) { - if (ref < fifos.size()) { - fifos.setElementAt(newFIFO, ref); - return; - } - fifos.setSize(ref + 1); - fifos.setElementAt(newFIFO, ref); - } - } - } - - public void removeFIFO(FIFO oldFIFO) { - if (!isLocked()) { - fifos.removeElement(oldFIFO); - } - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleRegister.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleRegister.java deleted file mode 100644 index 91e6df8..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SimpleRegister.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Class implementing a simple Register. - *

- * The setValue() method is synchronized, which ensures atomic access, * but no specific access order. - * - * @author Dieter Wimberger - * @author Julie Haugh - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class SimpleRegister extends SynchronizedAbstractRegister implements - Register { - - /** - * Constructs a new SimpleRegister instance. - * - * @param b1 the first (hi) byte of the word. - * @param b2 the second (low) byte of the word. - */ - public SimpleRegister(byte b1, byte b2) { - register[0] = b1; - register[1] = b2; - } - - /** - * Constructs a new SimpleRegister instance with the given value. - * - * @param value the value of this SimpleRegister as int. - */ - public SimpleRegister(int value) { - setValue(value); - } - - /** - * Constructs a new SimpleRegister instance. It's state will be - * invalid. - * - * Attempting to access this register will result in an - * IllegalAddressException(). It may be used to create "holes" in a Modbus - * register map. - */ - public SimpleRegister() { - register = null; - } - - public String toString() { - if (register == null) { - return "invalid"; - } - - return getValue() + ""; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SynchronizedAbstractRegister.java b/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SynchronizedAbstractRegister.java deleted file mode 100644 index ab6f5ae..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/procimg/SynchronizedAbstractRegister.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.procimg; - -/** - * Abstract class with synchronized register operations. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public abstract class SynchronizedAbstractRegister implements Register { - - /** - * The word (byte[2]) holding the state of this register. - * - * Note that a superclass may set register to null to create a - * gap in a Modbus map. - */ - protected byte[] register = new byte[2]; - - synchronized public int getValue() { - if (register == null) { - throw new IllegalAddressException(); - } - - return ((register[0] & 0xff) << 8 | (register[1] & 0xff)); - } - - public final int toUnsignedShort() { - if (register == null) { - throw new IllegalAddressException(); - } - - return ((register[0] & 0xff) << 8 | (register[1] & 0xff)); - } - - public final short toShort() { - if (register == null) { - throw new IllegalAddressException(); - } - - return (short)((register[0] << 8) | (register[1] & 0xff)); - } - - public synchronized byte[] toBytes() { - byte[] dest = new byte[register.length]; - System.arraycopy(register, 0, dest, 0, dest.length); - return dest; - } - - public final synchronized void setValue(short s) { - if (register == null) { - throw new IllegalAddressException(); - } - - register[0] = (byte)(0xff & (s >> 8)); - register[1] = (byte)(0xff & s); - } - - public final synchronized void setValue(byte[] bytes) { - if (bytes.length < 2) { - throw new IllegalArgumentException(); - } - else { - if (register == null) { - throw new IllegalAddressException(); - } - - register[0] = bytes[0]; - register[1] = bytes[1]; - } - } - - public final synchronized void setValue(int v) { - if (register == null) { - throw new IllegalAddressException(); - } - - register[0] = (byte)(0xff & (v >> 8)); - register[1] = (byte)(0xff & v); - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlave.java b/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlave.java deleted file mode 100644 index 55e94ce..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlave.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.slave; - -import com.ghgande.j2mod.modbus.ModbusException; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.net.ModbusTCPListener; -import com.ghgande.j2mod.modbus.net.ModbusUDPListener; -import com.ghgande.j2mod.modbus.procimg.ProcessImage; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import com.ghgande.j2mod.modbus.util.SerialParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.util.HashMap; -import java.util.Map; - -/** - * Class that implements a wrapper around a Slave Listener - * - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusSlave { - - private static final Logger logger = LoggerFactory.getLogger(ModbusSlave.class); - - private ModbusSlaveType type; - private int port; - private SerialParameters serialParams; - private AbstractModbusListener listener; - private boolean isRunning; - private Thread listenerThread; - - private Map processImages = new HashMap(); - - /** - * Creates a TCP modbus slave - * - * @param port Port to listen on if IP type - * @param poolSize Pool size for TCP slaves - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @throws ModbusException If a problem occurs e.g. port already in use - */ - protected ModbusSlave(int port, int poolSize, boolean useRtuOverTcp) throws ModbusException { - this(ModbusSlaveType.TCP, null, port, poolSize, null, useRtuOverTcp); - } - - /** - * Creates a TCP modbus slave - * - * @param address IP address to listen on - * @param port Port to listen on if IP type - * @param poolSize Pool size for TCP slaves - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @throws ModbusException If a problem occurs e.g. port already in use - */ - protected ModbusSlave(InetAddress address, int port, int poolSize, boolean useRtuOverTcp) throws ModbusException { - this(ModbusSlaveType.TCP, address, port, poolSize, null, useRtuOverTcp); - } - - /** - * Creates a UDP modbus slave - * - * @param port Port to listen on if IP type - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @throws ModbusException If a problem occurs e.g. port already in use - */ - protected ModbusSlave(int port, boolean useRtuOverTcp) throws ModbusException { - this(ModbusSlaveType.UDP, null, port, 0, null, useRtuOverTcp); - } - - /** - * Creates a UDP modbus slave - * - * @param address IP address to listen on - * @param port Port to listen on if IP type - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @throws ModbusException If a problem occurs e.g. port already in use - */ - protected ModbusSlave(InetAddress address, int port, boolean useRtuOverTcp) throws ModbusException { - this(ModbusSlaveType.UDP, address, port, 0, null, useRtuOverTcp); - } - - /** - * Creates a serial modbus slave - * - * @param serialParams Serial parameters for serial type slaves - * @throws ModbusException If a problem occurs e.g. port already in use - */ - protected ModbusSlave(SerialParameters serialParams) throws ModbusException { - this(ModbusSlaveType.SERIAL, null, 0, 0, serialParams, false); - } - - /** - * Creates an appropriate type of listener - * - * @param type Type of slave to create - * @param address IP address to listen on - * @param port Port to listen on if IP type - * @param poolSize Pool size for TCP slaves - * @param serialParams Serial parameters for serial type slaves - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @throws ModbusException If a problem occurs e.g. port already in use - */ - private ModbusSlave(ModbusSlaveType type, InetAddress address, int port, int poolSize, SerialParameters serialParams, boolean useRtuOverTcp) throws ModbusException { - this.type = type == null ? ModbusSlaveType.TCP : type; - this.port = port; - this.serialParams = serialParams; - - // Create the listener - - logger.debug("Creating {} listener", this.type.toString()); - if (this.type.is(ModbusSlaveType.UDP)) { - listener = new ModbusUDPListener(); - } - else if (this.type.is(ModbusSlaveType.TCP)) { - listener = new ModbusTCPListener(poolSize, useRtuOverTcp); - } - else { - // listener = new ModbusSerialListener(serialParams); - } - - listener.setListening(true); - listener.setAddress(address); - listener.setPort(port); - listener.setTimeout(0); - } - - /** - * Returns the type of this slave - * - * @return Type of slave - */ - public ModbusSlaveType getType() { - return type; - } - - /** - * Returns the port that this IP slave is listening on - * - * @return Port being listened on if TCP or UDP - */ - public int getPort() { - return port; - } - - /** - * Returns the process image for the given Unit ID - * - * @param unitId Unit ID of the associated image - * @return Process image - */ - public ProcessImage getProcessImage(int unitId) { - return processImages.get(unitId); - } - - /** - * Removes the process image for the given Unit ID - * - * @param unitId Unit ID of the associated image - * @return Process image - */ - public ProcessImage removeProcessImage(int unitId) { - return processImages.remove(unitId); - } - - /** - * Adds a process image for the given Unit ID - * - * @param unitId Unit ID to associate with this image - * @param processImage Process image to add - * @return Process image - */ - public ProcessImage addProcessImage(int unitId, ProcessImage processImage) { - return processImages.put(unitId, processImage); - } - - /** - * Returns the serial parameters of this slave if it is a Serial type - * - * @return Serial parameters - */ - public SerialParameters getSerialParams() { - return serialParams; - } - - /** - * Opens the listener to service requests - * - * @throws ModbusException If we cannot listen - */ - public void open() throws ModbusException { - - // Start the listener if it isn' already running - - if (!isRunning) { - try { - listenerThread = new Thread(listener); - listenerThread.start(); - isRunning = true; - } - catch (Exception x) { - closeListener(); - throw new ModbusException(x.getMessage()); - } - } - } - - /** - * Convenience method for closing this port and removing it from the running list - simply - * calls ModbusSlaveFactory.close(this) - */ - public void close() { - ModbusSlaveFactory.close(this); - } - - /** - * Returns the last error accrued by the listener - * - * @return Error if there is one - */ - public String getError() { - return listener != null ? listener.getError() : null; - } - - /** - * Returns the listener used for this port - * - * @return Listener - */ - protected AbstractModbusListener getListener() { - return listener; - } - - /** - * Closes the listener of this slave - */ - @SuppressWarnings("deprecation") - void closeListener() { - if (listener != null && listener.isListening()) { - listener.stop(); - - // Wait until the listener says it has stopped, but don't wait forever - int count = 0; - while (listenerThread != null && listenerThread.isAlive() && count < 50) { - ModbusUtil.sleep(100); - count++; - } - // If the listener is still not stopped, kill the thread - if (listenerThread != null && listenerThread.isAlive()) { - listenerThread.stop(); - } - listenerThread = null; - } - isRunning = false; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlaveFactory.java b/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlaveFactory.java deleted file mode 100644 index d8ad31a..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlaveFactory.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.slave; - -import com.ghgande.j2mod.modbus.ModbusException; -import com.ghgande.j2mod.modbus.net.AbstractModbusListener; -import com.ghgande.j2mod.modbus.util.ModbusUtil; -import com.ghgande.j2mod.modbus.util.SerialParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -/** - * This is a factory class that allows users to easily create and manage slaves.
- * Each slave is uniquely identified by the port it is listening on, irrespective of if - * the socket type (TCP, UDP or Serial) - * - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ModbusSlaveFactory { - - private static final Logger logger = LoggerFactory.getLogger(ModbusSlaveFactory.class); - private static Map slaves = new HashMap(); - - /** - * Creates a TCP modbus slave or returns the one already allocated to this port - * - * @param port Port to listen on - * @param poolSize Pool size of listener threads - * @return new or existing TCP modbus slave associated with the port - * - * @throws ModbusException If a problem occurs e.g. port already in use - */ - public static synchronized ModbusSlave createTCPSlave(int port, int poolSize) throws ModbusException { - return createTCPSlave(port, poolSize, false); - } - - /** - * Creates a TCP modbus slave or returns the one already allocated to this port - * - * @param port Port to listen on - * @param poolSize Pool size of listener threads - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @return new or existing TCP modbus slave associated with the port - * - * @throws ModbusException If a problem occurs e.g. port already in use - */ - public static synchronized ModbusSlave createTCPSlave(int port, int poolSize, boolean useRtuOverTcp) throws ModbusException { - return ModbusSlaveFactory.createTCPSlave(null, port, poolSize, useRtuOverTcp); - } - - /** - * Creates a TCP modbus slave or returns the one already allocated to this port - * - * @param address IP address to listen on - * @param port Port to listen on - * @param poolSize Pool size of listener threads - * @param useRtuOverTcp True if the RTU protocol should be used over TCP - * @return new or existing TCP modbus slave associated with the port - * - * @throws ModbusException If a problem occurs e.g. port already in use - */ - public static synchronized ModbusSlave createTCPSlave(InetAddress address, int port, int poolSize, boolean useRtuOverTcp) throws ModbusException { - String key = ModbusSlaveType.TCP.getKey(port); - if (slaves.containsKey(key)) { - return slaves.get(key); - } - else { - ModbusSlave slave = new ModbusSlave(address, port, poolSize, useRtuOverTcp); - slaves.put(key, slave); - return slave; - } - } - - /** - * Creates a UDP modbus slave or returns the one already allocated to this port - * - * @param port Port to listen on - * @return new or existing UDP modbus slave associated with the port - * - * @throws ModbusException If a problem occurs e.g. port already in use - */ - public static synchronized ModbusSlave createUDPSlave(int port) throws ModbusException { - return createUDPSlave(null, port); - } - - /** - * Creates a UDP modbus slave or returns the one already allocated to this port - * - * @param address IP address to listen on - * @param port Port to listen on - * @return new or existing UDP modbus slave associated with the port - * - * @throws ModbusException If a problem occurs e.g. port already in use - */ - public static synchronized ModbusSlave createUDPSlave(InetAddress address, int port) throws ModbusException { - String key = ModbusSlaveType.UDP.getKey(port); - if (slaves.containsKey(key)) { - return slaves.get(key); - } - else { - ModbusSlave slave = new ModbusSlave(address, port, false); - slaves.put(key, slave); - return slave; - } - } - - /** - * Creates a serial modbus slave or returns the one already allocated to this port - * - * @param serialParams Serial parameters for serial type slaves - * @return new or existing Serial modbus slave associated with the port - * - * @throws ModbusException If a problem occurs e.g. port already in use - */ - public static synchronized ModbusSlave createSerialSlave(SerialParameters serialParams) throws ModbusException { - ModbusSlave slave = null; - if (serialParams == null) { - throw new ModbusException("Serial parameters are null"); - } - else if (ModbusUtil.isBlank(serialParams.getPortName())) { - throw new ModbusException("Serial port name is empty"); - } - - // If we have a slave already assigned to this port - if (slaves.containsKey(serialParams.getPortName())) { - slave = slaves.get(serialParams.getPortName()); - - // Check if any of the parameters have changed - if (!serialParams.toString().equals(slave.getSerialParams().toString())) { - close(slave); - slave = null; - } - } - - // If we don;t have a slave, create one - if (slave == null) { - slave = new ModbusSlave(serialParams); - slaves.put(serialParams.getPortName(), slave); - return slave; - } - return slave; - } - - /** - * Closes this slave and removes it from the running list - * - * @param slave Slave to remove - */ - public static synchronized void close(ModbusSlave slave) { - if (slave != null) { - slave.closeListener(); - slaves.remove(slave.getType().getKey(slave.getPort())); - } - } - - /** - * Closes all slaves and removes them from the running list - */ - public static synchronized void close() { - for (ModbusSlave slave : new ArrayList(slaves.values())) { - slave.close(); - } - } - - /** - * Returns the running slave listening on the given IP port - * - * @param port Port to check for running slave - * @return Null or ModbusSlave - */ - public static ModbusSlave getSlave(int port) { - return slaves.get(port + ""); - } - - /** - * Returns the running slave listening on the given serial port - * - * @param port Port to check for running slave - * @return Null or ModbusSlave - */ - public static ModbusSlave getSlave(String port) { - return ModbusUtil.isBlank(port) ? null : slaves.get(port); - } - - /** - * Returns the running slave that utilises the give listener - * - * @param listener Listener used for this slave - * @return Null or ModbusSlave - */ - public static synchronized ModbusSlave getSlave(AbstractModbusListener listener) { - for (ModbusSlave slave : slaves.values()) { - if (slave.getListener().equals(listener)) { - return slave; - } - } - return null; - } - -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlaveType.java b/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlaveType.java deleted file mode 100644 index c993d15..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/slave/ModbusSlaveType.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.slave; - -import com.ghgande.j2mod.modbus.util.ModbusUtil; - -/** - * Descibes the types of Modbus Slaves - */ -public enum ModbusSlaveType { - TCP, UDP, SERIAL; - - /** - * Returns true if this type is one of those listed - * - * @param types Array of types to check for - * @return True if this is one of the array - */ - public boolean is(ModbusSlaveType... types) { - if (!ModbusUtil.isBlank(types)) { - for (ModbusSlaveType type : types) { - if (equals(type)) { - return true; - } - } - } - return false; - } - - /** - * Returns a unique key for this port and type - * - * @param port Port number - * @return Unique key - */ - public String getKey(int port) { - return toString() + port; - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/util/BitVector.java b/app/src/main/java/com/ghgande/j2mod/modbus/util/BitVector.java deleted file mode 100644 index ff82cf9..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/util/BitVector.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.util; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class that implements a collection for - * bits, storing them packed into bytes. - * Per default the access operations will index from - * the LSB (rightmost) bit. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class BitVector { - - private static final Logger logger = LoggerFactory.getLogger(BitVector.class); - private static final int[] ODD_OFFSETS = {-1, -3, -5, -7}; - private static final int[] STRAIGHT_OFFSETS = {7, 5, 3, 1}; - //instance attributes - private int size; - private byte[] data; - private boolean MSBAccess = false; - - /** - * Constructs a new BitVector instance - * with a given size. - *

- * - * @param size the number of bits the BitVector - * should be able to hold. - */ - public BitVector(int size) { - //store bits - this.size = size; - - //calculate size in bytes - if ((size % 8) > 0) { - size = (size / 8) + 1; - } - else { - size = (size / 8); - } - data = new byte[size]; - } - - /** - * Factory method for creating a BitVector instance - * wrapping the given byte data. - * - * @param data a byte[] containing packed bits. - * @param size Size to set the bit vector to - * - * @return the newly created BitVector instance. - */ - public static BitVector createBitVector(byte[] data, int size) { - BitVector bv = new BitVector(data.length * 8); - bv.setBytes(data); - bv.size = size; - return bv; - } - - /** - * Factory method for creating a BitVector instance - * wrapping the given byte data. - * - * @param data a byte[] containing packed bits. - * - * @return the newly created BitVector instance. - */ - public static BitVector createBitVector(byte[] data) { - BitVector bv = new BitVector(data.length * 8); - bv.setBytes(data); - return bv; - } - - public static void main(String[] args) { - BitVector test = new BitVector(24); - logger.debug(test.isLSBAccess() + ""); - test.setBit(7, true); - logger.debug(test.getBit(7) + ""); - test.toggleAccess(true); - logger.debug(test.getBit(7) + ""); - - test.toggleAccess(true); - test.setBit(6, true); - test.setBit(3, true); - test.setBit(2, true); - - test.setBit(0, true); - test.setBit(8, true); - test.setBit(10, true); - - logger.debug(test.toString()); - test.toggleAccess(true); - logger.debug(test.toString()); - test.toggleAccess(true); - logger.debug(test.toString()); - - logger.debug(ModbusUtil.toHex(test.getBytes())); - } - - /** - * Toggles the flag deciding whether the LSB - * or the MSB of the byte corresponds to the - * first bit (index=0). - * - * @param b true if LSB=0 up to MSB=7, false otherwise. - */ - public void toggleAccess(boolean b) { - MSBAccess = !MSBAccess; - } - - /** - * Tests if this BitVector has - * the LSB (rightmost) as the first bit - * (i.e. at index 0). - * - * @return true if LSB=0 up to MSB=7, false otherwise. - */ - public boolean isLSBAccess() { - return !MSBAccess; - } - - /** - * Tests if this BitVector has - * the MSB (leftmost) as the first bit - * (i.e. at index 0). - * - * @return true if LSB=0 up to MSB=7, false otherwise. - */ - public boolean isMSBAccess() { - return MSBAccess; - } - - /** - * Returns the byte[] which is used to store - * the bits of this BitVector. - *

- * - * @return the byte[] used to store the bits. - */ - public synchronized final byte[] getBytes() { - byte[] dest = new byte[data.length]; - System.arraycopy(data, 0, dest, 0, dest.length); - return dest; - } - - /** - * Sets the byte[] which stores - * the bits of this BitVector. - *

- * - * @param data a byte[]. - */ - public final void setBytes(byte[] data) { - System.arraycopy(data, 0, this.data, 0, data.length); - } - - /** - * Sets the byte[] which stores - * the bits of this BitVector. - *

- * - * @param data a byte[]. - * @param size Size to set the bit vector to - */ - public final void setBytes(byte[] data, int size) { - System.arraycopy(data, 0, this.data, 0, data.length); - this.size = size; - } - - /** - * Returns the state of the bit at the given index of this - * BitVector. - *

- * - * @param index the index of the bit to be returned. - * - * @return true if the bit at the specified index is set, - * false otherwise. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public final boolean getBit(int index) throws IndexOutOfBoundsException { - index = translateIndex(index); - logger.debug("Get bit #{}", index); - return ((data[byteIndex(index)] - & (0x01 << bitIndex(index))) != 0 - ); - } - - /** - * Sets the state of the bit at the given index of - * this BitVector. - *

- * - * @param index the index of the bit to be set. - * @param b true if the bit should be set, false if it should be reset. - * - * @throws IndexOutOfBoundsException if the index is out of bounds. - */ - public final void setBit(int index, boolean b) throws IndexOutOfBoundsException { - index = translateIndex(index); - logger.debug("Set bit #{}", index); - int value = ((b) ? 1 : 0); - int byteNum = byteIndex(index); - int bitNum = bitIndex(index); - data[byteNum] = (byte)((data[byteNum] & ~(0x01 << bitNum)) - | ((value & 0x01) << bitNum) - ); - } - - /** - * Returns the number of bits in this BitVector - * as int. - *

- * - * @return the number of bits in this BitVector. - */ - public final int size() { - return size; - } - - /** - * Forces the number of bits in this BitVector. - * - * @param size Size to set the bit vector to - * - * @throws IllegalArgumentException if the size exceeds - * the byte[] store size multiplied by 8. - */ - public final void forceSize(int size) { - if (size > data.length * 8) { - throw new IllegalArgumentException("Size exceeds byte[] store"); - } - else { - this.size = size; - } - } - - /** - * Returns the number of bytes used to store the - * collection of bits as int. - *

- * - * @return the number of bits in this BitVector. - */ - public final int byteSize() { - return data.length; - } - - /** - * Returns a String representing the - * contents of the bit collection in a way that - * can be printed to a screen or log. - *

- * Note that this representation will ALLWAYS - * show the MSB to the left and the LSB to the right - * in each byte. - * - * @return a String representing this BitVector. - */ - public String toString() { - StringBuilder sbuf = new StringBuilder(); - for (int i = 0; i < data.length; i++) { - - int numberOfBitsToPrint = Byte.SIZE; - int remainingBits = size - (i * Byte.SIZE); - if (remainingBits < Byte.SIZE) { - numberOfBitsToPrint = remainingBits; - } - - sbuf.append(String.format("%" + numberOfBitsToPrint + "s", Integer.toBinaryString(data[i] & 0xFF)).replace(' ', '0')); - sbuf.append(" "); - } - return sbuf.toString(); - } - - /** - * Returns the index of the byte in the the byte array - * that contains the given bit. - *

- * - * @param index the index of the bit. - * - * @return the index of the byte where the given bit is stored. - * - * @throws IndexOutOfBoundsException if index is - * out of bounds. - */ - private int byteIndex(int index) throws IndexOutOfBoundsException { - - if (index < 0 || index >= data.length * 8) { - throw new IndexOutOfBoundsException(); - } - else { - return index / 8; - } - } - - /** - * Returns the index of the given bit in the byte - * where it it stored. - *

- * - * @param index the index of the bit. - * - * @return the bit index relative to the position in the byte - * that stores the specified bit. - * - * @throws IndexOutOfBoundsException if index is - * out of bounds. - */ - private int bitIndex(int index) throws IndexOutOfBoundsException { - - if (index < 0 || index >= data.length * 8) { - throw new IndexOutOfBoundsException(); - } - else { - return index % 8; - } - } - - private int translateIndex(int idx) { - if (MSBAccess) { - int mod4 = idx % 4; - int div4 = idx / 4; - - if ((div4 % 2) != 0) { - //odd - return (idx + ODD_OFFSETS[mod4]); - } - else { - //straight - return (idx + STRAIGHT_OFFSETS[mod4]); - } - } - else { - return idx; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/util/ModbusUtil.java b/app/src/main/java/com/ghgande/j2mod/modbus/util/ModbusUtil.java deleted file mode 100644 index 66f5466..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/util/ModbusUtil.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.util; - -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.io.BytesOutputStream; -import com.ghgande.j2mod.modbus.msg.ModbusMessage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.List; - -/** - * Helper class that provides utility methods. - * - * @author Dieter Wimberger - * @author John Charlton - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public final class ModbusUtil { - - private static final Logger logger = LoggerFactory.getLogger(ModbusUtil.class); - - /* Table of CRC values for high-order byte */ - private final static short[] auchCRCHi = { - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 - }; - /* Table of CRC values for low-order byte */ - private final static short[] auchCRCLo = { - 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, - 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, - 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, - 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, - 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, - 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, - 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, - 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, - 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, - 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, - 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, - 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, - 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, - 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, - 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, - 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, - 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, - 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, - 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, - 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, - 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, - 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 - }; - - /** - * Converts a ModbusMessage instance into - * a hex encoded string representation. - * - * @param msg the message to be converted. - * - * @return the converted hex encoded string representation of the message. - */ - public static String toHex(ModbusMessage msg) { - BytesOutputStream byteOutputStream = new BytesOutputStream(Modbus.MAX_MESSAGE_LENGTH); - String ret = "-1"; - try { - msg.writeTo(byteOutputStream); - ret = toHex(byteOutputStream.getBuffer(), 0, byteOutputStream.size()); - } - catch (IOException ex) { - logger.debug("Hex conversion error {}", ex); - } - return ret; - } - - /** - * Returns the given byte[] as hex encoded string. - * - * @param data a byte[] array. - * - * @return a hex encoded String. - */ - public static String toHex(byte[] data) { - return toHex(data, 0, data.length); - } - - /** - * Returns a String containing unsigned hexadecimal - * numbers as digits. - * The String will coontain two hex digit characters - * for each byte from the passed in byte[].
- * The bytes will be separated by a space character. - * - * @param data the array of bytes to be converted into a hex-string. - * @param off the offset to start converting from. - * @param end the offset of the end of the byte array. - * - * @return the generated hexadecimal representation as String. - */ - public static String toHex(byte[] data, int off, int end) { - //double size, two bytes (hex range) for one byte - StringBuilder buf = new StringBuilder(data.length * 2); - if (end > data.length) { - end = data.length; - } - for (int i = off; i < end; i++) { - //don't forget the second hex digit - if (((int)data[i] & 0xff) < 0x10) { - buf.append("0"); - } - buf.append(Long.toString((int)data[i] & 0xff, 16).toUpperCase()); - if (i < end - 1) { - buf.append(" "); - } - } - return buf.toString(); - } - - /** - * Returns a byte[] containing the given - * byte as unsigned hexadecimal number digits. - * - * @param i the int to be converted into a hex string. - * - * @return the generated hexadecimal representation as byte[]. - */ - public static byte[] toHex(int i) { - StringBuilder buf = new StringBuilder(2); - //don't forget the second hex digit - if ((i & 0xff) < 0x10) { - buf.append("0"); - } - buf.append(Long.toString(i & 0xff, 16).toUpperCase()); - try { - return buf.toString().getBytes("US-ASCII"); - } - catch (Exception e) { - logger.debug("Problem converting bytes to string - {}", e.getMessage()); - } - return null; - } - - /** - * Converts the register (a 16 bit value) into an unsigned short. - * The value returned is: - * - *

(((a & 0xff) << 8) | (b & 0xff))
- * - * This conversion has been taken from the documentation of - * the DataInput interface. - * - * @param bytes a register as byte[2]. - * - * @return the unsigned short value as int. - * - * @see java.io.DataInput - */ - public static int registerToUnsignedShort(byte[] bytes) { - return ((bytes[0] & 0xff) << 8 | (bytes[1] & 0xff)); - } - - /** - * Converts the given unsigned short into a register - * (2 bytes). - * The byte values in the register, in the order - * shown, are: - * - *

-     * (byte)(0xff & (v >> 8))
-     * (byte)(0xff & v)
-     * 
- * - * This conversion has been taken from the documentation of - * the DataOutput interface. - * - * @param v Value to convert - * - * @return the register as byte[2]. - * - * @see java.io.DataOutput - */ - public static byte[] unsignedShortToRegister(int v) { - byte[] register = new byte[2]; - register[0] = (byte)(0xff & (v >> 8)); - register[1] = (byte)(0xff & v); - return register; - } - - /** - * Converts the given register (16-bit value) into - * a short. - * The value returned is: - * - *

-     * (short)((a << 8) | (b & 0xff))
-     * 
- * - * This conversion has been taken from the documentation of - * the DataInput interface. - * - * @param bytes bytes a register as byte[2]. - * - * @return the signed short as short. - */ - public static short registerToShort(byte[] bytes) { - return (short)((bytes[0] << 8) | (bytes[1] & 0xff)); - } - - /** - * Converts the register (16-bit value) at the given index - * into a short. - * The value returned is: - * - *

-     * (short)((a << 8) | (b & 0xff))
-     * 
- * - * This conversion has been taken from the documentation of - * the DataInput interface. - * - * @param bytes a byte[] containing a short value. - * @param idx an offset into the given byte[]. - * - * @return the signed short as short. - */ - public static short registerToShort(byte[] bytes, int idx) { - return (short)((bytes[idx] << 8) | (bytes[idx + 1] & 0xff)); - } - - /** - * Converts the given short into a register - * (2 bytes). - * The byte values in the register, in the order - * shown, are: - * - *

-     * (byte)(0xff & (v >> 8))
-     * (byte)(0xff & v)
-     * 
- * - * @param s Value to convert - * - * @return a register containing the given short value. - */ - public static byte[] shortToRegister(short s) { - byte[] register = new byte[2]; - register[0] = (byte)(0xff & (s >> 8)); - register[1] = (byte)(0xff & s); - return register; - } - - /** - * Converts a byte[4] binary int value to a primitive int.
- * The value returned is: - * - *

-     * (((a & 0xff) << 24) | ((b & 0xff) << 16) |
-     *  ((c & 0xff) << 8) | (d & 0xff))
-     * 
- * - * @param bytes registers as byte[4]. - * - * @return the integer contained in the given register bytes. - */ - public static int registersToInt(byte[] bytes) { - return (((bytes[0] & 0xff) << 24) | - ((bytes[1] & 0xff) << 16) | - ((bytes[2] & 0xff) << 8) | - (bytes[3] & 0xff) - ); - } - - /** - * Converts an int value to a byte[4] array. - * - * @param v the value to be converted. - * - * @return a byte[4] containing the value. - */ - public static byte[] intToRegisters(int v) { - byte[] registers = new byte[4]; - registers[0] = (byte)(0xff & (v >> 24)); - registers[1] = (byte)(0xff & (v >> 16)); - registers[2] = (byte)(0xff & (v >> 8)); - registers[3] = (byte)(0xff & v); - return registers; - } - - /** - * Converts a byte[8] binary long value into a long - * primitive. - * - * @param bytes a byte[8] containing a long value. - * - * @return a long value. - */ - public static long registersToLong(byte[] bytes) { - return ((((long)(bytes[0] & 0xff) << 56) | - ((long)(bytes[1] & 0xff) << 48) | - ((long)(bytes[2] & 0xff) << 40) | - ((long)(bytes[3] & 0xff) << 32) | - ((long)(bytes[4] & 0xff) << 24) | - ((long)(bytes[5] & 0xff) << 16) | - ((long)(bytes[6] & 0xff) << 8) | - ((long)(bytes[7] & 0xff))) - ); - } - - /** - * Converts a long value to a byte[8]. - * - * @param v the value to be converted. - * - * @return a byte[8] containing the long value. - */ - public static byte[] longToRegisters(long v) { - byte[] registers = new byte[8]; - registers[0] = (byte)(0xff & (v >> 56)); - registers[1] = (byte)(0xff & (v >> 48)); - registers[2] = (byte)(0xff & (v >> 40)); - registers[3] = (byte)(0xff & (v >> 32)); - registers[4] = (byte)(0xff & (v >> 24)); - registers[5] = (byte)(0xff & (v >> 16)); - registers[6] = (byte)(0xff & (v >> 8)); - registers[7] = (byte)(0xff & v); - return registers; - } - - /** - * Converts a byte[4] binary float value to a float primitive. - * - * @param bytes the byte[4] containing the float value. - * - * @return a float value. - */ - public static float registersToFloat(byte[] bytes) { - return Float.intBitsToFloat((((bytes[0] & 0xff) << 24) | - ((bytes[1] & 0xff) << 16) | - ((bytes[2] & 0xff) << 8) | - (bytes[3] & 0xff) - )); - } - - /** - * Converts a float value to a byte[4] binary float value. - * - * @param f the float to be converted. - * - * @return a byte[4] containing the float value. - */ - public static byte[] floatToRegisters(float f) { - return intToRegisters(Float.floatToIntBits(f)); - } - - /** - * Converts a byte[8] binary double value into a double primitive. - * - * @param bytes a byte[8] to be converted. - * - * @return a double value. - */ - public static double registersToDouble(byte[] bytes) { - return Double.longBitsToDouble(((((long)(bytes[0] & 0xff) << 56) | - ((long)(bytes[1] & 0xff) << 48) | - ((long)(bytes[2] & 0xff) << 40) | - ((long)(bytes[3] & 0xff) << 32) | - ((long)(bytes[4] & 0xff) << 24) | - ((long)(bytes[5] & 0xff) << 16) | - ((long)(bytes[6] & 0xff) << 8) | - ((long)(bytes[7] & 0xff))) - )); - } - - /** - * Converts a double value to a byte[8]. - * - * @param d the double to be converted. - * - * @return a byte[8]. - */ - public static byte[] doubleToRegisters(double d) { - return longToRegisters(Double.doubleToLongBits(d)); - } - - /** - * Converts an unsigned byte to an integer. - * - * @param b the byte to be converted. - * - * @return an integer containing the unsigned byte value. - */ - public static int unsignedByteToInt(byte b) { - return (int)b & 0xFF; - } - - /** - * Returns the low byte of an integer word. - * - * @param wd word to get low byte from - * - * @return low byte of word - */ - public static byte lowByte(int wd) { - return Integer.valueOf(0xff & wd).byteValue(); - } - - /** - * @param wd word to get high byte from - * - * @return high byte - */ - public static byte hiByte(int wd) { - return Integer.valueOf(0xff & (wd >> 8)).byteValue(); - } - - /** - * Makes a word from 2 bytes - * - * @param hibyte High byte - * @param lowbyte Low byte - * - * @return Word - */ - public static int makeWord(int hibyte, int lowbyte) { - int hi = 0xFF & hibyte; - int low = 0xFF & lowbyte; - return ((hi << 8) | low); - } - - public static int[] calculateCRC(byte[] data, int offset, int len) { - - int[] crc = {0xFF, 0xFF}; - int nextByte; - int uIndex; /* will index into CRC lookup*/ /* table */ - /* pass through message buffer */ - for (int i = offset; i < len && i < data.length; i++) { - nextByte = 0xFF & ((int)data[i]); - uIndex = crc[0] ^ nextByte; //*puchMsg++; /* calculate the CRC */ - crc[0] = crc[1] ^ auchCRCHi[uIndex]; - crc[1] = auchCRCLo[uIndex]; - } - - return crc; - } - - /** - * Return true if the string is null or empty - * - * @param value String to check - * @return True if the value is blank or empty - */ - public static boolean isBlank(String value) { - return value == null || value.isEmpty(); - } - - /** - * Return true if the list is null or empty - * - * @param list List to check - * @return True if the list is blank or empty - */ - public static boolean isBlank(List list) { - return list == null || list.isEmpty(); - } - - /** - * Return true if the array is null or empty - * - * @param list Array to check - * @return True if the array is blank or empty - */ - public static boolean isBlank(Object[] list) { - return list == null || list.length == 0; - } - - /** - * Sleeps safely for the specified amount of time unless awoken by an interruption - * - * @param time Time in milliseconds - */ - public static void sleep(long time) { - try { - Thread.sleep(time); - } - catch (InterruptedException ex) { - logger.warn("Backout sleep timer has been interrupted"); - } - - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/util/Observable.java b/app/src/main/java/com/ghgande/j2mod/modbus/util/Observable.java deleted file mode 100644 index a7861ff..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/util/Observable.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.util; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Vector; - -/** - * A cleanroom implementation of the Observable pattern. - * - * @author Dieter Wimberger (wimpi) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class Observable { - - private static final Logger logger = LoggerFactory.getLogger(Observable.class); - - private Vector observers; - - /** - * Constructs a new Observable instance. - */ - public Observable() { - observers = new Vector(10); - } - - public synchronized int getObserverCount() { - return observers.size(); - } - - /** - * Adds an observer instance if it is not already in the set of observers - * for this Observable. - * - * @param o an observer instance to be added. - */ - public synchronized void addObserver(Observer o) { - if (!observers.contains(o)) { - observers.addElement(o); - } - } - - /** - * Removes an observer instance from the set of observers of this - * Observable. - * - * @param o an observer instance to be removed. - */ - public synchronized void removeObserver(Observer o) { - observers.removeElement(o); - } - - /** - * Removes all observer instances from the set of observers of this - * Observable. - */ - public synchronized void removeObservers() { - observers.removeAllElements(); - } - - /** - * Notifies all observer instances in the set of observers of this - * Observable. - * - * @param arg an arbitrary argument to be passed. - */ - public synchronized void notifyObservers(Object arg) { - for (int i = 0; i < observers.size(); i++) { - observers.elementAt(i).update(this, arg); - } - } -} diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/util/Observer.java b/app/src/main/java/com/ghgande/j2mod/modbus/util/Observer.java deleted file mode 100644 index 46d0466..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/util/Observer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.util; - -/** - * A cleanroom implementation of the Observer interface - * for the Observable design pattern. - * - * @author Dieter Wimberger (wimpi) - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public interface Observer { - - /** - * Updates the state of this Observer to be in - * synch with an Observable instance. - * The argument should usually be an indication of the - * aspects that changed in the Observable. - * - * @param o an Observable instance. - * @param arg an arbitrary argument to be passed. - */ - void update(Observable o, Object arg); - -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/util/SerialParameters.java b/app/src/main/java/com/ghgande/j2mod/modbus/util/SerialParameters.java deleted file mode 100644 index 80c9011..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/util/SerialParameters.java +++ /dev/null @@ -1,557 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.util; -import com.ghgande.j2mod.modbus.Modbus; -import com.ghgande.j2mod.modbus.net.AbstractSerialConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Properties; - -/** - * Helper class wrapping all serial port communication parameters. - * Very similar to the javax.comm demos, however, not the same. - * - * @author Dieter Wimberger - * @author John Charlton - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class SerialParameters { - - private static final Logger logger = LoggerFactory.getLogger(SerialParameters.class); - - //instance attributes - private String portName; - private int baudRate; - private int flowControlIn; - private int flowControlOut; - private int databits; - private int stopbits; - private int parity; - private String encoding; - private boolean echo; - private int openDelay; - - /** - * Constructs a new SerialParameters instance with - * default values. - */ - public SerialParameters() { - portName = ""; - baudRate = 9600; - flowControlIn = AbstractSerialConnection.FLOW_CONTROL_DISABLED; - flowControlOut = AbstractSerialConnection.FLOW_CONTROL_DISABLED; - databits = 8; - stopbits = AbstractSerialConnection.ONE_STOP_BIT; - parity = AbstractSerialConnection.NO_PARITY; - encoding = Modbus.DEFAULT_SERIAL_ENCODING; - echo = false; - openDelay = AbstractSerialConnection.OPEN_DELAY; - } - - /** - * Constructs a new SerialParameters instance with - * given parameters. - * - * @param portName The name of the port. - * @param baudRate The baud rate. - * @param flowControlIn Type of flow control for receiving. - * @param flowControlOut Type of flow control for sending. - * @param databits The number of data bits. - * @param stopbits The number of stop bits. - * @param parity The type of parity. - * @param echo Flag for setting the RS485 echo mode. - */ - public SerialParameters(String portName, int baudRate, - int flowControlIn, - int flowControlOut, - int databits, - int stopbits, - int parity, - boolean echo) { - this.portName = portName; - this.baudRate = baudRate; - this.flowControlIn = flowControlIn; - this.flowControlOut = flowControlOut; - this.databits = databits; - this.stopbits = stopbits; - this.parity = parity; - this.echo = echo; - } - - /** - * Constructs a new SerialParameters instance with - * parameters obtained from a Properties instance. - * - * @param props a Properties instance. - * @param prefix a prefix for the properties keys if embedded into - * other properties. - */ - public SerialParameters(Properties props, String prefix) { - if (prefix == null) { - prefix = ""; - } - setPortName(props.getProperty(prefix + "portName", "")); - setBaudRate(props.getProperty(prefix + "baudRate", "" + 9600)); - setFlowControlIn(props.getProperty(prefix + "flowControlIn", "" + AbstractSerialConnection.FLOW_CONTROL_DISABLED)); - setFlowControlOut(props.getProperty(prefix + "flowControlOut", "" + AbstractSerialConnection.FLOW_CONTROL_DISABLED)); - setParity(props.getProperty(prefix + "parity", "" + AbstractSerialConnection.NO_PARITY)); - setDatabits(props.getProperty(prefix + "databits", "8")); - setStopbits(props.getProperty(prefix + "stopbits", "" + AbstractSerialConnection.ONE_STOP_BIT)); - setEncoding(props.getProperty(prefix + "encoding", Modbus.DEFAULT_SERIAL_ENCODING)); - setEcho("true".equals(props.getProperty(prefix + "echo"))); - setOpenDelay(props.getProperty(prefix + "openDelay", "" + AbstractSerialConnection.OPEN_DELAY)); - } - - /** - * Returns the port name. - * - * @return the port name. - */ - public String getPortName() { - return portName; - } - - /** - * Sets the port name. - * - * @param name the new port name. - */ - public void setPortName(String name) { - portName = name; - } - - /** - * Sets the baud rate. - * - * @param rate the new baud rate. - */ - public void setBaudRate(int rate) { - baudRate = rate; - } - - /** - * Return the baud rate as int. - * - * @return the baud rate as int. - */ - public int getBaudRate() { - return baudRate; - } - - /** - * Sets the baud rate. - * - * @param rate the new baud rate. - */ - public void setBaudRate(String rate) { - baudRate = Integer.parseInt(rate); - } - - /** - * Returns the baud rate as a String. - * - * @return the baud rate as String. - */ - public String getBaudRateString() { - return Integer.toString(baudRate); - } - - /** - * Sets the type of flow control for the input - * as given by the passed in int. - * - * @param flowcontrol the new flow control type. - */ - public void setFlowControlIn(int flowcontrol) { - flowControlIn = flowcontrol; - } - - /** - * Returns the input flow control type as int. - * - * @return the input flow control type as int. - */ - public int getFlowControlIn() { - return flowControlIn; - } - - /** - * Sets the type of flow control for the input - * as given by the passed in String. - * - * @param flowcontrol the flow control for reading type. - */ - public void setFlowControlIn(String flowcontrol) { - flowControlIn = stringToFlow(flowcontrol); - } - - /** - * Returns the input flow control type as String. - * - * @return the input flow control type as String. - */ - public String getFlowControlInString() { - return flowToString(flowControlIn); - } - - /** - * Sets the output flow control type as given - * by the passed in int. - * - * @param flowControlOut new output flow control type as int. - */ - public void setFlowControlOut(int flowControlOut) { - this.flowControlOut = flowControlOut; - } - - /** - * Returns the output flow control type as int. - * - * @return the output flow control type as int. - */ - public int getFlowControlOut() { - return flowControlOut; - } - - /** - * Sets the output flow control type as given - * by the passed in String. - * - * @param flowControlOut the new output flow control type as String. - */ - public void setFlowControlOut(String flowControlOut) { - this.flowControlOut = stringToFlow(flowControlOut); - } - - /** - * Returns the output flow control type as String. - * - * @return the output flow control type as String. - */ - public String getFlowControlOutString() { - return flowToString(flowControlOut); - } - - /** - * Sets the number of data bits. - * - * @param databits the new number of data bits. - */ - public void setDatabits(int databits) { - this.databits = databits; - } - - /** - * Returns the number of data bits as int. - * - * @return the number of data bits as int. - */ - public int getDatabits() { - return databits; - } - - /** - * Sets the number of data bits from the given String. - * - * @param databits the new number of data bits as String. - */ - public void setDatabits(String databits) { - if (!ModbusUtil.isBlank(databits) && databits.matches("[0-9]+")) { - this.databits = Integer.parseInt(databits); - } - else { - this.databits = 8; - } - } - - /** - * Returns the number of data bits as String. - * - * @return the number of data bits as String. - */ - public String getDatabitsString() { - return databits + ""; - } - - /** - * Sets the number of stop bits. - * - * @param stopbits the new number of stop bits setting. - */ - public void setStopbits(int stopbits) { - this.stopbits = stopbits; - } - - /** - * Returns the number of stop bits as int. - * - * @return the number of stop bits as int. - */ - public int getStopbits() { - return stopbits; - } - - /** - * Sets the number of stop bits from the given String. - * - * @param stopbits the number of stop bits as String. - */ - public void setStopbits(String stopbits) { - if (ModbusUtil.isBlank(stopbits) || stopbits.equals("1")) { - this.stopbits = AbstractSerialConnection.ONE_STOP_BIT; - } - else if (stopbits.equals("1.5")) { - this.stopbits = AbstractSerialConnection.ONE_POINT_FIVE_STOP_BITS; - } - else if (stopbits.equals("2")) { - this.stopbits = AbstractSerialConnection.TWO_STOP_BITS; - } - } - - /** - * Returns the number of stop bits as String. - * - * @return the number of stop bits as String. - */ - public String getStopbitsString() { - switch (stopbits) { - case AbstractSerialConnection.ONE_STOP_BIT: - return "1"; - case AbstractSerialConnection.ONE_POINT_FIVE_STOP_BITS: - return "1.5"; - case AbstractSerialConnection.TWO_STOP_BITS: - return "2"; - default: - return "1"; - } - } - - /** - * Sets the parity schema. - * - * @param parity the new parity schema as int. - */ - public void setParity(int parity) { - this.parity = parity; - } - - /** - * Returns the parity schema as int. - * - * @return the parity schema as int. - */ - public int getParity() { - return parity; - } - - /** - * Sets the parity schema from the given - * String. - * - * @param parity the new parity schema as String. - */ - public void setParity(String parity) { - if (ModbusUtil.isBlank(parity) || parity.equalsIgnoreCase("none")) { - this.parity = AbstractSerialConnection.NO_PARITY; - } - else if (parity.equalsIgnoreCase("even")) { - this.parity = AbstractSerialConnection.EVEN_PARITY; - } - else if (parity.equalsIgnoreCase("odd")) { - this.parity = AbstractSerialConnection.ODD_PARITY; - } - else if (parity.equalsIgnoreCase("mark")) { - this.parity = AbstractSerialConnection.MARK_PARITY; - } - else if (parity.equalsIgnoreCase("space")) { - this.parity = AbstractSerialConnection.SPACE_PARITY; - } - else { - this.parity = AbstractSerialConnection.NO_PARITY; - } - } - - /** - * Returns the parity schema as String. - * - * @return the parity schema as String. - */ - public String getParityString() { - switch (parity) { - case AbstractSerialConnection.NO_PARITY: - return "none"; - case AbstractSerialConnection.EVEN_PARITY: - return "even"; - case AbstractSerialConnection.ODD_PARITY: - return "odd"; - case AbstractSerialConnection.MARK_PARITY: - return "mark"; - case AbstractSerialConnection.SPACE_PARITY: - return "space"; - default: - return "none"; - } - } - - /** - * Returns the encoding to be used. - * - * @return the encoding as string. - * - * @see Modbus#SERIAL_ENCODING_ASCII - * @see Modbus#SERIAL_ENCODING_RTU - */ - public String getEncoding() { - return encoding; - } - - /** - * Sets the encoding to be used. - * - * @param enc the encoding as string. - * @see Modbus#SERIAL_ENCODING_ASCII - * @see Modbus#SERIAL_ENCODING_RTU - */ - public void setEncoding(String enc) { - if (!ModbusUtil.isBlank(enc) && - (enc.equalsIgnoreCase(Modbus.SERIAL_ENCODING_ASCII) || enc.equalsIgnoreCase(Modbus.SERIAL_ENCODING_RTU))) { - encoding = enc; - } - else { - encoding = Modbus.DEFAULT_SERIAL_ENCODING; - } - } - - /** - * Get the Echo value. - * - * @return the Echo value. - */ - public boolean isEcho() { - return echo; - } - - /** - * Set the Echo value. - * - * @param newEcho The new Echo value. - */ - public void setEcho(boolean newEcho) { - echo = newEcho; - } - - /** - * Converts a String describing a flow control type to the - * int which is defined in SerialPort. - * - * @param flowcontrol the String describing the flow control type. - * @return the int describing the flow control type. - */ - private int stringToFlow(String flowcontrol) { - if (ModbusUtil.isBlank(flowcontrol) || flowcontrol.equalsIgnoreCase("none")) { - return AbstractSerialConnection.FLOW_CONTROL_DISABLED; - } - else if (flowcontrol.equalsIgnoreCase("xon/xoff out")) { - return AbstractSerialConnection.FLOW_CONTROL_XONXOFF_OUT_ENABLED; - } - else if (flowcontrol.equalsIgnoreCase("xon/xoff in")) { - return AbstractSerialConnection.FLOW_CONTROL_XONXOFF_IN_ENABLED; - } - else if (flowcontrol.equalsIgnoreCase("rts/cts")) { - return AbstractSerialConnection.FLOW_CONTROL_CTS_ENABLED | AbstractSerialConnection.FLOW_CONTROL_RTS_ENABLED; - } - else if (flowcontrol.equalsIgnoreCase("dsr/dtr")) { - return AbstractSerialConnection.FLOW_CONTROL_DSR_ENABLED | AbstractSerialConnection.FLOW_CONTROL_DTR_ENABLED; - } - return AbstractSerialConnection.FLOW_CONTROL_DISABLED; - } - - /** - * Converts an int describing a flow control type to a - * String describing a flow control type. - * - * @param flowcontrol the int describing the - * flow control type. - * @return the String describing the flow control type. - */ - private String flowToString(int flowcontrol) { - switch (flowcontrol) { - case AbstractSerialConnection.FLOW_CONTROL_DISABLED: - return "none"; - case AbstractSerialConnection.FLOW_CONTROL_XONXOFF_OUT_ENABLED: - return "xon/xoff out"; - case AbstractSerialConnection.FLOW_CONTROL_XONXOFF_IN_ENABLED: - return "xon/xoff in"; - case AbstractSerialConnection.FLOW_CONTROL_CTS_ENABLED: - return "rts/cts"; - case AbstractSerialConnection.FLOW_CONTROL_DTR_ENABLED: - return "dsr/dtr"; - default: - return "none"; - } - } - - /** - * Gets the open delay used to prevent some OS from losing the comms port - * - * @return Sleep before an open is attempted on a comms port - */ - public int getOpenDelay() { - return openDelay; - } - - /** - * Sets the sleep time tat occurs just prior to opening a coms port - * Some OS don't like to have their comms ports opened/closed in very quick succession - * particularly, virtual ports. This delay is a rather crude way of stopping the problem that - * a comms port doesn't re-appear immediately after a close - * - * @param openDelay Sleep time in millieseconds - */ - public void setOpenDelay(int openDelay) { - this.openDelay = openDelay; - } - - /** - * Sets the sleep time tat occurs just prior to opening a coms port - * Some OS don't like to have their comms ports opened/closed in very quick succession - * particularly, virtual ports. This delay is a rather crude way of stopping the problem that - * a comms port doesn't re-appear immediately after a close - * - * @param openDelay Sleep time in millieseconds - */ - public void setOpenDelay(String openDelay) { - this.openDelay = Integer.parseInt(openDelay); - } - - @Override - public String toString() { - return "SerialParameters{" + - "portName='" + portName + '\'' + - ", baudRate=" + baudRate + - ", flowControlIn=" + flowControlIn + - ", flowControlOut=" + flowControlOut + - ", databits=" + databits + - ", stopbits=" + stopbits + - ", parity=" + parity + - ", encoding='" + encoding + '\'' + - ", echo=" + echo + - ", openDelay=" + openDelay + - '}'; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ghgande/j2mod/modbus/util/ThreadPool.java b/app/src/main/java/com/ghgande/j2mod/modbus/util/ThreadPool.java deleted file mode 100644 index 11055a0..0000000 --- a/app/src/main/java/com/ghgande/j2mod/modbus/util/ThreadPool.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2002-2016 jamod & j2mod development teams - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ghgande.j2mod.modbus.util; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * Class implementing a simple thread pool. - * - * @author Dieter Wimberger - * @author Steve O'Hara (4NG) - * @version 2.0 (March 2016) - */ -public class ThreadPool { - - private static final Logger logger = LoggerFactory.getLogger(ThreadPool.class); - - private LinkedBlockingQueue taskPool; - private List threadPool = new ArrayList(); - private int size = 1; - private boolean running; - - /** - * Constructs a new ThreadPool instance. - * - * @param size the size of the thread pool. - */ - public ThreadPool(int size) { - this.size = size; - taskPool = new LinkedBlockingQueue(); - initPool(); - } - - /** - * Execute the Runnable instance - * through a thread in this ThreadPool. - * - * @param task the Runnable to be executed. - */ - public synchronized void execute(Runnable task) { - if (running) { - try { - taskPool.put(task); - } - catch (InterruptedException ex) { - //FIXME: Handle!? - } - } - } - - /** - * Initializes the pool, populating it with - * n started threads. - */ - protected void initPool() { - running = true; - for (int i = size; --i >= 0; ) { - PoolThread thread = new PoolThread(); - threadPool.add(thread); - thread.start(); - } - } - - /** - * Shutdown the pool of threads - */ - public void close() { - if (running) { - taskPool.clear(); - running = false; - for (PoolThread thread : threadPool) { - thread.interrupt(); - } - } - } - - /** - * Inner class implementing a thread that can be - * run in a ThreadPool. - * - * @author Dieter Wimberger - * @version 1.2rc1 (09/11/2004) - */ - private class PoolThread extends Thread { - - /** - * Runs the PoolThread. - *

- * This method will infinitely loop, picking - * up available tasks from the LinkedQueue. - */ - public void run() { - logger.debug("Running PoolThread"); - do { - try { - logger.debug(this.toString()); - taskPool.take().run(); - } - catch (Exception ex) { - if (running) { - logger.error("Problem starting receiver thread", ex); - } - } - } while (running); - } - } - -} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/drawable/con1.xml b/app/src/main/res/drawable/con1.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/drawable/ls1.xml b/app/src/main/res/drawable/ls1.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/drawable/zyl1.xml b/app/src/main/res/drawable/zyl1.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/drawable/zyl2.xml b/app/src/main/res/drawable/zyl2.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/layout/activity_display_message.xml b/app/src/main/res/layout/activity_display_message.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/layout/activity_manual_drive.xml b/app/src/main/res/layout/activity_manual_drive.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/layout/activity_measurement.xml b/app/src/main/res/layout/activity_measurement.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png old mode 100644 new mode 100755 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml old mode 100644 new mode 100755 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml old mode 100644 new mode 100755 diff --git a/app/src/test/java/com/example/user/myapp/ExampleUnitTest.java b/app/src/test/java/com/example/user/myapp/ExampleUnitTest.java deleted file mode 100644 index 5d89d0d..0000000 --- a/app/src/test/java/com/example/user/myapp/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.user.myapp; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/build.gradle b/build.gradle old mode 100644 new mode 100755 diff --git a/documentation/Tag Liste.xlsx b/documentation/Tag Liste.xlsx old mode 100644 new mode 100755 diff --git a/documentation/doku.ods b/documentation/doku.ods old mode 100644 new mode 100755 diff --git a/gradle.properties b/gradle.properties old mode 100644 new mode 100755 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar old mode 100644 new mode 100755 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties old mode 100644 new mode 100755 diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 diff --git a/plc-program/Schauanlage-Elektropneumatik.mnp b/plc-program/Schauanlage-Elektropneumatik.mnp deleted file mode 100644 index 5228ea9..0000000 Binary files a/plc-program/Schauanlage-Elektropneumatik.mnp and /dev/null differ diff --git a/plc-program/V4/Schauanlage-Elektropneumatik.mnp b/plc-program/V4/Schauanlage-Elektropneumatik.mnp new file mode 100755 index 0000000..7b21fb3 Binary files /dev/null and b/plc-program/V4/Schauanlage-Elektropneumatik.mnp differ diff --git a/plc-program/V4/notizen b/plc-program/V4/notizen new file mode 100755 index 0000000..176b031 --- /dev/null +++ b/plc-program/V4/notizen @@ -0,0 +1,2 @@ +manual inhibitor von Pu2 ist inkorrekterweise auf I10 statt I11 gesetzt - wurde in V5 gefixt + diff --git a/plc-program/V5/Schauanlage-Elektropneumatik_V5.mnp b/plc-program/V5/Schauanlage-Elektropneumatik_V5.mnp new file mode 100755 index 0000000..eca8dc1 Binary files /dev/null and b/plc-program/V5/Schauanlage-Elektropneumatik_V5.mnp differ diff --git a/plc-program/network-inputs-udf.lma b/plc-program/network-inputs-udf.lma old mode 100644 new mode 100755 diff --git a/settings.gradle b/settings.gradle old mode 100644 new mode 100755