- Search the download area for your version of OpenWrt's packages folder
- Then use your browser's find in page and look for "DDNS"
- There will be three hits; the first two start with:
luci-ddns
ddns-scripts - SCP these files to the router (I use WinSCP).
- SSH to the router (I use Putty) and type:
opkg install ddns{tab} luci-{tab} - Now you can edit the DDNS settings either via the web browser (click the services tab) or
vi /etc/config/ddns - Make sure to click the "Enable" checkbox and set enabled equal to 1 in the config file!
- At this point you could stop and hope it works, but more likely than not it wont.
- Try to run the update script and see what happens:
/usr/lib/ddns/dynamic_dns_updater.sh myddns - This script uses BusyBox's wget to call the DDNS service. However, whoever put the sed replacements together must use "1234" as their password because just about any special character gets escaped wrong and break DDNS updating.
Even my email address did not work.
Luckily with dyndns you can use a username as well-- I set mine to have no special characters.
There are a number of fixes you can make to the script instead (see first 3 results).
Friday, January 25, 2013
Dynamic DNS on OpenWrt
Thursday, June 28, 2012
Cross Site Scripting PHP Proxy
I needed to access a REST web service from jQuery, but Chrome would throw an error during the ajax call due to the "origin" policy. It's possible to setup a CORS filter with Tomcat and Apache, but that sounded like a lot of work.
Instead, if you can use PHP, just download the following PHP proxy:
https://github.com/developerforce/Force.com-JavaScript-REST-Toolkit/blob/master/proxy.php
Two changes are needed:
Instead, if you can use PHP, just download the following PHP proxy:
https://github.com/developerforce/Force.com-JavaScript-REST-Toolkit/blob/master/proxy.php
Two changes are needed:
- Edit line 176 such that it reads $url_query_param = 'url';
- Either fix the regexp at lines 172 and 173 which checks that the call is to sales force.com (set it to match your website) or comment out lines 206 to 212 (potentially dangerous).
var req = $.ajax({
type: 'GET',
contentType: 'application/json',
mimeType: 'application/json',
url: 'http://proxy-server/app/proxy.php?mode=native&url=http://api-server/api/object/'+$("#objectID").val(),
dataType: 'json',
success: function(data, textStatus, jqXHR) {
alert("Got data successfully");
$('#responseData').text(JSON.stringify(data));
},
error: function(xhr, textStatus, error) {
alert("Error: " + textStatus);
}
});
That's it!
Thursday, March 15, 2012
Monday, March 12, 2012
Fun Android camera gotcha
Android's camera object includes a method called takePicture which takes 3 callbacks as arguments:
1) shutter callback
2) raw callback
3) jpeg callback
The shutter callback occurs roughly when the shutter sound occurs in the stock camera.
Raw callback and jpeg callback occur when camera image data is available. Well, RAW > JPEG, right? So why not just implement RAW callback and skip JPEG callback? If you code up the RAW callback, you'll find that you can't get an image from the returned data. The object is non-null, but upon further inspection has zero length. What did I do wrong? you'll think. Actually, nothing, it just doesn't work. Never has. Yet it's still there in the libraries and in the documentation after years and years, without any note or anything that it doesn't freaking work. Huh? (typical Android).
1) shutter callback
2) raw callback
3) jpeg callback
The shutter callback occurs roughly when the shutter sound occurs in the stock camera.
Raw callback and jpeg callback occur when camera image data is available. Well, RAW > JPEG, right? So why not just implement RAW callback and skip JPEG callback? If you code up the RAW callback, you'll find that you can't get an image from the returned data. The object is non-null, but upon further inspection has zero length. What did I do wrong? you'll think. Actually, nothing, it just doesn't work. Never has. Yet it's still there in the libraries and in the documentation after years and years, without any note or anything that it doesn't freaking work. Huh? (typical Android).
Monday, March 05, 2012
Sending Multipart Form Data from Java (and receiving it via PHP)
If you want to send binary data and some parameters, you'll need to execute a POST with the content type of multipart/form-data. This takes a different format than usual HTTP requests. The secret to sending multipart form data is sending the right number of line endings. Rather than explain it, here's the code.
Ok, now how to read this on the other end? Here's how to do it via PHP:
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
File temp_file = new File("foo.txt");
// open a URL connection
URL url = new URL(urlString);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
// Allow Inputs
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
// Don't use a cached copy.
conn.setUseCaches(false);
// Use a post method.
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
dos = new DataOutputStream( conn.getOutputStream() );
// Send parameter #1
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"param1\"" + lineEnd + lineEnd);
dos.writeBytes("foo1" + lineEnd);
// Send parameter #2
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"param2\"" + lineEnd + lineEnd);
dos.writeBytes("foo2" + lineEnd);
// Send a binary file
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + temp_file.getName() +"\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// close streams
fileInputStream.close();
dos.flush();
dos.close();
Ok, now how to read this on the other end? Here's how to do it via PHP:
// Make sure a binary file is attached to the POST
if(!$_FILES) {
echo "No file!"
}
$id = $_FILES['uploadedfile']['name'];
move_uploaded_file($_FILES['uploadedfile']['tmp_name'], "/permanent/location".$id);
// Uncomment next line to print out the array to a file
// file_put_contents("/permanent/location/".$id.".debug.txt", print_r($_POST, true));
$param1="";
$param2="";
if(isset($arguments['param1'])) {
$lat = $arguments['param1'];
}
if(isset($arguments['param2'])) {
$lon = $arguments['param2'];
}
echo "Uploaded " . $id . " with param1=" . $param1 . " and param2=" . $param2;
Android ProgressDialog and Threads
Many tasks require an application to get or post data from/to some web service. Since internet communication can be quick or quite lengthy, it's necessary to notify the user that some work is occurring. Android's ProgressDialog gives you two options: a dialog with a bar (like a copy dialog on Windows) or a spinner dialog (typical for Ajax web apps).
Unfortunately, using the progress dialog can be painful. Frustratingly, many tutorials show you how to instantiate a ProgressDialog but not how to use it properly, failing to mention that if you make a blocking call on the UI thread (like an HTTP request), the ProgressDialog will never actually appear. After 2 seconds, the Android OS will think your app has frozen and kill it. Great.
Many forum posts suggest using Android's AsyncTask to execute the "work" in the background (AsyncTask is supposed to be easier to use than creating a new thread), but I've found AsyncTask to be more headache than help. Just create a thread. It's not hard.
FYI, ProgressDialog requires a context (the calling activity), a message to display, and a handler to do some work. Your handler can only receive ONE variable, so I tend to use a HashMap so I can pass multiple bits of data.
I've come up with a pattern that I've reused and works well. Here we go!
Unfortunately, using the progress dialog can be painful. Frustratingly, many tutorials show you how to instantiate a ProgressDialog but not how to use it properly, failing to mention that if you make a blocking call on the UI thread (like an HTTP request), the ProgressDialog will never actually appear. After 2 seconds, the Android OS will think your app has frozen and kill it. Great.
Many forum posts suggest using Android's AsyncTask to execute the "work" in the background (AsyncTask is supposed to be easier to use than creating a new thread), but I've found AsyncTask to be more headache than help. Just create a thread. It's not hard.
FYI, ProgressDialog requires a context (the calling activity), a message to display, and a handler to do some work. Your handler can only receive ONE variable, so I tend to use a HashMap so I can pass multiple bits of data.
I've come up with a pattern that I've reused and works well. Here we go!
- Create a thread class.
- Add a thread and a null handler to your activity.
- Create the ProgressDialog in your Activity's onCreate
- Create a handler.
- Instantiate your worker thread
- Implement onPause for your activity to stop the worker thread if the activity is paused(and possibly onResume-- though be aware that onResume will be called before onCreate)
public class WorkerThread extends Thread {
private ProgressDialog dialog;
private Handler handler;
private HashMap messageData = new HashMap();
// .. put your constructor etc here ...
public WorkerThread(ProgressDialog dialog, Handler handler) {
this.dialog = dialog;
this.handler = handler;
}
public void run() {
// Var to keep track of whether the work succeeded or not
Boolean status = true;
// ... do some work here ...
// If an error occurred...
if(error) {
status = false;
messageData.put("message", "Error message goes here");
}
messageData.put("status", status);
// Send a message back to calling activity
handler.obtainMessage(0x2a, messageData).sendToTarget();
// Dismiss dialog
if (dialog != null && dialog.isShowing())
dialog.dismiss();
}
// Clean up if the thread is cancelled
public void cancel() {
messageData.put("status", false);
handler.obtainMessage(0x2a, messageData).sendToTarget();
if (dialog != null && dialog.isShowing())
dialog.dismiss();
}
}WorkerThread WorkerThreadInstance = null;
Handler handler = null;
ProgressDialog workDialog = ProgressDialog.show(this, "", "Working...", true);
// Handle response from the worker thread
handler = new Handler() {
@SuppressWarnings("unchecked")
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
HashMap data = (HashMap) msg.obj;
Boolean status = (Boolean) data.get("status");
if (status==true) {// if successful
Toast.makeText(getApplicationContext(), "Work was successful",
2000).show();
// Process return data here
// Uncomment the next line if your activity should end once processing is done
//finish();
} else {
if(data.get("message")!=null) {
Toast.makeText(getApplicationContext(), "Work failed!" + data.get("message") ,
3000).show();
}
// Uncomment the next line if your activity should end after an error
//finish();
}
}
};
// Create an instance of the worker thread
WorkerThreadInstance = new WorkerThread(workDialog, handler);
WorkerThreadInstance.start();
@Override
public void onPause() {
super.onPause();
if (WorkerThreadInstance != null) {
WorkerThreadInstance.cancel();
// Mark thread for deletion by GC or there will be a memory leak
WorkerThreadInstance = null;
}
}
Android ListView
Android includes a ListView element designed to make it easy to create lists. But it's not as straightforward as adding a ListView element and then calling some add function. You will need to create an "ArrayAdapter" and a couple of layout XML files, unless you want to create a simple list of strings (change your activity from extending Activity to ListActivity and use the default array adapter).
Rather than explain the process, I refer you to a great tutorial which be found here.
Rather than explain the process, I refer you to a great tutorial which be found here.
Tuesday, November 08, 2011
Using an AVR ISP Mk II with the Arduino IDE
It is possible to program an AVR on an Arduino board using the AVR ISP Mk II programmer directly from the Arduino IDE. The process is faster and an Arduino bootloader is not required to be loaded on the AVR, so you can program AVRs purchased from Mouser, Digikey, etc and then transfer them to a permanent circuit board.
Simply edit boards.txt (location varies-- try searching your root arduino software folder) and add:
atmega328ii.name=Arduino Duemilanove ATmega328 AVR ISP Mk II
atmega328ii.upload.protocol=stk500
atmega328ii.upload.maximum_size=30720
atmega328ii.upload.speed=57600
atmega328ii.upload.using=avrispmkii
atmega328ii.build.mcu=atmega328p
atmega328ii.build.f_cpu=16000000L
atmega328ii.build.core=arduino
##############################################################
Then you can go to Tools>Boards> and select ATMega 328 ISP from the list. Attach your AVR ISP Mk II to the Arduino board (make sure the orientation is correct-- both of the AVR and the ISP cable). Hit program as normal. Voila!
Friday, October 14, 2011
CSS Radial Backgrounds
CSS3 allows you to make radial gradients fairly easily. Unfortunately, you need six lines to cover all the browsers that support CSS3, but luckily all but the old webkit syntax are very similar.
Full Screen Background Image with CSS
Since the height attribute doesn't work so well in CSS backgrounds (100% will not actually cause your background image to scale to the full height of the window, for example), if you want a full screen background you'll have to go another route. Luckily, this solution is written up cleanly:
http://paulmason.name/blog/item/full-screen-background-image-pure-css-codeSimply copy #full-screen-background-image and you're good to go. The styling also works for DIVs.
Subscribe to:
Posts (Atom)
Labels
- Java (34)
- Oracle (27)
- javascript (24)
- NIX administration (19)
- Reporting (18)
- XML (17)
- Web Graphics (10)
- perl (10)
- CSS (9)
- Tomcat (8)
- Android (7)
- Matlab (7)
- XSL (7)
- HTML (6)
- SQL (6)
- XForms (6)
- browser quirks (6)
- Orbeon XForms (5)
- Solaris (5)
- AJAX (4)
- Mirth Project (4)
- PHP (4)
- Video (4)
- Arduino (3)
- Eclipse (3)
- JPA (3)
- JSP (3)
- JSTL (3)
- LAMPS (3)
- SSH (3)
- SVN (3)
- Hibernate (2)
- Netbeans (2)
- Networking (2)
- Python (2)
- Windows (2)
- Wordpress (2)
- XHTML (2)
- Alfresco (1)
- Architecture (1)
- ArduPilot (1)
- Arduino Yun (1)
- Arduplane (1)
- Audio Recording (1)
- Betaflight (1)
- CouchDB (1)
- DIY (1)
- Design (1)
- FPV (1)
- JSON (1)
- JUnit (1)
- Mobile Development (1)
- Printing (1)
- RC Airplane (1)
- REST (1)
- Scalability (1)
- Struts (1)
- Tools (1)
- Virtualization (1)
- Web services (1)
- camera (1)
- canon (1)
- gphoto2 (1)
- jQuery (1)
- ubuntu (1)
- unix (1)