diff --git a/jni/natpmpclient.cpp b/jni/natpmpclient.cpp index 52b7bee..87005a6 100644 --- a/jni/natpmpclient.cpp +++ b/jni/natpmpclient.cpp @@ -1,5 +1,10 @@ +#include +#include +#include #include "beginvision.h" +#include "libnatpmp/natpmp.h" + #define JNIDEFINE(fname) Java_teaonly_droideye_MainActivity_##fname extern "C" { @@ -7,4 +12,81 @@ extern "C" { }; +jstring JNICALL JNIDEFINE(nativeQueryInternet)(JNIEnv* env, jclass clz) { + natpmp_t natpmp; + natpmpresp_t response; + std::string ipaddr; + uint16_t privatePort = 8080; + uint16_t publicPort = 7910; + uint32_t lifetime = 36000; // 10 hours + int protocol = NATPMP_PROTOCOL_TCP; + in_addr_t gateway = 0; + fd_set fds; + struct timeval timeout; + int ret; + std::string result = ""; + + // 1. init internal object + ret = initnatpmp(&natpmp, 0, gateway); + if (ret < 0) { + result = "error:gateway"; + goto _done; + } + + // 2. get internet public ip address + ret = sendpublicaddressrequest(&natpmp); + if ( ret != 2) { + result = "error:ipaddr"; + goto _done; + } + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + if(ret < 0) { + result = "error:select"; + goto _done; + } + ret = readnatpmpresponseorretry(&natpmp, &response); + if( ret == NATPMP_TRYAGAIN ) { + result = "error:timeout"; + goto _done; + } else if ( ret < 0) { + result = "error:failed"; + goto _done; + } + ipaddr = inet_ntoa(response.pnu.publicaddress.addr); + + // 3. set extern port mapping + ret = sendnewportmappingrequest(&natpmp, protocol, + privatePort, publicPort, + lifetime); + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + if(ret < 0) { + result = "error:select"; + goto _done; + } + ret = readnatpmpresponseorretry(&natpmp, &response); + if( ret == NATPMP_TRYAGAIN ) { + result = "error:timeout"; + goto _done; + } else if ( ret < 0) { + result = "error:failed"; + goto _done; + } + privatePort = response.pnu.newportmapping.privateport; + publicPort = response.pnu.newportmapping.mappedpublicport; + + { + std::stringstream stream; + stream << "http://" << ipaddr << ":" << publicPort; + result = stream.str(); + } + +_done: + return env->NewStringUTF(result.c_str()); +} diff --git a/res/layout/main.xml b/res/layout/main.xml index 06fd01e..73e1cc4 100644 --- a/res/layout/main.xml +++ b/res/layout/main.xml @@ -31,9 +31,19 @@ android:layout_width="fill_parent" android:gravity="center" android:background="#88333333" - android:orientation="horizontal"> + android:orientation="vertical"> + Wifi Camera - Setup - Close + Exit - Open URL in PC + Open at local: + Open at internet: + Detecting internet ... + Can not be opened at internet Error: Please enable wifi diff --git a/src/teaonly/droideye/MainActivity.java b/src/teaonly/droideye/MainActivity.java index fd8d05b..a8c4c17 100644 --- a/src/teaonly/droideye/MainActivity.java +++ b/src/teaonly/droideye/MainActivity.java @@ -72,7 +72,8 @@ public class MainActivity extends Activity private CameraView cameraView_; private OverlayView overlayView_; private Button btnExit; - private TextView tvMessage; + private TextView tvMessage1; + private TextView tvMessage2; private AudioRecord audioCapture = null; private StreamingLoop audioLoop = null; @@ -96,7 +97,8 @@ public void onCreate(Bundle savedInstanceState) { btnExit = (Button)findViewById(R.id.btn_exit); btnExit.setOnClickListener(exitAction); - tvMessage = (TextView)findViewById(R.id.tv_message); + tvMessage1 = (TextView)findViewById(R.id.tv_message1); + tvMessage2 = (TextView)findViewById(R.id.tv_message2); for(int i = 0; i < maxVideoNumber; i++) { videoFrames[i] = new VideoFrame(1024*1024*2); @@ -224,12 +226,16 @@ private boolean initWebServer() { } } if ( webServer != null) { - tvMessage.setText( getString(R.string.msg_access) + " http://" + ipAddr + ":8080" ); + tvMessage1.setText( getString(R.string.msg_access_local) + " http://" + ipAddr + ":8080" ); + tvMessage2.setText( getString(R.string.msg_access_query)); + tvMessage2.setVisibility(View.VISIBLE); return true; } else { - tvMessage.setText( getString(R.string.msg_error) ); + tvMessage1.setText( getString(R.string.msg_error) ); + tvMessage2.setVisibility(View.GONE); return false; } + } private OnClickListener exitAction = new OnClickListener() { @@ -414,5 +420,30 @@ public void run() { nativeCloseEncoder(); } } -} + + + static private native String nativeQueryInternet(); + private class NatPMPClinet extends Thread { + String ret = nativeQueryInternet(); + @Override + public void run(){ + Handler handleQueryResult = new Handler(getMainLooper()); + if ( ret.startsWith("error:") ) { + handleQueryResult.post( new Runnable() { + @Override + public void run() { + tvMessage2.setText( getString(R.string.msg_access_query_error)); + } + }); + } else { + handleQueryResult.post( new Runnable() { + @Override + public void run() { + tvMessage2.setText( getString(R.string.msg_access_internet) + " " + ret ); + } + }); + } + } + } +}