tag:blogger.com,1999:blog-84335162787102515512024-03-19T15:28:07.295-07:00Tiriboy's Blog"Sit back and relax letz have a TechTalk !"rasikahttp://www.blogger.com/profile/06138246766449305805noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-8433516278710251551.post-38934126573300578422015-09-06T23:43:00.000-07:002015-09-06T23:45:10.583-07:00Fixing Raspberry Pi WiFi dropping issueMany of our Raspberry Pi projects needs remote accessibility. This means you spends lot of time using either VNC or SSH to access the Raspberry Pi. Unfortunately, when wifi connectivity drops and failed to re-connect your whole world stops right? On such situations, physically accessing the RPi and doing the restart is really a pain.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-A02lveHAuTI/Ve0x1orqtyI/AAAAAAAADgg/nfqBvu6W1KY/s1600/rpi%2Bwifi.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-A02lveHAuTI/Ve0x1orqtyI/AAAAAAAADgg/nfqBvu6W1KY/s320/rpi%2Bwifi.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<h3>
Writing checkwifi.sh</h3>
<br />
You can just copy paste this script into "/usr/local/bin/checkwifi.sh"<br />
<br />
<pre class="brush:bash">ping -c4 192.168.1.1 > /dev/null
if [ $? != 0 ]
then
echo "No network connection, restarting wlan0...!"
/sbin/ifdown 'wlan0'
sleep 5
/sbin/ifup --force 'wlan0'
fi
</pre>
<br />
What we are trying to do is, we are restarting the wireless interface. First it tries to ping a given IP with `ping` command.<br />
<br />
Then `$?` represents the exit code of the previous command. In our case, previous command is `ping`. If `ping` command fails will output a different exit code(not 0). Then the code part inside the `if` will be executed. It will turn off, wait 5 seconds and re-start the wireless interface `wlan0`.<br />
<br />
And make sure you have necessary execute permissions for the script.<br />
<br />
<pre class="brush:bash">sudo chmod 775 /usr/local/bin/checkwifi.sh
</pre>
<br />
<h3>
Adding a Cron Job</h3>
<br />
Open up the cron tab editor by `crontab -e` and add the following lines to the bottom of the file.
<br />
<pre class="brush:bash">*/5 * * * * /usr/bin/sudo -H /usr/local/bin/checkwifi.sh >> /dev/null 2>&1
</pre>
<br />
This script will run every 5 minutes with sudo permission. And the script's output is redirected to /dev/null hence won't clog your sys logs.
<br />
<h3>
Done</h3>
Everything is done! now restart your RPi and enjoy!
Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-50061541383535152612015-08-15T06:52:00.000-07:002015-08-15T06:52:36.298-07:00XMPP/Jabber for IoT Devices - Part 2<img border="0" src="http://1.bp.blogspot.com/-T8ioAEJwGvI/Vct1LqGq-oI/AAAAAAAADJ8/cIcMYFPP6vM/s320/xmpp.png" style="display: none;" />
From the <a href="http://tiriboy.blogspot.com/2015/08/xmppjabber-for-iot-devices-part-1.html">previous post</a> we discussed nuts and bolts of the XMPP(or Jabber) and how we can make use of it in the context of Internet-of-Things(IoT).
This blog post will demonstrate a sample implementation on XMPP using <b>unofficial official</b> <a href="http://wiki.xmpp.org/web/Tech_pages/IoT_XepsExplained">IoT XEPs(XMPP Extensions)</a>. These XMPP extensions are still in "Experimental" state at the time of writing this blog post.<br />
<br />
Today we will be using <a href="http://xmpp.org/extensions/xep-0030.html">XEP0030</a>(service discovery), <a href="http://xmpp.org/extensions/xep-0323.html">XEP0323</a>(IoT sensor data) and <a href="http://xmpp.org/extensions/xep-0325.html">XEP325</a>(IoT control) for this sample. We are using <a href="https://github.com/fritzy/SleekXMPP/wiki">SleekXMPP</a> python library as XMPP client which implements these XEPs.
<br />
<br />
<b>STEP 1:</b><br/>
First we need to setup a XMPP server. If you haven't setup any XMPP server; please follow <a href="http://tiriboy.blogspot.com/2015/08/setting-up-xmpp-openfire-server-rest-api.html">this blog post</a> which will describe "How to Setting up XMPP Openfire Server and expose via RESTful APIs". Please note that you can use a XMPP Server from any XMPP vendor. Here we use Openfire since it shipped with Apache Open Source license. Once you have setup Openfire server you need to create two user accounts "bob" and "alice". Our user story is that "alice" has a sensor device called "firealarm" and "bob" needs to get sensor information (e.g. temperature) of the "firealarm":D. Please refer the following image.
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-iRRWDorQsiE/Vc84vJDrCqI/AAAAAAAADQA/9eNmT0PFJoE/s1600/drawing2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="128" src="http://1.bp.blogspot.com/-iRRWDorQsiE/Vc84vJDrCqI/AAAAAAAADQA/9eNmT0PFJoE/s640/drawing2.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">How Bob can get sensor information from the Alice's Firealarm</td></tr>
</tbody></table>
<br />
<b>STEP 2:</b><br/>
Copy paste below python scripts into two files "xmpp_server.py" and "xmpp_client.py". Or you can directly download both scripts from <a href="https://goo.gl/9SjuQU">this zip</a> archive.
<br />
<br />
<b>STEP 3:</b><br/>
We need to install SleekXMPP library. Enter following to install SleekXMPP from PyPI (Please visit <a href="https://github.com/fritzy/SleekXMPP#get-the-code">here</a> to get more install options).
<pre class="brush:bash">pip install sleekxmpp</pre>
<br />
<b>STEP 4:</b><br/>
Once Openfire server is up and running you can issue following commands;
<br />
<pre class="brush:bash">python xmpp_server.py -j "alice@127.0.0.1" -p "password" -n "firealarm"</pre>
In another terminal;
<br />
<pre class="brush:bash">python xmpp_client.py -j "bob@127.0.0.1" -p "password" -c "alice@127.0.0.1/firealarm" -q</pre>
<br />
<hr />
IoT Server Code(xmpp_server.py)
<br />
<pre class="brush:python">#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import sys
from optparse import OptionParser
import socket
import sleekxmpp
# Python versions before 3.0 do not use UTF-8 encoding
# by default. To ensure that Unicode is handled properly
# throughout SleekXMPP, we will set the default encoding
# ourselves to UTF-8.
if sys.version_info < (3, 0):
from sleekxmpp.util.misc_ops import setdefaultencoding
setdefaultencoding('utf8')
else:
raw_input = input
from sleekxmpp.plugins.xep_0323.device import Device
class IoT_Server(sleekxmpp.ClientXMPP):
"""
A simple IoT device that can act as server.
This script can act as a "server" an IoT device that can provide sensor information.
Setup the command line arguments.
python xmpp_client.py -j "alice@yourdomain.com" -p "password" -n "device1" {--[debug|quiet]}
python xmpp_client.py -j "alice@127.0.0.1" -p "password" -n "device1" {--[debug|quiet]}
"""
def __init__(self, jid, password):
sleekxmpp.ClientXMPP.__init__(self, jid, password)
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message)
self.device = None
self.releaseMe = False
def testForRelease(self):
# todo thread safe
return self.releaseMe
def doReleaseMe(self):
# todo thread safe
self.releaseMe = True
def addDevice(self, device):
self.device = device
def session_start(self, event):
self.send_presence()
self.get_roster()
# tell your preffered friend that you are alive
# self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me')
def message(self, msg):
if msg['type'] in ('chat', 'normal'):
logging.debug("got normal chat message" + str(msg))
ip = socket.gethostbyname(socket.gethostname())
msg.reply("Hi I am " + self.boundjid.full + " and I am on IP " + ip + " use xep_323 stanza to talk to me").send()
else:
logging.debug("got unknown message type %s", str(msg['type']))
class IoT_Device(Device):
"""
This is the actual device object that you will use to get information from your real hardware
You will be called in the refresh method when someone is requesting information from you
"""
def __init__(self, nodeId):
Device.__init__(self, nodeId)
logging.debug("=========TheDevice.__init__ called==========")
self.temperature = 25 # define default temperature value
self.update_sensor_data()
def refresh(self, fields):
"""
the implementation of the refresh method
"""
logging.debug("=========TheDevice.refresh called===========")
self.temperature += 1 # increment default temperature value by one
self.update_sensor_data()
def update_sensor_data(self):
logging.debug("=========TheDevice.update_sensor_data called===========")
self._add_field(name="Temperature", typename="numeric", unit="C")
self._set_momentary_timestamp(self._get_timestamp())
self._add_field_momentary_data("Temperature", self.get_temperature(),
flags={"automaticReadout": "true"})
def get_temperature(self):
return str(self.temperature)
if __name__ == '__main__':
#-------------------------------------------------------------------------------------------
# Parsing Arguments
#-------------------------------------------------------------------------------------------
optp = OptionParser()
# Output verbosity options.
optp.add_option('-q', '--quiet', help='set logging to ERROR',
action='store_const', dest='loglevel',
const=logging.ERROR, default=logging.INFO)
optp.add_option('-d', '--debug', help='set logging to DEBUG',
action='store_const', dest='loglevel',
const=logging.DEBUG, default=logging.INFO)
# JID and password options.
optp.add_option("-j", "--jid", dest="jid",
help="JID to use")
optp.add_option("-p", "--password", dest="password",
help="password to use")
# IoT device id
optp.add_option("-n", "--nodeid", dest="nodeid",
help="I am a device get ready to be called", default=None)
opts, args = optp.parse_args()
# Setup logging.
logging.basicConfig(level=opts.loglevel,
format='%(levelname)-8s %(message)s')
if opts.jid is None or opts.password is None or opts.nodeid is None:
optp.print_help()
exit()
#-------------------------------------------------------------------------------------------
# Starting XMPP with XEP0030, XEP0323, XEP0325
#-------------------------------------------------------------------------------------------
# we bounded resource into node_id; because client can always call using static jid
# opts.jid + "/" + opts.nodeid
xmpp = IoT_Server(opts.jid + "/" + opts.nodeid, opts.password)
xmpp.register_plugin('xep_0030')
xmpp.register_plugin('xep_0323')
xmpp.register_plugin('xep_0325')
if opts.nodeid:
myDevice = IoT_Device(opts.nodeid)
xmpp['xep_0323'].register_node(nodeId=opts.nodeid, device=myDevice, commTimeout=10)
while not (xmpp.testForRelease()):
xmpp.connect()
xmpp.process(block=True)
logging.debug("lost connection")
</pre>
<br />
IoT Client Code(xmpp_client.py)
<br />
<pre class="brush:python">#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import sys
from optparse import OptionParser
import socket
import sleekxmpp
from sleekxmpp.exceptions import IqError, IqTimeout
# Python versions before 3.0 do not use UTF-8 encoding
# by default. To ensure that Unicode is handled properly
# throughout SleekXMPP, we will set the default encoding
# ourselves to UTF-8.
if sys.version_info < (3, 0):
from sleekxmpp.util.misc_ops import setdefaultencoding
setdefaultencoding('utf8')
else:
raw_input = input
PRINT_HEADER_LENGTH = 40
class IoT_Client(sleekxmpp.ClientXMPP):
"""
A simple IoT device that can act as client
This script can act as a "client" an IoT device or other party that would like to get data from
another device.
Setup the command line arguments.
python xmpp_client.py -j "bob@yourdomain.com" -p "password" -c "alice@yourdomain.com/device1" {--[debug|quiet]}
python xmpp_client.py -j "bob@127.0.0.1" -p "password" -c "alice@127.0.0.1/device1" {--[debug|quiet]}
"""
def __init__(self, jid, password, sensorjid):
sleekxmpp.ClientXMPP.__init__(self, jid, password)
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message)
self.device = None
self.releaseMe = False
self.target_jid = sensorjid
def datacallback(self, from_jid, result, nodeId=None, timestamp=None, fields=None,
error_msg=None):
"""
This method will be called when you ask another IoT device for data with the xep_0323
se script below for the registration of the callback
"""
logging.debug("we got data %s from %s", str(result), from_jid)
if (result == "fields"):
header = 'XEP 302 Sensor Data'
print('-' * PRINT_HEADER_LENGTH)
gap = ' '* ((PRINT_HEADER_LENGTH - len(header)) / 2)
print(gap + header)
print('-' * PRINT_HEADER_LENGTH)
logging.debug("RECV:"+str(fields))
if len(fields) > 0:
print "Name\t\tType\tValue\tUnit"
for field in fields:
print " - " + field["name"] + "\t" + field["typename"] + "\t" + field["value"] + "\t" + field["unit"]
print ""
self.disconnect()
def testForRelease(self):
# todo thread safe
return self.releaseMe
def doReleaseMe(self):
# todo thread safe
self.releaseMe = True
def addDevice(self, device):
self.device = device
def session_start(self, event):
self.send_presence()
self.get_roster()
# tell your preffered friend that you are alive using generic xmpp chat protocol
# self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me')
#-------------------------------------------------------------------------------------------
# Service Discovery
#-------------------------------------------------------------------------------------------
try:
# By using block=True, the result stanza will be
# returned. Execution will block until the reply is
# received. Non-blocking options would be to listen
# for the disco_info event, or passing a handler
# function using the callback parameter.
info = self['xep_0030'].get_info(jid=self.target_jid,
node=None,
block=True)
except IqError as e:
logging.error("Entity returned an error: %s" % e.iq['error']['condition'])
except IqTimeout:
logging.error("No response received.")
else:
header = 'XMPP Service Discovery'
print('-' * PRINT_HEADER_LENGTH)
gap = ' '* ((PRINT_HEADER_LENGTH - len(header)) / 2)
print(gap + header)
print('-' * PRINT_HEADER_LENGTH)
print "Device: %s" % self.target_jid
for feature in info['disco_info']['features']:
print(' - %s' % feature)
#-------------------------------------------------------------------------------------------
# Requesting data through XEP0323
#-------------------------------------------------------------------------------------------
session = self['xep_0323'].request_data(self.boundjid.full, self.target_jid,
self.datacallback, flags={"momentary": "true"})
def message(self, msg):
if msg['type'] in ('chat', 'normal'):
logging.debug("got normal chat message" + str(msg))
ip = socket.gethostbyname(socket.gethostname())
msg.reply("Hi I am " + self.boundjid.full + " and I am on IP " + ip + " use xep_323 stanza to talk to me").send()
else:
logging.debug("got unknown message type %s", str(msg['type']))
if __name__ == '__main__':
#-------------------------------------------------------------------------------------------
# Parsing Arguments
#-------------------------------------------------------------------------------------------
optp = OptionParser()
# JID and password options.
optp.add_option("-j", "--jid", dest="jid",
help="JID to use")
optp.add_option("-p", "--password", dest="password",
help="password to use")
# IoT sensor jid
optp.add_option("-c", "--sensorjid", dest="sensorjid",
help="Another device to call for data on", default=None)
# Output verbosity options.
optp.add_option('-q', '--quiet', help='set logging to ERROR',
action='store_const', dest='loglevel',
const=logging.ERROR, default=logging.INFO)
optp.add_option('-d', '--debug', help='set logging to DEBUG',
action='store_const', dest='loglevel',
const=logging.DEBUG, default=logging.INFO)
opts, args = optp.parse_args()
# Setup logging.
logging.basicConfig(level=opts.loglevel,
format='%(levelname)-8s %(message)s')
if opts.jid is None or opts.password is None or opts.sensorjid is None:
optp.print_help()
exit()
#-------------------------------------------------------------------------------------------
# Starting XMPP with XEP0030, XEP0323, XEP0325
#-------------------------------------------------------------------------------------------
xmpp = IoT_Client(opts.jid, opts.password, opts.sensorjid)
xmpp.register_plugin('xep_0030')
xmpp.register_plugin('xep_0323')
xmpp.register_plugin('xep_0325')
if opts.sensorjid:
logging.debug("will try to call another device for data")
xmpp.connect()
xmpp.process(block=True)
logging.debug("ready ending")
else:
print "noopp didn't happen"
</pre>Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-7263932570596805312015-08-13T01:18:00.001-07:002015-08-15T06:15:27.313-07:00Setting up XMPP Openfire Server and expose via RESTful APIs<img border="0" src="http://4.bp.blogspot.com/-GE4CQs5S39A/VcxoWjksTVI/AAAAAAAADN4/Xr4rsDSjNpA/s320/openfire.png" style="display: none;" />
In my previous <a href="http://tiriboy.blogspot.com/2015/08/xmppjabber-for-iot-devices-part-1.html" target="_blank">post</a> I explained most of the fundamentals in XMPP. In this post I hope to explain how we can implement XMPP IoT sample.<br />
<br />
First we need to setup a XMPP server(or Jabber server). There are many XMPP server implementations available based on different and competitive license and support models. In this example I have chosen <a href="http://www.igniterealtime.org/projects/openfire/" target="_blank">Openfire</a> which comes with Apache license which one of well-known corporate friendly open source license.<br />
<br />
<h3>
Installing Openfire Jabber Server</h3>
<br />
<b>STEP 1:</b><br />
Goto download link and download Openfire latest version.<br />
<br />
<b>STEP 2:</b><br />
Extract the zip archive file(depends on the platform) and run the setup.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-FuTArUqOmTc/VcuAUUEN01I/AAAAAAAADKk/neCApKMvSaw/s1600/Screen%2BShot%2B2015-08-12%2Bat%2B10.48.48%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="283" src="http://3.bp.blogspot.com/-FuTArUqOmTc/VcuAUUEN01I/AAAAAAAADKk/neCApKMvSaw/s400/Screen%2BShot%2B2015-08-12%2Bat%2B10.48.48%2BPM.png" width="400" /></a></div>
<b>STEP 3:</b><br />
Go through installation steps and complete the installation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-YyikyBENiSY/VcuAvQ9zTsI/AAAAAAAADKs/eAPiFq0_yTk/s1600/Screen%2BShot%2B2015-08-12%2Bat%2B10.51.09%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="282" src="http://2.bp.blogspot.com/-YyikyBENiSY/VcuAvQ9zTsI/AAAAAAAADKs/eAPiFq0_yTk/s400/Screen%2BShot%2B2015-08-12%2Bat%2B10.51.09%2BPM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>STEP 4:</b></div>
<div class="separator" style="clear: both; text-align: left;">
In MAC-OSX; I had to do one more additional step since "openfire" ownership was "openfire:247". </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
sudo chown -R <your_os_username>:admin /usr/local/openfire</div>
<div class="separator" style="clear: both; text-align: left;">
chmod +x /usr/local/openfire/bin/*.sh</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Then you can run the server using following command;</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
cd /usr/local/openfire/bin</div>
<div class="separator" style="clear: both; text-align: left;">
./openfire</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If everything ran smoothly, terminal should print the following;</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
Openfire 3.10.2 [Aug 12, 2015 11:13:20 PM]</div>
<div class="separator" style="clear: both;">
Admin console listening at http://rasikas-macbook-pro.local:9090</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Just copy and paste admin console url on the address bar of a web browser.</div>
<b>STEP 5:</b><br />
<div class="separator" style="clear: both;">
Now setup wizard should be appeared on the web browser. Select "English" as the language and click "continue". On the second screen enter the following;</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Domain -> 127.0.0.1 #or enter the IP assigned on ifconfig.</div>
<div class="separator" style="clear: both;">
Admin Console Port -> 9090 #http login</div>
<div class="separator" style="clear: both;">
Secure Admin Console Port -> 9091 #https login</div>
<div class="separator" style="clear: both;">
Property Encryption via -> Blowfish</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Gb-HAMwcr9I/VcuG9ou3buI/AAAAAAAADLA/g6NL3jQm0KE/s1600/Screen%2BShot%2B2015-08-12%2Bat%2B11.18.06%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="143" src="http://4.bp.blogspot.com/-Gb-HAMwcr9I/VcuG9ou3buI/AAAAAAAADLA/g6NL3jQm0KE/s400/Screen%2BShot%2B2015-08-12%2Bat%2B11.18.06%2BPM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b>STEP 6:</b></div>
<div class="separator" style="clear: both; text-align: center;">
On the next step select "Embedded Database" and click "Continue". This is will simplify the database connection process and make use of its HSQLDB internally embedded DB. On the production environment you must select "Standard Database Connection" and configure a separate database.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-jgea-HZIzM4/VcvnEG_oNvI/AAAAAAAADLY/RtiD8Jpf4sQ/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B6.07.22%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="100" src="http://2.bp.blogspot.com/-jgea-HZIzM4/VcvnEG_oNvI/AAAAAAAADLY/RtiD8Jpf4sQ/s400/Screen%2BShot%2B2015-08-13%2Bat%2B6.07.22%2BAM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<b>STEP 7:</b></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both;">
For the profile settings; select "Default". this option will keep the user information on the connected database.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-9-pH645aZRA/Vcvp1-MVi_I/AAAAAAAADLk/w2Ck-7RqG5U/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B6.09.53%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="106" src="http://4.bp.blogspot.com/-9-pH645aZRA/Vcvp1-MVi_I/AAAAAAAADLk/w2Ck-7RqG5U/s400/Screen%2BShot%2B2015-08-13%2Bat%2B6.09.53%2BAM.png" width="400" /></a></div>
<div class="separator" style="clear: both;">
<b>STEP 8:</b></div>
<div class="separator" style="clear: both;">
On the next step; enter an "email" and a valid password for the admin account. Click "Continue".</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-K8h_NeKd2IE/VcvqSqaG8wI/AAAAAAAADLs/IbURAyYBGOM/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B6.21.49%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="100" src="http://2.bp.blogspot.com/-K8h_NeKd2IE/VcvqSqaG8wI/AAAAAAAADLs/IbURAyYBGOM/s400/Screen%2BShot%2B2015-08-13%2Bat%2B6.21.49%2BAM.png" width="400" /></a></div>
<div class="separator" style="clear: both;">
<b>STEP 9:</b></div>
<div class="separator" style="clear: both;">
Once you are done, It will display "Setup Complete!" message. Then click on "Log to the admin console".</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-p3sADao3_E8/VcvrRtCGZHI/AAAAAAAADL4/qoqjUADUOmM/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B6.25.03%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="53" src="http://2.bp.blogspot.com/-p3sADao3_E8/VcvrRtCGZHI/AAAAAAAADL4/qoqjUADUOmM/s400/Screen%2BShot%2B2015-08-13%2Bat%2B6.25.03%2BAM.png" width="400" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div>
<b>STEP 10:</b></div>
<div>
Once you are redirected, enter the username as "admin" and the password will be the same you gave on the previous Step 8. If you are unable to login using provided credentials; please try restarting the server.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-pjabSqEgO-k/Vcvr7Tp9tsI/AAAAAAAADMI/r2RmrSLGq4E/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B6.28.13%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="121" src="http://1.bp.blogspot.com/-pjabSqEgO-k/Vcvr7Tp9tsI/AAAAAAAADMI/r2RmrSLGq4E/s320/Screen%2BShot%2B2015-08-13%2Bat%2B6.28.13%2BAM.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<h3>
Creating a New User</h3>
<div>
On this step we will create a new user on the open fire using admin console.</div>
<div>
<br />
<b>STEP 1:</b><br />
Navigate into "Users/Groups" tab. Select "Create New User" on the left menu pane.</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-y0-n6JW86w4/Vcw6TEBHawI/AAAAAAAADM4/PSNKe4ThnUw/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B12.03.05%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="106" src="http://3.bp.blogspot.com/-y0-n6JW86w4/Vcw6TEBHawI/AAAAAAAADM4/PSNKe4ThnUw/s400/Screen%2BShot%2B2015-08-13%2Bat%2B12.03.05%2BPM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-uviWX5Pcr6s/Vcw61DsFuiI/AAAAAAAADNE/SHESdM3Zahs/s1600/Screen%2BShot%2B2015-08-13%2Bat%2B12.04.28%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="66" src="http://4.bp.blogspot.com/-uviWX5Pcr6s/Vcw61DsFuiI/AAAAAAAADNE/SHESdM3Zahs/s400/Screen%2BShot%2B2015-08-13%2Bat%2B12.04.28%2BPM.png" width="400" /></a></div>
<br />
<h3>
Deploying REST-API plugin to manage users</h3>
When integrating with other servers, manually creating each user on the openfire is not scalable or feasible approach. Hence you can use Openfire <a href="http://www.igniterealtime.org/projects/openfire/plugins.jsp" target="_blank">plugins</a>. <a href="http://www.igniterealtime.org/projects/openfire/plugins/restapi/readme.html" target="_blank">REST-API plugin</a> provides functionalities to manage users through HTTP calls. API documentation is available on <a href="http://www.igniterealtime.org/projects/openfire/plugins/restapi/readme.html" target="_blank">here</a>.<br />
<br />
In order to install plugin, you can just copy "restApi.jar" file into $OPEN-FIRE-HOME/plugins folder. In OS-X "/usr/local/openfire/plugins". You don't need to restart the server. It will automatically deployed.<br />
<br />
To configure REST API, Go to Server -> Server Settings. Then REST API from the left menu pane.<br />
<br /></div>
</div>
Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-69884113266314504132015-08-12T09:30:00.000-07:002015-08-15T08:47:23.322-07:00XMPP/Jabber for IoT Devices - Part 1Recently we implemented XMPP (or Jabber) support into our IoT Device Management Framework. Ideally this provides near realtime communication between multiple devices over multiple networks. The architecture of the Jabber server is conforms to an email server(server.com) where XMPP clients conforms email clients(user@server.com). Many chat clients implements XMPP to communicate between distributed networks near realtime.<br />
<img border="0" src="http://1.bp.blogspot.com/-T8ioAEJwGvI/Vct1LqGq-oI/AAAAAAAADJ8/cIcMYFPP6vM/s320/xmpp.png" style="display: none;" />
<br />
Earlier we had the assumption of each device always have an accessible IP address. Based on this assumption we had an HTTP server running on the client-side. The APIs on the IoT Device Framework can call HTTP server on the device and perform actuators and sensor readings.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-fJA6zxVktX0/Vct5lhpTZUI/AAAAAAAADKU/KZN0jw7Imn0/s1600/drawing1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="HTTP server based implementation" border="0" height="188" src="http://1.bp.blogspot.com/-fJA6zxVktX0/Vct5lhpTZUI/AAAAAAAADKU/KZN0jw7Imn0/s400/drawing1.png" title="HTTP server based implementation" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">HTTP server based implementation</td></tr>
</tbody></table>
<br />
<br />
<h6>
What's wrong with HTTP?</h6>
Let me explain why this doesn't work all time. Suppose you need to make your devices controllable through IoT Device Framework APIs over Internet. One option is to provide public IPs into each device. Oh God!, it is not a good solution.<br />
<br />
Then other option is <a href="http://www.openbsd.org/faq/pf/nat.html#works" target="_blank">NAT</a>. The devices are exposed into Internet over a NAT gateway. Outgoing messages from the device will be modified by NAT gateway so that they appear to be coming from the NAT gateway itself. The NAT gateway will record the changes it makes in its state table so that it can reverse the changes on return packets. NATs will keep the association for as long as the connection is <b>alive</b>. When your API calls returning into NAT gateway, Gateway itself might not be able to find return destination.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-FvkKI7-niJQ/VctpYkT6C9I/AAAAAAAADJM/eSiwz4RHUws/s1600/nat-router.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="How NAT works" border="0" height="116" src="http://1.bp.blogspot.com/-FvkKI7-niJQ/VctpYkT6C9I/AAAAAAAADJM/eSiwz4RHUws/s320/nat-router.jpg" title="How NAT works" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">How NAT works (photo courtesy of How Stuff Works)</td></tr>
</tbody></table>
<h6>
How XMPP handle it?</h6>
Let's see how XMPP can handle this. XMPP is the Internet Standard for real time messaging communication and presence. It uses a standard TCP connection. You can use fully-fledged light-weight XMPP pings (<a href="http://xmpp.org/extensions/xep-0199.html" target="_blank">XEP-0199</a>) to keep NAT records alive. Need to notice that XMPP can be also implemented over HTTP too(<a href="http://xmpp.org/about-xmpp/technology-overview/bosh/" target="_blank">BOSH</a>). Prime advantage of the XMPP is that you can address a device on "user@server.com/mobile" resource addressing scheme instead of IP of the device. XMPP can act<br />
<br />
XMPP's basic model of communication is Client -> Server -> Server -> Client, and in support of this it defines a Client to Server protocol and a Server to Server protocol. Both of these protocols use XML encoded protocol directly over TCP. XMPP is a Bi-directional stream and "non-blocking":uses event-driven style. Powerful XMPP extensions such as Pub-Sub(XEP060) are available out-of-the box.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-_2b7_-ILWag/Vc9RdpXDEOI/AAAAAAAADQc/y0Zblr00Lkc/s1600/drawing3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="286" src="http://2.bp.blogspot.com/-_2b7_-ILWag/Vc9RdpXDEOI/AAAAAAAADQc/y0Zblr00Lkc/s400/drawing3.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">HTTP polling vs XMPP PubSub(source: [1])</td></tr>
</tbody></table>
<br />
<br />
<h6>
How XMPP works?</h6>
The major steps for server-to-client communication as follows;
<br />
<ol>
<li>Client and server communicate through port 5222 via a TCP connection.
</li>
<li>XMPP informations are contained on XML streams. A XMPP session is opened by <stream> tag and ended by </stream> tag. All other parts are located between them.
</li>
<li>For security purpose, the open stream is followed by moderate Transport Layer Security (TLS) negotiation and compulsory Simple Authentication and Security Layer (SASL) negotiation.
</li>
<li>A new stream will be opened immediately after the SASL negotiation, and it will be more secure and safe.
</li>
</ol>
Please refer <a href="http://ceit.uq.edu.au/content/how-xmpp-works-step-step">this post</a> for more detail explanation.
<br />
<br />
<h6>
XMPP Network Architecture</h6>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-be_VIur67wk/Vc9esyCniPI/AAAAAAAADQs/bPMvxuE60z4/s1600/drawing4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-be_VIur67wk/Vc9esyCniPI/AAAAAAAADQs/bPMvxuE60z4/s400/drawing4.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">XMPP Network Architecture</td></tr>
</tbody></table>
<br />
The <a href="http://tiriboy.blogspot.com/2015/08/xmppjabber-for-iot-devices-part-2.html">next blog-post</a> will describe how you can configure XMPP client and a server based on unofficial official XMPP IoT devices standard.<br />
<br />
Links:<br />
[1] http://www.slideshare.net/igrigorik/event-driven-architecture-meshu-ilya-grigorik<br />
<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-62257225153545354562015-08-11T11:52:00.002-07:002015-08-14T22:19:17.144-07:00Git Rewrite History, Removing Old Commits From History<br />
<h5>
"<span style="color: red;">REWRITING</span> History is a <span style="color: red;">BAD PRACTICE</span> and should <span style="color: red;">AVOID</span> as much as possible".</h5>
We recently came across this serious issue with "git" repositories. In our word; "WE MESSED UP OUR REPO". Had several reverts to fix it(But revert again is recorded as commit and so on...). Again needed to revert all revert commits. All these things altogether left us one option; which is the rewriting the history.<br />
<img border="0" src="http://1.bp.blogspot.com/-WKU0GRt4auI/VcpMbA8_60I/AAAAAAAADII/fZXoO71-7io/s320/githistory.png" style="display: none;" />
<br />
This post will show you how to re-write, but this will be an issue if lots of people have based their work on the remote master branch and have pulled that branch in their local repo (But if you haven't push the revert commits into remote repository; this would be the ideal solution).<br />
<br/>
What we are trying to achieve here is...
<ol><li>go back to a past revision</li><li>create and switch to a dummy branch</li><li>rename dummy branch into the master.</li></ol>
<br/><b> Yep, That's it!</b>
<br /><br />
<b>STEP 1:</b><br />
First we need to rewind back to a specific commit. Below command will move the pointer to a specific commit. The "<SHA1>" is the commit id.<br />
<br />
<pre class="brush:bash">git reset --hard <SHA1>
git status
</pre>
<br />
Should output something similar below. Note that in this example given commit id resulted current branch to move back 10 commits.
<br />
<br />
<div>
<span class="s1" style="font-family: Courier New, Courier, monospace;">
On branch master<br />
Your branch is behind 'origin/master' by 10 commits, and can be fast-forwarded.<br />
(use "git pull" to update your local branch)<br />
nothing to commit, working directory clean<br />
</span>
</div>
<br />
<b>STEP 2:</b><br />
Now create a new branch base on the current pointer and switch into it.
<br />
<pre class="brush:bash">git checkout -b temp
</pre>
<b>STEP 3:</b><br />
As the final step we are renaming our "master" branch into another and "temp" into "master".<br />
<pre class="brush:bash">git branch -m master old-master #rename master branch into old-master
git branch -m temp master #rename temp branch into master
git push -f origin master #do a force push changes
</pre>Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-18736156266175444812015-08-10T23:12:00.000-07:002015-08-11T11:17:57.546-07:00Setting JAVA_HOME on Raspberry PiThe new Raspbian build comes with Java 1.8 pre-installed. You can check the current java version by issuing following command;<br />
<br />
<pre class="brush:bash">java -version
</pre>
<br />
<img border="0" src="http://2.bp.blogspot.com/-h2K7fM-hl7A/Vco73J5K6ZI/AAAAAAAADH0/aInGsEeegVY/s320/raspi.png" style="display:none" />
<br />
java version "1.8.0"<br />
Java(TM) SE Runtime Environment (build 1.8.0-b132)<br />
Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode)<br />
<br />
In order to set environment variable "JAVA_HOME"; you can set it on ~/.bashrc file.<br />
<br />
<pre class="brush:bash">nano ~/.bashrc
</pre>
<br />
<br />
then add the following into the end of file and save changes.<br />
<br />
<pre class="brush:bash">export JAVA_HOME="/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt"
export PATH=$PATH:$JAVA_HOME/bin
</pre>
<br />
Then on you next login you can try out this;<br />
<br />
<pre class="brush:bash">export
</pre>
<br />
which should ideally print;<br />
<br />
declare -x JAVA_HOME="/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt"<br />
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/bin"Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-49776316966397368552015-04-16T00:39:00.001-07:002015-04-16T01:02:25.655-07:00Compiling ARM1176 for QEMU Raspberry Pi Emulation KernelThis is referred from <a href="http://xecdesign.com/compiling-a-kernel/" target="_blank">this</a> forum post and optimized for Mac OSX users. This blog post will show you how to compile a QEMU-ready Linux kernel for the ARM1176JZF-S CPU used by the Raspberry Pi. If you want to skip all of this and just have a kernel you can use, you can download 3.18 kernel <a href="https://drive.google.com/file/d/0BzxqUIMB8O1nYld4STBrR1VOUXc/view?usp=sharing" target="_blank">here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-FaWUr5XJkLY/VS9nHUgru0I/AAAAAAAABfU/r34mJ-Dwo48/s1600/raspi.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-FaWUr5XJkLY/VS9nHUgru0I/AAAAAAAABfU/r34mJ-Dwo48/s1600/raspi.png" height="200" width="200" /></a></div>
<br />
<h3>
<b>1. Preparing the development environment</b></h3>
<h4>
<b>Installing brew</b></h4>
First you need to have a package manager. HomeBrew is a good choice(for more info. refer <a href="http://tiriboy.blogspot.com/2015/03/apt-get-yum-install-on-mac-os-x.html" target="_blank">this</a> post). Or you can use any other such as "macport".<br />
<pre class="brush:bash">ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"</pre>
<br />
<h4>
Installing libcurses5 library</h4>
<a href="https://packages.debian.org/search?keywords=libncurses5" target="_blank">libncurses5-dev</a><br />
<pre class="brush:bash">brew install homebrew/dupes/ncurses
brew link --force ncurses</pre>
<h4>
Installing crosee-compiler tools</h4>
You can download pre-compiled cross-compiler tools for MAC OSX from <a href="http://www.welzels.de/blog/en/arm-cross-compiling-with-mac-os-x/comment-page-1/" target="_blank">this</a> blog.<br />
After the installation add the binaries to your path.<br />
<pre class="brush:bash">echo "/usr/local/linaro/arm-linux-gnueabihf-raspbian/bin" >> /etc/paths
</pre>
<br />
<h3>
2. Preparing the Linux Kernel</h3>
<h4>
Installing Git</h4>
Installing any package on homebrew is simple as "brew install <package_name>".<br />
<pre class="brush:bash">brew install git</pre>
<br />
<h4>
Download the source</h4>
Download linux source from raspberrypi linux repository.<br />
<pre class="brush:bash">git clone https://github.com/raspberrypi/linux.git</pre>
<h3>
3. Configure the Kernel</h3>
<div>
Then we need to configure the kernel accordingly:</div>
<pre class="brush:bash">cd linux
make ARCH=arm versatile_defconfig
make ARCH=arm menuconfig
</pre>
<br />
<h4>
Specify the cross-compiler:</h4>
<div class="p1">
General Setup ---></div>
<div class="p1">
Cross-compiler tool prefix</div>
<div class="p1">
(arm-linux-gnueabihf-)</div>
<div class="p1">
<br /></div>
<div class="p1">
<b>Note: Do not forget the '-' at the end of this string.</b></div>
<div class="p1">
<b>Note: When you select an option make sure you don't see 'M', but '*' (you may need to press space twice).</b></div>
<div class="p1">
<br /></div>
<h4>
Select the right CPU options:</h4>
<div class="p1">
System Type ---></div>
<div class="p1">
[*] Support ARM V6 processor</div>
<div class="p1">
[*] ARM errata: Invalidation of the Instruction Cache operation can fail</div>
<div class="p1">
[*] ARM errata: Possible cache data corruption with hit-under-miss enabled</div>
<div class="p1">
<br /></div>
<h4>
Enable support for hard-float binaries:</h4>
<div class="p1">
Floating point emulation ---></div>
<div class="p1">
[*] VFP-format floating point maths</div>
<div class="p1">
<br /></div>
<h4>
Enable ARM EABI:</h4>
<div class="p1">
Kernel Features ---></div>
<div class="p1">
[*] Use ARM EABI to compile the kernel</div>
<div class="p1">
[*] Allow old ABI binaries to run with this kernel</div>
<div class="p1">
<br /></div>
<h4>
Enable QEMU's disk support:</h4>
<div class="p1">
Bus Support ---></div>
<div class="p1">
[*] PCI Support</div>
<div class="p1">
Device Drivers ---></div>
<div class="p1">
SCSI Device Support ---></div>
<div class="p1">
[*] SCSI Device Support</div>
<div class="p1">
[*] SCSI Disk Support</div>
<div class="p1">
[*] SCSI CDROM support</div>
<div class="p1">
[*] SCSI low-lever drivers ---></div>
<div class="p1">
[*] SYM53C8XX Version 2 SCSI support</div>
<div class="p1">
<br /></div>
<h4>
Enable devtmpfs:</h4>
<div class="p1">
Device Drivers ---></div>
<div class="p1">
Generic Driver Options---></div>
<div class="p1">
[*] Maintain a devtmpfs filesystem to mount at /dev</div>
<div class="p1">
[*] Automount devtmpfs at /dev, after the kernel mounted the root</div>
<div class="p1">
<br /></div>
<h4>
Enable the important file systems:</h4>
<div class="p1">
File systems --></div>
<div class="p1">
<*> Ext3 journalling file system support</div>
<div class="p1">
<*> The Extended 4 (ext4) filesystem</div>
<div class="p1">
<br /></div>
<h4>
Enable tmpfs:</h4>
<div class="p1">
File systems ---></div>
<div class="p1">
Pseudo filesystems---></div>
<div class="p1">
[*] Virtual memory file system support (former shm fs)</div>
<div class="p1">
<br /></div>
<h4>
Enable the event interface:</h4>
<div class="p1">
Device Drivers ---></div>
<div class="p1">
Input device support---></div>
<div class="p1">
[*] Event interface<br />
<br />
<h4>
Adding RaspberryPi Logo into Kernel:</h4>
Device Drivers ---><br />
Graphics Support ---><br />
Console display driver support ---><br />
[ ] Select compiled-in fonts<br />
[*] Bootup logo (optional)<br />
<br /></div>
<div class="p1">
Exit, saving the configuration.</div>
<div class="p1">
<br /></div>
<h3>
4. Compiling the Kernel</h3>
<pre class="brush:bash">make ARCH=arm
mkdir ../modules
make ARCH=arm INSTALL_MOD_PATH=../modules modules_install</pre>
<h4>
<span class="s1">Troubleshooting</span></h4>
<div>
<u>Error 1:</u></div>
<div>
<span class="s1"><b>scripts/mod/modpost.c:1465:7: </b></span><span class="s2"><b>error: </b></span><span class="s1"><b>use of undeclared identifier 'R_386_32'</b></span></div>
<div class="p1">
</div>
<div class="p1">
<span class="s1"> case R_386_32:</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Create a new file elf.h and paste <a href="http://www.opensource.apple.com/source/dtrace/dtrace-78/sys/elf.h?txt" target="_blank">this</a> code from the opensource.apple.com.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<pre class="brush:bash">nano /usr/local/include/elf.h</pre>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In the same file </span>append these...</div>
<div class="p1">
<br /></div>
<pre class="brush:cpp">#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_26 4
#define R_MIPS_HI16 5
#define R_MIPS_LO16 6</pre>
<div class="p1">
<br />
<u>Error2:</u><br />
<br /></div>
<div class="p1">
<span class="s1"><b>/usr/local/include/elf.h:45:10: </b></span><span class="s2"><b>fatal error: </b></span><span class="s1"><b>'elftypes.h' file not found</b></span></div>
<div class="p1">
</div>
<div class="p1">
<span class="s1">#include "elftypes.h" /* In lieu of Solaris <sys/elftypes.h> */</span><br />
<span class="s1"><br /></span>
<span class="s1">create a new file elftypes.h and paste <a href="http://www.opensource.apple.com/source/dtrace/dtrace-48/sys/elftypes.h?txt" target="_blank">this</a> code from </span> the opensource.apple.com.</div>
<div class="p1">
<br /></div>
<div class="p1">
<pre class="brush:bash">nano /usr/local/include/elftypes.h</pre>
<br />
<u>Error 3:</u></div>
<div class="p1">
<br /></div>
<div class="p1">
xargs: illegal option -- r</div>
<div class="p1">
<br /></div>
<pre style="white-space: pre-wrap; word-wrap: break-word;">This is because BSD xargs doesn't have the same options as GNU xargs. Install GNU xargs from macports (It should show up earlier in your search path)
</pre>
<div>
<br /></div>
<div class="p1">
# Install GNU `find`, `locate`, `updatedb`, and `xargs`, g-prefixed</div>
<pre class="brush:bash">brew install findutils</pre>
<div class="p1">
<br /></div>
<div class="p1">
Replace all files using 'xargs' to 'gxargs'. (Use a sublime or any texteditor).</div>
<div class="p1">
<br /></div>
<div class="p1">
<h3>
5. Copy compiled Kernel</h3>
<div>
<div>
Copy the compiled kernel to your working directory:</div>
<div>
<br /></div>
<pre class="brush:bash">cp arch/arm/boot/zImage ../</pre>
<div>
<br /></div>
<div>
Done! You should name have a QEMU-bootable linux kernel and modules in your work directory.</div>
<div>
<br /></div>
</div>
</div>
Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-59488764466291356562015-04-11T22:56:00.001-07:002015-04-11T23:09:55.213-07:00Arduino UNO Clone Serial Port CH340/CH341 Drivers for Mac OS XRecently I tried connecting my newly purchased clone version of the Arduino UNO with the MacBook OS X Yosemite. It turns outs that, nothing gonna detect my serial port. This is because most of the clone versions are using a different chip for USB-to-Serial communication namely CH340/CH341 instead of ATmega16U2.<br />
<br />
<table border="0" cellpadding="20" style="margin-left: auto; margin-right: auto;">
<tbody>
<tr>
<td><a href="http://4.bp.blogspot.com/-_jYtLK5xe7U/VSoHr67UsmI/AAAAAAAABcA/JzgTkOv5auY/s1600/arduino.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img align="right" border="0" src="http://4.bp.blogspot.com/-_jYtLK5xe7U/VSoHr67UsmI/AAAAAAAABcA/JzgTkOv5auY/s1600/arduino.jpg" height="200" width="200" /></a></td>
<td><a href="http://2.bp.blogspot.com/-f1634Y3rIBY/VSoHwy1XR8I/AAAAAAAABcI/F9Ociw1MEJU/s1600/Screen%2BShot%2B2015-04-12%2Bat%2B11.17.50%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img align="left" border="0" src="http://2.bp.blogspot.com/-f1634Y3rIBY/VSoHwy1XR8I/AAAAAAAABcI/F9Ociw1MEJU/s1600/Screen%2BShot%2B2015-04-12%2Bat%2B11.17.50%2BAM.png" height="95.5" width="100" /></a></td>
</tr>
</tbody></table>
<br />
After hours of work and digging throughout the Internet, I found these drivers for CH341/CH340 is working as expected.<br />
<br />
<h4>
Here how you do it;</h4>
<br />
Download the drivers and install relevant setup. This package includes, drivers for linux, mac os x and windows.<br />
<br />
<a href="https://drive.google.com/file/d/0BzxqUIMB8O1na1ZLZzFXZGxCbm8/view?usp=sharing" target="_blank">Download all-in-one drivers pack</a><br />
<br />
One more additional step for Mac OS X users. Disable the kext signing security setting with this command.<br />
<br />
<pre class="brush:bash">sudo nvram boot-args="kext-dev-mode=1"
</pre>
<br />
<h4>
How to test it;</h4>
on the terminal type;<br />
<br />
<pre class="brush:bash">ls /dev/tty*</pre>
<br />
you should see something like "/dev/tty.wchusbserial1410". In addition, if you open up your Ardunio IDE then goto Tools->Port. You should see something similar to below.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-vAya1dZp9FE/VSoL9JB54RI/AAAAAAAABcU/AQ8ppGnUTPs/s1600/Screen%2BShot%2B2015-04-12%2Bat%2B11.38.01%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-vAya1dZp9FE/VSoL9JB54RI/AAAAAAAABcU/AQ8ppGnUTPs/s1600/Screen%2BShot%2B2015-04-12%2Bat%2B11.38.01%2BAM.png" height="147" width="320" /></a></div>
<br />
<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-10013685294728727802015-03-18T12:21:00.001-07:002015-03-18T12:27:46.002-07:00apt-get, yum install on Mac OS X : HomeBrewThis is a short blog entry on how you can invoke the the same semantic functionality you used to have in ubuntu, cent os...etc. There's a exciting project called "Homebrew" that will provide the "<b>missing package manager for Mac OS X</b>".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_gfPF1LDZa1auUWVBfN4YPc2etlXas6Vu_qlSicpBfurjnvGGaCik2GQxlODzcLC-1buyRjp-HSPDJIH8jmi1a6-g_r7a4YEIfQIqn4f1P18aMyoGqwEU848Mp1STwwKDVdR3wxvZraw/s1600/homebrew.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="homebrew logo" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_gfPF1LDZa1auUWVBfN4YPc2etlXas6Vu_qlSicpBfurjnvGGaCik2GQxlODzcLC-1buyRjp-HSPDJIH8jmi1a6-g_r7a4YEIfQIqn4f1P18aMyoGqwEU848Mp1STwwKDVdR3wxvZraw/s1600/homebrew.png" height="106" width="320" /></a></div>
<br />
<br />
You can download homebrew from <a href="http://brew.sh/" target="_blank">this</a> link.<br />
<br />
Once successfully downloaded and installed; you can issue "brew install <package>" to install any package. For instance...<br />
<br />
<pre class="brush:bash">brew install wget</pre>
<br />
And, this is how it appears...<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR-qh-vj6fvgabYaRLIqTr9CY6JcSNY7ioXTAa7Gx8H9iV2EoCJByz3koZ3IzDdIo1qX5FL1VdV9xxO3w_96DuyUIzq8dvUX3d6mrc_LkMx77N7z6pALSqRdWw1SOCuLSY6DWkh9QHRXc/s1600/Screen+Shot+2015-03-19+at+12.49.38+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR-qh-vj6fvgabYaRLIqTr9CY6JcSNY7ioXTAa7Gx8H9iV2EoCJByz3koZ3IzDdIo1qX5FL1VdV9xxO3w_96DuyUIzq8dvUX3d6mrc_LkMx77N7z6pALSqRdWw1SOCuLSY6DWkh9QHRXc/s1600/Screen+Shot+2015-03-19+at+12.49.38+AM.png" height="425" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">screen capture of installing "wget" using homebrew</td></tr>
</tbody></table>
<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-47996673970375230462015-03-18T11:04:00.000-07:002015-03-18T12:12:00.951-07:00java.lang.SecurityException: invalid SHA1 signature file digestThis weekend we came up with a issue when trying to verify a jar already signed using <a href="http://docs.oracle.com/javase/tutorial/security/toolfilex/step3.html" target="_blank">JarSigner</a> in JDK7 or JDK8(JarSigner? seriously WTH is that? read <a href="http://www.ibm.com/developerworks/library/j-jar/#N101BA" target="_blank">this</a>). When the same jar file is signed with JDK6 it is working fine. Here how to reproduce this error;<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgihK-v37aeyZ5kHP0u_pnEFE1v9X3c7hNS9uG7Wq46WnV7nUq8xHYA0GCQsqYtI_3t3Ar_ynd6uc9bao9__k3VUQugA7-ET_jsj1-F1C8JTuLUlI2JunyzITtRgKuvP8lEZ8ouvIJv3CA/s1600/exploit.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgihK-v37aeyZ5kHP0u_pnEFE1v9X3c7hNS9uG7Wq46WnV7nUq8xHYA0GCQsqYtI_3t3Ar_ynd6uc9bao9__k3VUQugA7-ET_jsj1-F1C8JTuLUlI2JunyzITtRgKuvP8lEZ8ouvIJv3CA/s1600/exploit.jpeg" height="240" width="320" alt="java security" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Java Jar Security</td></tr>
</tbody></table>
<br />
<h3>
</h3>
<h3>
Reproducing the issue</h3>
Sign a jar file in JDK6 using;<br />
<pre class="brush:bash">jarsigner -keystore /path/to/keystore.jks dummy.jar alias
</pre>
<br />
alias: is the alias identifying the private key that's to be used to sign the JAR file, and the key's associated certificate<br />
<br />
Switch into JDK7 and sign again using(but with another key);<br />
<pre class="brush:bash">jarsigner -keystore /path/to/another/keystore.jks dummy.jar otheralias</pre>
<br />
You might wondering why two private keys / keystores are used. In the real world scenario usually JARS are signed by the official organization who realeases it (First time signed). Another organization might use these JARS and may need to sign on their private key(Second time signed).<br />
<br />
However, If you tried to verify the above JAR file;<br />
<pre class="brush:bash">jarsigner -verify dummy.jar </pre>
<br />
You will get the following error;<br />
<pre class="brush:bash">jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for Test.class</pre>
<br />
This error usually happens when jarsigner digest algorithms mismatched. But how it is related here?<br />
<br />
<h3>
Analyzing the problem and the solution</h3>
Finally we found that the issue. Problem is with the mismatch of the default signing algorithm in JDK6, 7 and 8. If you are not specifying -digestnlg option;<br />
<br />
<a href="http://docs.oracle.com/javase/6/docs/technotes/tools/windows/jarsigner.html#DefaultAlgs" target="_blank">JDK6 Doc</a>: by default, SHA-1 will be used.<br />
<a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html#DefaultAlgs" target="_blank">JDK 7 Doc</a>: by default, SHA-256 will be used.<br />
<br />
<h4>
Solution</h4>
<div>
You may use "-digestalg SHA1" to sign the already signed JAR with a different certificate key. For example;</div>
<pre class="brush:bash">jarsigner -keystore /path/to/keystore.jks -digestalg SHA1 dummy.jar alias</pre>
<h4>
</h4>
<h4>
Further Observations</h4>
I have further observed that; Eventhough "-digestalg SHA1" solves(or work as a workaround), I am not clear about the jarsigner's verification behaviour.<br />
<ol>
<li>Suppose we are signing a JAR with SHA1 then signing SHA256 with the same key / alias verification never fails. </li>
<li>Signing a JAR with SHA1 then signing SHA256 with different keys / alias broke the verification.</li>
<li>Signing a JAR with SHA1 then again SHA1 with same/different keys /alias never fails(This is what we did to solve the issue).</li>
</ol>
<br />
This is also reported in stackoverflow<a href="https://www.blogger.com/blogger.g?blogID=8433516278710251551&pli=1#link1">[1]</a>. But according to the java doc<a href="https://www.blogger.com/blogger.g?blogID=8433516278710251551&pli=1#link2">[2]</a>, it says It is also possible for a JAR file to have mixed signatures.<br />
<h4>
</h4>
<h4>
Links</h4>
[1]<a href="http://stackoverflow.com/questions/12614139/what-prevents-java-from-verifying-signed-jars-with-multiple-signature-algorithms" name="link1">http://stackoverflow.com/questions/12614139/what-prevents-java-from-verifying-signed-jars-with-multiple-signature-algorithms</a><br />
<br />
[2]<a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html#sthref18" name="link2">http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html#sthref18</a><br />
<br />
Therefore, the workaround for the problem is,<br />
<br />
<br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-45973985812025067962015-03-07T10:06:00.001-08:002015-03-07T10:06:08.485-08:00Customizing the Finder in MAC OS X (Making Finder Suck Less!)Probably MAC OS X, Finder App is one of most complained App and has always given undesirable behaviors(at least for me). There are some quick workarounds that can make your favourite Finder Application less suck.<br />
<br />
Hope this might be more helpful for the people migrating from Windows to MAC OS;<br />
<h3>
1. How to get Address Bar / Path Bar (I am Lost! Where am I?)</h3>
<h3>
Solution 1:</h3>
<div>
You can Hide/Show the Address Bar(Path Bar) using View -> Show PathBar in the Finder Application. The keyboard shortcut is to press Option[<span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌥</span>] + Command[<span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌘</span>] + [P] at once.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgekMTbmhmQPTkOFc2lH0H8uxkIGDbg9rtu42eE1a3J4jbjug4WTu5ah93MDMbB1MQCazLRVTHV5UmpEQa7LUTgNCJE9x4FkqKHh4_DHZgg8jiLPG9u1vZ8MMPzniqaAZO3EFtCbXTuv-g/s1600/Screen+Shot+2015-03-07+at+9.21.15+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgekMTbmhmQPTkOFc2lH0H8uxkIGDbg9rtu42eE1a3J4jbjug4WTu5ah93MDMbB1MQCazLRVTHV5UmpEQa7LUTgNCJE9x4FkqKHh4_DHZgg8jiLPG9u1vZ8MMPzniqaAZO3EFtCbXTuv-g/s1600/Screen+Shot+2015-03-07+at+9.21.15+PM.png" height="178" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
The expected outcome(on the bottom of the Finder):</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi7f70IucZ0sbkHorWG7ZSZ08eUy6V_WMW8sgbyx-pGoWOtjeMYq90lSjuvidoLiWhReX6FnjXIiylDr3D7vUk2dM28vu797XDYoNPCCBFqLeZQlvWCQTUuO3HRpMeo1DLcdcAxjjJWGw/s1600/Screen+Shot+2015-03-07+at+9.25.58+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi7f70IucZ0sbkHorWG7ZSZ08eUy6V_WMW8sgbyx-pGoWOtjeMYq90lSjuvidoLiWhReX6FnjXIiylDr3D7vUk2dM28vu797XDYoNPCCBFqLeZQlvWCQTUuO3HRpMeo1DLcdcAxjjJWGw/s1600/Screen+Shot+2015-03-07+at+9.25.58+PM.png" height="35" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<h4>
Solution 2:</h4>
</div>
<div>
<div>
You can also just show the path in the Finder’s titlebar with these terminal command:</div>
<div>
<br /></div>
</div>
<pre class="brush:bash">defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
killall Finder
</pre>
<br />
The Expected outcome(on the titlebar of the Finder):<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-62gvWpxJS9-2YU6kOqaamLcq_fpi1HyS8eoxXkQpiPYDVjEj6QIhnCO94Ye_wAQFTnjzMZNuQ6BxMWrDbl8p56Xul1IwZn17Wsro73KX62O93LJ6NygsoivGAcJ-ClGuODcTHzK4BjU/s1600/Screen+Shot+2015-03-07+at+9.31.32+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-62gvWpxJS9-2YU6kOqaamLcq_fpi1HyS8eoxXkQpiPYDVjEj6QIhnCO94Ye_wAQFTnjzMZNuQ6BxMWrDbl8p56Xul1IwZn17Wsro73KX62O93LJ6NygsoivGAcJ-ClGuODcTHzK4BjU/s1600/Screen+Shot+2015-03-07+at+9.31.32+PM.png" height="43" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3 style="clear: both; text-align: left;">
How to switch in to the middle of the path?</h3>
<h4 style="clear: both; text-align: left;">
Solution 1:</h4>
<div class="separator" style="clear: both; text-align: left;">
You need to activate `Show Path Bar` for this. If you haven't activated yet; keyboard shortcut is to press Option[<span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌥</span>] + Command[<span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌘</span>] + [P] at once.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Then you can simply double click on the desired parent folder.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH2czgEVN9Ll-RAqmE26XQvO_iJw1bkMr19Sx648nOVs3GjsmbE6rVRAKb2BRPGoSyxHiuHvhWxXhcpz4svHVy0AEhPoIaWh7qBIKJD-CmrtFzMJ-SSoJRr13ONkQLN-dRKXEI5RidVeQ/s1600/Screen+Shot+2015-03-07+at+9.38.25+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH2czgEVN9Ll-RAqmE26XQvO_iJw1bkMr19Sx648nOVs3GjsmbE6rVRAKb2BRPGoSyxHiuHvhWxXhcpz4svHVy0AEhPoIaWh7qBIKJD-CmrtFzMJ-SSoJRr13ONkQLN-dRKXEI5RidVeQ/s1600/Screen+Shot+2015-03-07+at+9.38.25+PM.png" height="55" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h4 style="clear: both; text-align: left;">
Solution 2:</h4>
<div class="separator" style="clear: both;">
There’s also a path button that you can add to the Finder’s toolbar. Right click on the toolbar and click “Customize toolbar. . .” Then, drag the “Path” button to wherever you want:</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table border="0">
<tbody>
<tr>
<td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIq3gso9mmDfGuNaVNZJ1TK5ez1yGUTKHlxk9Gi-DAGEC4nzt3YmOp29t8sBfIAss25RpPoYa2Mm2HQ8hJqCkTAXVWEwMnFB3XFy-zG5lbQpn6I5C_KSLsMa0Z41Ke9G5-jF_tUEngGjw/s1600/Screen+Shot+2015-03-07+at+9.43.28+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIq3gso9mmDfGuNaVNZJ1TK5ez1yGUTKHlxk9Gi-DAGEC4nzt3YmOp29t8sBfIAss25RpPoYa2Mm2HQ8hJqCkTAXVWEwMnFB3XFy-zG5lbQpn6I5C_KSLsMa0Z41Ke9G5-jF_tUEngGjw/s1600/Screen+Shot+2015-03-07+at+9.43.28+PM.png" height="316" width="320" /></a></td>
<td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkOzToIfdOlSfEOf-19rEV0K31OBk4jmGJBvSuXkfZuUGSawXmT15yx8u1M83fLheTkJ76Kcd7IVqLcTeP-sO5fVlzbdllaJeE-U_R2Dy6Ldcln8Z70XlRvEbHDIVpRa9f5f1tXxlceqk/s1600/Screen+Shot+2015-03-07+at+9.47.56+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkOzToIfdOlSfEOf-19rEV0K31OBk4jmGJBvSuXkfZuUGSawXmT15yx8u1M83fLheTkJ76Kcd7IVqLcTeP-sO5fVlzbdllaJeE-U_R2Dy6Ldcln8Z70XlRvEbHDIVpRa9f5f1tXxlceqk/s1600/Screen+Shot+2015-03-07+at+9.47.56+PM.png" height="182" width="320" /></a></td>
</tr>
</tbody></table>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
<br /></div>
<h4 style="clear: both;">
Solution 3:</h4>
<div class="separator" style="clear: both;">
You can also right-click on the title bar to get a path listing(see solution 2 on the previous topic to activate path on title bar).</div>
<h3 style="clear: both;">
2. Search on the current folder (WTH! These are not in my folder!)</h3>
<div class="separator" style="clear: both;">
This most hilarious feature. I don't know why they have by default enabled to search whole Mac Computer. To make it more clear... Go to any folder and search something typing on the Search box.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiAHMc53ZbLjiGZgkrcfyvSmTRF8A6IQntW_egjpQejvT35bvixOvzfH_mpIfnYrM7OF57RHDIAeMsDuHbYFAyfpTaceUJt4qlf7IT3mMtYapt-uAXM6H5hVXLoKhLSEWYDj5bm2wBWLc/s1600/Screen+Shot+2015-03-07+at+10.06.13+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiAHMc53ZbLjiGZgkrcfyvSmTRF8A6IQntW_egjpQejvT35bvixOvzfH_mpIfnYrM7OF57RHDIAeMsDuHbYFAyfpTaceUJt4qlf7IT3mMtYapt-uAXM6H5hVXLoKhLSEWYDj5bm2wBWLc/s1600/Screen+Shot+2015-03-07+at+10.06.13+PM.png" height="93" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You will get a list of unwanted files which are also not in the folder you are currently in.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h4 style="clear: both; text-align: left;">
Solution:</h4>
<div class="separator" style="clear: both; text-align: left;">
Open Finder Preferences using "Finder-> Preferences..." from the menu. The keyboard shortcut is to press Command[<span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌘</span>] + [ , ] at once. This shortcut is common for almost all applications in Mac world. Select `Search the Current Folder` under the "When performing a search" text. Okay that's it.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table border="0">
<tbody>
<tr>
<td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheZBOOKVRHezMm-hBxAgQSWbYh3lekYqPmddU8FWy_PLkxqHRehGtiQ7q9PZDrblv0I9UtHFzb8H6tP3g4JYpVl_PwNNWdWfTxuIs8NjsAS7qQcRlKaNzHe2jc6SGZcYnA3fIhslrgaDM/s1600/Screen+Shot+2015-03-07+at+10.12.48+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheZBOOKVRHezMm-hBxAgQSWbYh3lekYqPmddU8FWy_PLkxqHRehGtiQ7q9PZDrblv0I9UtHFzb8H6tP3g4JYpVl_PwNNWdWfTxuIs8NjsAS7qQcRlKaNzHe2jc6SGZcYnA3fIhslrgaDM/s1600/Screen+Shot+2015-03-07+at+10.12.48+PM.png" height="300" width="320" /></a>
</td>
<td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPToUr-daa0sVDUbldfvSOijOomeWYDgNkospaWVwXpu3BQ_u-1zuWgDvJm8WwUlR1SbQn7jAEVBd0sHRK43h4hce4Yj74VjCB-CCoipZ1gIgz1AV7T0EnLDU1tXSITdqtOkDOIs8RzTg/s1600/Screen+Shot+2015-03-07+at+10.09.22+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPToUr-daa0sVDUbldfvSOijOomeWYDgNkospaWVwXpu3BQ_u-1zuWgDvJm8WwUlR1SbQn7jAEVBd0sHRK43h4hce4Yj74VjCB-CCoipZ1gIgz1AV7T0EnLDU1tXSITdqtOkDOIs8RzTg/s1600/Screen+Shot+2015-03-07+at+10.09.22+PM.png" height="251" width="320" /></a>
</td>
</tr>
</tbody></table>
<div class="separator" style="clear: both;">
<br /></div>
Now by default you are searching on the current folder.Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-74359928278771153052015-03-07T02:28:00.000-08:002015-03-07T03:11:27.798-08:00Support for Selenium IDE export as Java / TestNG / WebDriverThis is a very brief entry for those who seeks support for exporting Selenium scripts. Currently Selenium IDE supports exporting selenium scripts into `<b>Java / TestNG / Remote Control(RC)</b>`. WebDriver is the successor of the old Remote Control(RC). Exporting test cases generated by Selenium IDE to `<b>Java / TestNG / WebDriver</b>` is not officially supported at the time writing this blog entry.<br />
<br />
Therefore, I created PR request and hopefully will be merged soon. The benefits of this PR are;<br />
<br />
1). Export Test Case As.. -> Java / TestNG / WebDriver<br />
<br />
Export your reordered test cases into Java, TestNG and WebDriver supported `.java` files.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIX7uw4UW5itp_CL14rW4hkDK9FNgIQwP5DwMe21FxmT96Y1q1ICSCvP8DMZo6tKja9SHhlykZg7WDFh81zGTohQtJa76smhokWZVK4YJeTuofU_B_aZKUSZ_q1c4q8kVyGjLpuBfRnUU/s1600/Screen+Shot+2015-03-07+at+2.21.50+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIX7uw4UW5itp_CL14rW4hkDK9FNgIQwP5DwMe21FxmT96Y1q1ICSCvP8DMZo6tKja9SHhlykZg7WDFh81zGTohQtJa76smhokWZVK4YJeTuofU_B_aZKUSZ_q1c4q8kVyGjLpuBfRnUU/s1600/Screen+Shot+2015-03-07+at+2.21.50+PM.png" height="231" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both;">
2). Export Test Suite As.. -> Java / TestNG / WebDriver</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
This will create a XML file conformed to TestNG Test Suite <a href="http://testng.org/doc/documentation-main.html" target="_blank">documentation</a> . According TestNG docs;</div>
<blockquote class="tr_bq" style="clear: both;">
A suite is represented by one XML file. It can contain one or more tests and is defined by the <suite> tag.</blockquote>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Therefore, expected outcome is a `testng.xml` file with <suite> tags.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4ZVTmqOdx8l3TPlNRSq1JJe4n9edjlQ2H3_UlTq0kGDbq1WH_CTWTDjFX1EMqDauZWh-_F7HRvbYKKrzhDAfMkMxByV2U_yD_IxlGPTHnr1DIL_jYgqF8YFUMqL3U-nLeouJlUDUgizU/s1600/Screen+Shot+2015-03-07+at+2.22.23+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4ZVTmqOdx8l3TPlNRSq1JJe4n9edjlQ2H3_UlTq0kGDbq1WH_CTWTDjFX1EMqDauZWh-_F7HRvbYKKrzhDAfMkMxByV2U_yD_IxlGPTHnr1DIL_jYgqF8YFUMqL3U-nLeouJlUDUgizU/s1600/Screen+Shot+2015-03-07+at+2.22.23+PM.png" height="173" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3 style="clear: both; text-align: left;">
Link to the Pull Request(PR)</h3>
<div class="separator" style="clear: both; text-align: left;">
The Pull Request and code changes are available on <a href="https://github.com/SeleniumHQ/selenium/pull/326">https://github.com/SeleniumHQ/selenium/pull/326</a>.</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<h3>
Download the Selenium IDE - XPI</h3>
You can download the build of this fix based on the Selenium IDE 2.8.0 from the following link <a href="http://goo.gl/N2Cp4O">http://goo.gl/N2Cp4O</a>.<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Note: You can find latest releases of the selenium IDE in <a href="http://www.seleniumhq.org/download/">http://www.seleniumhq.org/download/</a>. </div>
<div class="separator" style="clear: both;">
<br /></div>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-15952553206771462032015-02-22T01:54:00.000-08:002015-06-02T07:00:40.190-07:00Github Beginners guide - Fork and submit Pull Request<br />
Today's post is about quick start guide on github. This article is more focused on git add, git commit and git push commands.<br />
<br />
<img border="0" height="236" src="http://3.bp.blogspot.com/-DKhzU2nJd5k/VOm8OvDRzEI/AAAAAAAAAoM/eBp8RBLDHVo/s1600/white-mug-1_1024x1024.png" style="display: none;" width="320" />
1. First you need to <a href="http://git-scm.com/downloads" target="_blank">download and install latest version of the Git</a>.<br />
2. Once you completed installation, first ever thing to do is setup the configs. Open a new terminal and type;<br />
<pre class="brush:bash">git config --global user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL ADDRESS ON GITHUB"</pre>
<br />
This will tell the Git your name and the email address associated with the Git account hence your commits properly labeled. And your email address is not publicly available under the default settings.<br />
<hr />
Now we have completed the basic steps on our Git. Now we need to fork the repository. A fork is a copy of a repository. It allows you to experiment the code do the bug fixes and submit it to the main repository. Unlike SVN, this workflow allows you to submit bug fixes for well-knows repositories even you do not have the permissions to commit directly. We need to;<br />
<ol>
<li>Fork from the original repository</li>
<li>Create a local clone of your fork</li>
<li>Do the fix/change on your clone</li>
<li>Commit changes to your fork</li>
<li>Submit a pull request to the owner of the original repository</li>
</ol>
<div>
For the demonstration purposes we will be using the Spoon-Knife test repository that’s hosted on GitHub.com that lets you test the Pull Request workflow.</div>
<h3>
1. Fork from the original repository</h3>
<div>
<ol>
<li>On Github, navigate to the <a href="https://github.com/octocat/Spoon-Knife" target="_blank">original</a> repository.</li>
<li>On the top-right corner click on the <b>fork.</b></li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-WMqEpLb8kEE/VOmBxDdipqI/AAAAAAAAAjE/ujJf-vdW7UE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B12.43.17%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="52" src="http://1.bp.blogspot.com/-WMqEpLb8kEE/VOmBxDdipqI/AAAAAAAAAjE/ujJf-vdW7UE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B12.43.17%2BPM.png" width="400" /></a></div>
<br />
Done! Now you have a copy of the original repository on your account. You can confirm it by navigating into your dashboard.<br />
<h3>
2. Create a local clone of your fork</h3>
Now we need to create a local clone on our fork and keep our fork synced.
<br />
<div>
On Github account dashboard; you will find the repositories that your have forked. Click on the fork that you created on the previous steps.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-8zALod5LP8M/VOmDWhF4qEI/AAAAAAAAAjY/EeUXoCUzidc/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B12.49.53%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="140" src="http://3.bp.blogspot.com/-8zALod5LP8M/VOmDWhF4qEI/AAAAAAAAAjY/EeUXoCUzidc/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B12.49.53%2BPM.png" width="200" /></a></div>
<br />
On the right-sidebar of your fork repository; click on the 'copy to clipboard' button to copy the clone URL.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-aMqMbHOdpz4/VOmCKwRkXRI/AAAAAAAAAjM/hD6kGx3wb8A/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B12.45.00%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="http://1.bp.blogspot.com/-aMqMbHOdpz4/VOmCKwRkXRI/AAAAAAAAAjM/hD6kGx3wb8A/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B12.45.00%2BPM.png" width="200" /></a></div>
<div>
<br /></div>
<div>
Open up the terminal application. Navigate into the place of your computer, where you need to create the clone. For example, I will create a new folder for the clone.</div>
<div>
<br /></div>
<pre class="brush:bash">mkdir ~/GitRepo
mkdir ~/GitRepo/SpoonKnife
cd ~/GitRepo/SpoonKnife
</pre>
<br />
Now we are ready to clone. You can use, clone <CLONE_URL_FOR_YOUR_FORK>. This URL should be similar to the "https://github.com/YOUR_USERNAME/YOUR_FORK.git".<br />
<br />
<pre class="brush:bash">clone git clone https://github.com/YOUR_USERNAME/Spoon-Knife.git</pre>
<br />
Press Enter. Your local clone will be created.<br />
<br />
<h3>
3. Do the Fix/Change on your clone</h3>
</div>
<div>
Now you can do the changes you want for the files on your local clone. Once the changes are done, we need to sync the changes into our fork repository.<br />
<br /></div>
<h3>
4. Commit changes to your fork</h3>
<div>
A commit is a snapshot of your work. To do a commit; navigate to your local clone.</div>
<div>
<br /></div>
<div>
<pre class="brush:bash">cd ~/GitRepo/SpoonKnife</pre>
</div>
<div>
<br /></div>
<div>
you can see the file changes by following command.</div>
<br />
<pre class="brush:bash">git status</pre>
<div>
<br /></div>
<div>
This will show up the <b>changes not staged for commit</b>. I have modified the build.xml and pom.xml files. <b>Untracked files</b> are usually newly created files on the local repository. Since I am using MAC OS X, it is automatically creating .DS_Store to track view options on the folders.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-fzzALsljiKc/VOmKJrtRo2I/AAAAAAAAAkI/MANZlvAAvuk/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.19.31%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="321" src="http://4.bp.blogspot.com/-fzzALsljiKc/VOmKJrtRo2I/AAAAAAAAAkI/MANZlvAAvuk/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.19.31%2BPM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div class="alert-box notice">
NOTICE:
You can use `git clean .` (Note the dot) or `git clean <<span style="color: #0b5394;">FILE_PATH_AS_SHOWN</span>>` to remove untracked files. Also, `git clean -n ` to do a dry-run and see what files would be removed before actually get removed.</div>
<div>
<br /></div>
<div>
However, there can be newly added config file, or resource that we need to add into our commit other than .DS_Store. So, we can ignore these files by following;</div>
<div>
<br /></div>
<div>
<div class="p1">
<pre class="brush:bash">echo ".DS_Store" >> ~/.gitignore</pre>
</div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">This will ignore all .DS_Store files for the future commits.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-5rjA3EWjVHc/VOmKaWJfm8I/AAAAAAAAAkQ/UC-1nz0JAiE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.20.43%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="304" src="http://4.bp.blogspot.com/-5rjA3EWjVHc/VOmKaWJfm8I/AAAAAAAAAkQ/UC-1nz0JAiE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.20.43%2BPM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="p1">
<span class="s1"></span></div>
<div class="p1">
Before adding, you can check your changes line-by-line by issuing, `git diff <FILE_PATH_AS_SHOWN >`. This will help you to verify, you are not submitting invalid or unintended changes such as indenting issues.</div>
<div class="p1">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-sothNysOJUA/VOmLvFuakjI/AAAAAAAAAkk/sLgg7AQJHTE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.25.45%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="267" src="http://3.bp.blogspot.com/-sothNysOJUA/VOmLvFuakjI/AAAAAAAAAkk/sLgg7AQJHTE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.25.45%2BPM.png" width="640" /></a></div>
<div class="p1">
<br /></div>
<div>
<br /></div>
<div class="p1">
<span class="s1">Now we need to add our modifications for the commit. Simply add, </span><span class="s1">git add <</span> FILE_PATH_AS_SHOWN >.</div>
<div class="p1">
<br /></div>
<div class="p1">
For example,</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git add index.html
git add newfile.txt</pre>
<div class="p1">
<br /></div>
<div class="alert-box notice">
NOTICE:
You can issue `git add .` to add all files for the commit. If you screwed up adding files, you can use `git reset .`(Note that dot means all files). </div>
<div class="p1">
<br /></div>
<div class="p1">
Once you added files for your commit. you can use `git status` to see your changes.</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git status</pre>
<div class="p1">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-jeayyYoAWFU/VOmKw7cPMLI/AAAAAAAAAkY/gDkbosleGto/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.22.13%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="http://3.bp.blogspot.com/-jeayyYoAWFU/VOmKw7cPMLI/AAAAAAAAAkY/gDkbosleGto/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B1.22.13%2BPM.png" width="640" /></a></div>
<div class="p1">
<br /></div>
<div class="p1">
<br /></div>
<div class="p1">
This will show already added files with the green color. You can simply add the commit into your master branch. But it is good practice is to keep the master branch clean. By clean, it is means without any changes, like that you can create at any time a branch from your master. <b>Therefore, It is recommended, A separate branch for commit a bug or a feature</b>. </div>
<div class="p1">
<br /></div>
<div class="p1">
In order to create a new branch and switch into new branch;</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git checkout -b change-msg</pre>
<div class="p1">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Mb5t4QuSYYM/VOmWHFWTAAI/AAAAAAAAAlM/PAoL_7Bkbmk/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.09.48%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="91" src="http://1.bp.blogspot.com/-Mb5t4QuSYYM/VOmWHFWTAAI/AAAAAAAAAlM/PAoL_7Bkbmk/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.09.48%2BPM.png" width="640" /></a></div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git branch</pre>
<div class="p1">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-u6JYkkAc9qA/VOmawpew5TI/AAAAAAAAAlY/7yVhSpFWnkg/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.30.29%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="76" src="http://2.bp.blogspot.com/-u6JYkkAc9qA/VOmawpew5TI/AAAAAAAAAlY/7yVhSpFWnkg/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.30.29%2BPM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For more details on git branches refer this <a href="https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches" target="_blank">tutorial</a>.</div>
<div class="p1">
<br /></div>
<div class="p1">
Now you can commit these staged changes to your repository. Use git commit -m "<YOUR_COMMIT_MESSAGE>".</div>
<div class="p1">
<br /></div>
<div class="p1">
Note that the commit message is important to track what you have done on the particular commit. For example you might fix a JIRA issue. Therefore, you can add JIRA ticket number for ease of tracking.</div>
<div class="p1">
<br /></div>
<div class="p1">
</div>
<div class="p1">
<pre class="brush:bash">git commit -m "Fixing JIRA SK:XXX - Changing the message"</pre>
</div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-0o4oRs7DoOY/VOmbHJNveAI/AAAAAAAAAlg/2HYYL8ZWOgE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.31.34%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="http://1.bp.blogspot.com/-0o4oRs7DoOY/VOmbHJNveAI/AAAAAAAAAlg/2HYYL8ZWOgE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.31.34%2BPM.png" width="640" /></a></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Now we need to push our local clone changes into our remote fork. We need to create an upstream for this; </span><span class="s1">`git remote add upstream <</span>CLONE_URL_FOR_ORIGINAL_REPO>`.Notice that CLONE_URL_FOR_ORIGINAL_REPO would be similar to a URL like "https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git.</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git remote add upstream https://github.com/octocat/Spoon-Knife.git</pre>
<div class="p1">
<br /></div>
<div class="p1">
you can verify the remote links by, "git remote -v";</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git remote -v
origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch)
upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push)
</pre>
<br />
In this case;
<br />
<pre class="brush:bash">git remote -v
origin https://github.com/YOUR_USERNAME/Spoon-Knife.git (fetch)
origin https://github.com/YOUR_USERNAME/Spoon-Knife.git (push)
upstream https://github.com/octocat/Spoon-Knife.git (fetch)
upstream https://github.com/octocat/Spoon-Knife.git (push)
</pre>
<div class="p1">
<br /></div>
<div class="p1">
If you screwed-up, you can use "git remote remove <URL_NAME>". For instance, "git remote remove upstream".</div>
<div class="p1">
<br /></div>
<div class="p1">
Now issue the following command;</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">git push origin change-msg
</pre>
<div class="p1">
<br /></div>
<div class="p1">
Note that "git push" might work on most of the time. But here, we have created a new branch in our local repository. Hence we need to push our code changes into that branch.<br />
<br />
This will push your changes into the remote repository and output something similar to the;</div>
<div class="p1">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-hLgzR_e3OFs/VOmczPSU74I/AAAAAAAAAls/49wrCPDfGns/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.38.55%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="http://2.bp.blogspot.com/-hLgzR_e3OFs/VOmczPSU74I/AAAAAAAAAls/49wrCPDfGns/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.38.55%2BPM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now goto your Github account and navigate into the forked repository. If everything went fine, when you navigate into `master` branch and the latest commit is still by octocat.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-aglyi8vEHM0/VOmeBE6LzCI/AAAAAAAAAl4/ukyqxLj6G1c/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.42.42%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="http://4.bp.blogspot.com/-aglyi8vEHM0/VOmeBE6LzCI/AAAAAAAAAl4/ukyqxLj6G1c/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.42.42%2BPM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="p1">
And on the newly created branch, "change-msg"; it should be your commit.</div>
<div class="p1">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-U9UbbhAJOqk/VOmerdDCsHI/AAAAAAAAAmA/_SXlV-jmEsw/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.46.37%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="219" src="http://3.bp.blogspot.com/-U9UbbhAJOqk/VOmerdDCsHI/AAAAAAAAAmA/_SXlV-jmEsw/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B2.46.37%2BPM.png" width="640" /></a></div>
<div class="p1">
<br /></div>
<h3>
5. Submit a pull request to the owner of the original repository</h3>
<div>
Now we have pushed our changes/ bug fixes to the forked repository. By submitting a pull request you are asking the owner of the repository to merge your repository with the original. To do that, on Github account dashboard; navigate into your forked repository. On the right hand click on "Pull Requests" tab.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-EIKoeYbzRb8/VOl2rifYQLI/AAAAAAAAAiU/l55mJRpROTo/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B11.53.42%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="143" src="http://3.bp.blogspot.com/-EIKoeYbzRb8/VOl2rifYQLI/AAAAAAAAAiU/l55mJRpROTo/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B11.53.42%2BAM.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
On the "Pull Requests" tab, click on "New Pull Request".</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-_kbjSokUQd8/VOl3S1DvFEI/AAAAAAAAAic/nasSQNPGNyY/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B11.58.25%2BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="128" src="http://1.bp.blogspot.com/-_kbjSokUQd8/VOl3S1DvFEI/AAAAAAAAAic/nasSQNPGNyY/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B11.58.25%2BAM.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
At the beginning it will show <b>"There isn't anything to compare"</b>. This is because we are comparing our master branch with original repository. In order to create a pull request from our new branch, you should select the newly created branch which is "change-msg" in our case.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-xEoXJb_cn9E/VOmimlwOXBI/AAAAAAAAAmY/VDpRKPDlZUw/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B3.03.23%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="48" src="http://3.bp.blogspot.com/-xEoXJb_cn9E/VOmimlwOXBI/AAAAAAAAAmY/VDpRKPDlZUw/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B3.03.23%2BPM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
Now you will see your commit changes and click on "Create Pull request".</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-MOZVVgwsDFw/VOmjNScLZXI/AAAAAAAAAmg/MFy2-x-h8Kc/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B3.05.27%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="http://4.bp.blogspot.com/-MOZVVgwsDFw/VOmjNScLZXI/AAAAAAAAAmg/MFy2-x-h8Kc/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B3.05.27%2BPM.png" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Add some meaningful details for the `title` and `comment` for the pull request. Before you send the pull request you can verify your changes, on the below of your pull request. Then you can click on "create pull request".</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-eX3qU1KupgI/VOmj18VkmvI/AAAAAAAAAmo/2iOiJtEyQdE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B3.08.18%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="http://1.bp.blogspot.com/-eX3qU1KupgI/VOmj18VkmvI/AAAAAAAAAmo/2iOiJtEyQdE/s1600/Screen%2BShot%2B2015-02-22%2Bat%2B3.08.18%2BPM.png" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3>
What would happen if the owner of the repository asked for modifications?</h3>
<div>
In this case, you don't have to cancel your pull-request and start a new request. You can submit the follow-up commits into the same branch(in this example, change-msg branch), Then it will be appeared on the same pull-request.</div>
<div>
<br /></div>
<h4>
Links</h4>
<div>
[1] Guides.github.com, (2014). Forking Projects · GitHub Guides. [online] Available at: https://guides.github.com/activities/forking/ [Accessed 22 Feb. 2015].<br />
[2] Help.github.com, (2015). Using pull requests - User Documentation. [online] Available at: https://help.github.com/articles/using-pull-requests/ [Accessed 22 Feb. 2015].<br />
[3] Help.github.com, (2015). Syncing a fork - User Documentation. [online] Available at: https://help.github.com/articles/syncing-a-fork/ [Accessed 22 Feb. 2015].<br />
[4] George, S. (2015). Kunena/Kunena-Forum. [online] GitHub. Available at: https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches [Accessed 22 Feb. 2015].</div>
</div>
Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-10050980523106711872015-02-21T10:01:00.000-08:002015-02-23T07:56:33.636-08:00JDK 1.7 fails on JIBX: java.lang.VerifyError errorThis is what I got when running <a href="https://docs.wso2.com/display/AS410/JiBX+Data+Binding" target="_blank">WSO2 AS JiBX sample</a> on JDK 1.7. By the way What is <a href="http://www.jibx.org/" target="_blank">JiBX</a>???<br />
<blockquote class="tr_bq">
JiBX differs from other data binding techniques supported by Axis2 in that it allows you to use your own Java data objects (as opposed to Java data objects generated from a schema definition). JiBX also provides a nicer form of an unwrapped Web services interface than is supported by the other data binding techniques<a href="https://www.blogger.com/blogger.g?blogID=8433516278710251551#ref1">[1]</a>.</blockquote>
<pre class="brush: java;highlight: [2,7,33]"> [bind] Error running binding compiler
[bind] java.lang.VerifyError: Expecting a stackmap frame at branch target 12
[bind] Exception Details:
[bind] Location:
[bind] org/wso2/appserver/jibx/library/beans/Book.JiBX_jibx_unwrapped_newinstance_1_0(Lorg/wso2/appserver/jibx/library/beans/Book;Lorg/jibx/runtime/impl/UnmarshallingContext;)Lorg/wso2/appserver/jibx/library/beans/Book; @1: ifnonnull
[bind] Reason:
[bind] Expected stackmap frame at this location.
[bind] Bytecode:
[bind] 0000000: 2ac7 000b bb00 0a59 b700 744b 2ab0
[bind]
[bind] at java.lang.Class.getDeclaredMethods0(Native Method)
[bind] at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
[bind] at java.lang.Class.getDeclaredMethods(Class.java:1860)
[bind] at org.jibx.binding.Compile.compile(Compile.java:278)
[bind] at org.jibx.binding.ant.CompileTask.execute(CompileTask.java:248)
[bind] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
[bind] at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
[bind] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[bind] at java.lang.reflect.Method.invoke(Method.java:606)
[bind] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[bind] at org.apache.tools.ant.Task.perform(Task.java:348)
[bind] at org.apache.tools.ant.Target.execute(Target.java:435)
[bind] at org.apache.tools.ant.Target.performTasks(Target.java:456)
[bind] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
[bind] at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
[bind] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[bind] at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
[bind] at org.apache.tools.ant.Main.runBuild(Main.java:851)
[bind] at org.apache.tools.ant.Main.startAnt(Main.java:235)
[bind] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
[bind] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
...
BUILD FAILED
</pre>
<br />
<div class="p1">
The hardest sentence that a developer ever don't want to see on `ant` is the "BUILD FAILED" message. So, we have lost in a java.lang.VerifyError.<br />
<h3>
Root Problem?</h3>
<span class="s1">Let's dig into the problem. We are getting a java.lang.VerifyError error. Why we getting such a thing?</span><br />
<span class="s1"><br /></span>
<span class="s1">Because JVM class loader checks the byte codes of the class for various purposes;</span><br />
<ul>
<li>Variables are initialized before they are used.</li>
<li>Method calls match the types of object references.</li>
<li>Rules for accessing private data and methods are not violated.</li>
<li>Local variable accesses fall within the runtime stack.</li>
<li>The runtime stack does not overflow.</li>
</ul>
<br />
If one of the above is failed, JVM will think the class is corrupted and/or the class will not be loaded. This strict verification is an important security consideration. It avoids unexpected errors that breaks the execution of the program ad injecting malicious codes into the Java programs.<br />
<br />
Java 7 introduced a strict verification and changed the class format slightly to contain a stackmap, used to verify the code is correct. As a result; on the exception details, it says; `Expected stackmap frame at this location`.<br />
<h3>
So What is the Solution?</h3>
If you are using ANT builders; you can use ANT_OPTS environment variable to following;<br />
<br />
<div class="p1">
<pre class="brush:bash">export ANT_OPTS=-noverify</pre>
<br />
<span class="s1"><br /></span>
<span class="s1">Or as a workaround you can add -noverify to the JVM arguments in order to disable verification. In Java 7 it was also possible to use -XX:-UseSplitVerifier to use the less strict verification method, but that option was removed in Java 8.</span><br />
<span class="s1"><br /></span>
<br />
<h3>
Additional Note:</h3>
<div>
In Java world, dynamic java code is protected with the three line of protection layers as shown in below image. The first line on defense is ByteCode Verifier. The verifier reads the bytecodes before it is run and make sure it is well behaved according to the basic rules of the java language.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="http://1.bp.blogspot.com/-Cz15osAD6X4/VOjJbbev6hI/AAAAAAAAAgo/dy8jB7SH508/s1600/java.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-Cz15osAD6X4/VOjJbbev6hI/AAAAAAAAAgo/dy8jB7SH508/s1600/java.png" height="257" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8000001907349px;">Niemeyer P., Leuck, D., "Learning Java, Fourth Edition", O'REILLY Atlas online version[1]</td></tr>
</tbody></table>
</div>
A trusted java compiler will not produce such malicious bytecodes, but it is possible to an outsider to malform the bytecodes of a class and it is java verifier's job to detect such <u>certain</u> instances. For additional readings please refer <a href="https://www.blogger.com/blogger.g?blogID=8433516278710251551#ref2">[2]</a>.</div>
</div>
<br />
<h4>
Links</h4>
<a href="https://www.blogger.com/null" name="ref1" style="position: relative; top: -30px;"></a>[1] WSO2 AS Documentation, Available Online: <a href="https://docs.wso2.com/display/AS521/JiBX+Data+Binding">https://docs.wso2.com/display/AS521/JiBX+Data+Binding</a>
<a href="https://www.blogger.com/null" name="ref2"></a>[2] Niemeyer P., Leuck, D., "Learning Java, Fourth Edition",chapter 1, O'REILLY Atlas, Available Online: <a href="http://chimera.labs.oreilly.com/books/1234000001805/ch01.html#learnjava3-CHP-1-SECT-5.1">http://chimera.labs.oreilly.com/books/1234000001805/ch01.html#learnjava3-CHP-1-SECT-5.1</a>Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-41030962142594471382015-02-21T02:19:00.001-08:002015-02-21T02:48:33.699-08:00Mac OS X Finder and Terminal ShortcutsThese are some of simple tricks that came across when I was working with Mac OS X - Yosemite. Most of them will work with older versions such as Mavericks and Mountain Lion.<br />
<br />
<ul>
<li><a href="#t1">How do you navigate to the '/usr/local' from the `Finder` program?</a></li>
<li><a href="#t2">Open current path of the terminal in Finder?</a></li>
<li><a href="#t3">Open '/usr' on the File Open Dialog?</a></li>
<li><a href="#t4">Get current address of a file into terminal?</a></li>
<li><a href="#t5">Open a file in a user-specified texteditor using terminal?</a></li>
<li><a href="#t6">Show/Hide Hidden Files in Finder?</a></li>
</ul>
<br />
<a name="t1" ></a>
<h3>
How do you navigate to the '/usr/local' from the `Finder` program?</h3>
When you open the Finder you can only navigate into limited places(figure 1).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ndUhov8CzvY/VOhP9UKWqoI/AAAAAAAAAgU/DswleNvH-wQ/s1600/Screen%2BShot%2B2015-02-21%2Bat%2B2.58.38%2BPM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-ndUhov8CzvY/VOhP9UKWqoI/AAAAAAAAAgU/DswleNvH-wQ/s1600/Screen%2BShot%2B2015-02-21%2Bat%2B2.58.38%2BPM.png" height="246" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Figure 1: `Goto` places in Finder</td></tr>
</tbody></table>
<br />
<br />
But for a scenario such as navigate into '<b>/usr/local</b>'. How do you do that? It is simple. Just type following on the terminal;<br />
<br />
<pre class="brush:bash">open '/usr/local'
</pre>
<br />
To get to know more about `open` command goto <a href="https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/open.1.html" target="_blank">this</a> link or type `man open`. Then `Q` to exit from the manual.<br />
<br />
<a name="t2"></a>
<h3>
Open current path of the terminal in Finder?</h3>
Surprisingly YES from me. You can open your current terminal path on the terminal by typing(Note the dot);<br />
<br />
<pre class="brush:bash">open .</pre>
<br />
<a name="t3"></a>
<h3>
Open '/usr' on the File Open Dialog?</h3>
<div>
Yes, you can use 'GoTo' feature. Just press [⌘Command]+[<span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⇧</span>Shift]+[G] on the file open dialog. Then type '/usr'. Voila !!!</div>
<div>
<br /></div>
<a name="t4"></a>
<h3>
Get current address of a file into terminal?</h3>
<div>
Just drag and drop the file/directory you want into the terminal.</div>
<div>
<br /></div>
<a name="t5" style='position:relative; top:-35px;'></a>
<h3>
Open a file in a user-specified texteditor using terminal?</h3>
<div>
You can create an alias for saving your time! Here how to do it. </div>
<div>
<br /></div>
<div>
First we need to create/edit the ~/bash_profile file. You can use any simple texteditor such as nano or vim. I am using nano. In the terminal type;</div>
<div>
<br /></div>
<pre class="brush:bash">nano ~/.bash_profile</pre>
<div>
<br /></div>
<div>
If there are any existing data, don't do any changes for those and start from a new line and type;</div>
<div>
<br /></div>
<div>
<div class="p1">
<pre class="brush:bash">alias te='open -a /Applications/Sublime\ Text\ 2.app'</pre>
</div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">Notice that I am defining a alias called `te` that executes the `open -a` command. Next part is the path for your text editor. Most of the time your already installed text-editor will appeared on the /Applications folder.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1">In nano editor once you done with adding the text, type [</span><span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌃</span><span class="s1">control]+[O] to write-out and press [Enter] to confirm. Then [</span><span style="background-color: white; color: #333333; font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 18px; line-height: 27px;">⌃</span><span class="s1">control]+[X] to exit.</span> </div>
<div class="p1">
<br /></div>
<div class="p1">
Then type;</div>
<div class="p1">
<br /></div>
<pre class="brush:bash">source ~/.bash_profile</pre>
<div class="p1">
<br /></div>
<div class="p1">
This will reload your settings in the ~/.bash_profile into current terminal emulator.<br />
<br />
Now you can use `te ~/Downloads/sample.txt` to open the `sample.txt` using the texteditor you chose. In my case, It is Sublime 2.</div>
<a name="t6" ></a>
<h3>
Show/Hide Hidden Files in Finder?</h3>
</div>
<div>
To show all hidden files, paste this in the terminal;</div>
<div>
<br /></div>
<pre class="brush:bash">defaults write com.apple.finder AppleShowAllFiles YES; killall Finder /System/Library/CoreServices/Finder.app</pre>
<div>
<br /></div>
<div>
To hide all hidden files again, paste this in the terminal;</div>
<div>
<br /></div>
<pre class="brush:bash">defaults write com.apple.finder AppleShowAllFiles NO; killall Finder /System/Library/CoreServices/Finder.app</pre>Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-25973682668758125292015-02-08T07:14:00.000-08:002015-02-08T07:26:24.049-08:00How to fix Java Apps Getting Blurred on Retina Displays MAC OS XHave you experienced this too???. My MacBook was shipped with JDK 1.6.0. So I installed JDK 1.7u07. Soon after I realized that all java based applications(or running on the newer JVM) are getting blurred. Look closer on these two images;<br />
<br />
`Android Studio` on JDK 1.7u07;<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPnw9DoeRuBTmXkTOqvbzXXuJLsxiFht0KkZQOZnhvLglk6VKt3b1rjoWFau1wCGtnLgOcmt5fBYIIxunLFF48rDbNvjjqEWtT5K2kBW5EPKWJwnxJMzh_lgcee0XKuedFnRDbRs1wNm0/s1600/Screen+Shot+2015-02-08+at+8.15.27+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPnw9DoeRuBTmXkTOqvbzXXuJLsxiFht0KkZQOZnhvLglk6VKt3b1rjoWFau1wCGtnLgOcmt5fBYIIxunLFF48rDbNvjjqEWtT5K2kBW5EPKWJwnxJMzh_lgcee0XKuedFnRDbRs1wNm0/s1600/Screen+Shot+2015-02-08+at+8.15.27+PM.png" height="300" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
`Android Studio` on JDK1.7u40;</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlFrs4-TMPfLj8mxwmTnE7lH3j07NPUgC_IQne1cUr-uIxM99J0vdgaKE7xBEm3cQyUAy9puGj2mJMldi5r7mbB5lLPP1Z4uzDpTp7V7gJ_a_7qmDL6xQEYVPbiPeGwI8J6YDq7FOuMd4/s1600/Screen+Shot+2015-02-08+at+8.16.21+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlFrs4-TMPfLj8mxwmTnE7lH3j07NPUgC_IQne1cUr-uIxM99J0vdgaKE7xBEm3cQyUAy9puGj2mJMldi5r7mbB5lLPP1Z4uzDpTp7V7gJ_a_7qmDL6xQEYVPbiPeGwI8J6YDq7FOuMd4/s1600/Screen+Shot+2015-02-08+at+8.16.21+PM.png" height="300" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
It is negligible, isn't it???</h3>
Of course it is not a big issue but having eyes on the screen for long hours will be definitely yelling; "There is something....!!!". So I decided to dig into the problem and found out, that is because JDK 1.7 support issue.<br />
<br />
AWT/ Swing under the JDK 1.7(as before 1.7u40) had an issue with HiDPI displays. HiDPI (High Dots Per Inch) also known as Apple's "<a href="http://en.wikipedia.org/wiki/Retina_Display" target="_blank">Retina Display</a>" marketing name, which are screens with a high resolution in a relatively small format<sup>[1]</sup>.<br />
<div>
<ul>
</ul>
<div>
<h3>
<b>So What is the Solution???</b></h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglo8deZmWuO46m7g8dDQl6_TFdlITsn0fon6gwIc8fzFkr7Uf02TCq8nbsNlLEZYG1h9ut6bVInizxTDOeM2aR6FFP5K_LHhgMGx8oAtNWKvz4aGb2t-ILM5X6YrbFC1tGlCanmJAc0Ic/s1600/solution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglo8deZmWuO46m7g8dDQl6_TFdlITsn0fon6gwIc8fzFkr7Uf02TCq8nbsNlLEZYG1h9ut6bVInizxTDOeM2aR6FFP5K_LHhgMGx8oAtNWKvz4aGb2t-ILM5X6YrbFC1tGlCanmJAc0Ic/s1600/solution.png" /></a></div>
<b><br /></b>
<b><br /></b><br />
<div>
According to <a href="http://www.oracle.com/technetwork/java/javase/7u40-relnotes-2004172.html" target="_blank">this change log</a> it is been fixed on JDK1.7u40. HiDPI or retina support is available on <sup>[2]</sup>;</div>
<div>
<ul>
<li>Java 6</li>
<li>Java 7u40ea or greater</li>
<li>Java 8</li>
</ul>
</div>
So the solution is to <b>upgrade</b> you current JDK into one of above matching criteria. </div>
<div>
<br /></div>
<div>
Have a Happy Coding Day !!! </div>
<div>
<br /></div>
<div>
Links</div>
</div>
<div>
[1] https://wiki.archlinux.org/index.php/HiDPI</div>
<div>
[2] http://stackoverflow.com/questions/15181079/apple-retina-display-support-in-java-jdk-1-7-for-awt-swing</div>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-66958815987731581192015-01-27T10:50:00.000-08:002015-01-27T10:56:49.036-08:00Syntax Highlighting bash terminal and vim in Mac OS XSo far I was not a huge Apple fan. However, recently I received a MacBook Pro(Amazing Huh!). In Mac OS X; your default terminal shell is bash. But the Terminal itself put a burden on me; Unlike it is in Ubuntu or Cent OS; the folders and files names...etc are not color coded ending up frustrating.
<br />
<br />
Here is how I made it colorful :P<br />
<br />
<b>STEP 1: </b><br />
Open up your terminal. You can simply press [⌘Command]+[SpaceBar] to appear 'Spotlight Search' and type 'terminal' and hit enter.<br />
<br />
<br />
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgteFDyQ-3OoPOdz0d1nVLCdurL25-agxeNApeXv6CjZBTruYyP9OYXyER4LkTRBqXfakOz6yE4jROXAgVOkFIhiKBFflXzp_4rMrZ-YD3MVPUBJhiV9mFRAeyvdqCbVF8jp8DxhPYlJs8/s1600/Screen+Shot+2015-01-27+at+11.46.24+PM.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgteFDyQ-3OoPOdz0d1nVLCdurL25-agxeNApeXv6CjZBTruYyP9OYXyER4LkTRBqXfakOz6yE4jROXAgVOkFIhiKBFflXzp_4rMrZ-YD3MVPUBJhiV9mFRAeyvdqCbVF8jp8DxhPYlJs8/s320/Screen+Shot+2015-01-27+at+11.46.24+PM.jpg" /></a></div>
<b>STEP 2:</b><br />
<br />
type "cd ~" and hit enter.<br />
<br />
This will change the current directory into your home directory.<br />
<br />
<b>STEP 3:</b><br />
<br />
type "vim .bash_profile".<br />
<br />
This command will open ".bash_profile" in vim editor. vim is a CLI based text editor.<br />
<br />
<b>STEP 4:</b><br />
<br />
Hit [i] to enter into --INSERT-- mode. This will enable you to insert new characters into the document. If there '.bash_profile' is not existed before; 'vim' will create a new one for you and it will appear empty. Otherwise; make sure you are not changing other settings in the file.<br />
<br />
After entering --INSERT-- mode; type the following;<br />
<br />
<br />
<pre class="brush: bash">
export CLICOLOR=1
</pre>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3"><b>STEP 5:</b></span></div>
<div class="p1">
<span class="s3">Enter [Esc] to exit from --INSERT-- mode. Then type ":wq" and hit enter.</span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3">":wq" -> will write and quite from the vim</span></div>
<div class="p1">
<span class="s3">":q!" -> will exit without saving your changes(If you did something wrong!)</span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3"><b>STEP 6:</b></span></div>
<div class="p1">
<span class="s3">In the terminal; enter "source .bash_profile".</span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3">This will apply configurations into the current bash shell. Or you can skip this step and re-open the terminals.</span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3"><b>STEP 7:</b></span></div>
<div class="p1">
<span class="s3">Now type "ls -l" you will experience it ! Enjoy !!!</span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbXf7DLjHsVSEPnlWi5B8KHjsQPS2khRNVZUgEQdSYaHjYCn6jjevmeO8yZXSVBOBhVrLHn6Tv6gim0-2YRLETBGkzt4m9solMBxxpG_CN1YM-ag3-VoBGntqDpM7hsGc0t3wGqp3tGwU/s1600/Screen+Shot+2015-01-28+at+12.17.23+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbXf7DLjHsVSEPnlWi5B8KHjsQPS2khRNVZUgEQdSYaHjYCn6jjevmeO8yZXSVBOBhVrLHn6Tv6gim0-2YRLETBGkzt4m9solMBxxpG_CN1YM-ag3-VoBGntqDpM7hsGc0t3wGqp3tGwU/s1600/Screen+Shot+2015-01-28+at+12.17.23+AM.png" height="218" width="320" /></a></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3"><b>BONUS</b>:</span></div>
<div class="p1">
<span class="s3">If you need to highlight syntaxes in the vim editor as well; follow the same steps to edit the file. Simplest way is to create a file in '~/.vimrc'. </span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<div class="p1">
<span class="s3">So your command would be "vim ~/.vimrc" and enter the following;</span></div>
<div class="p1">
<span class="s3"><br /></span></div>
<pre class="brush: bash">
filetype plugin indent on
syntax on
</pre>
<div class="p2">
<span class="s4"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOsSLDcr1TVQjZfquc5SvR06BPEAbbVHyuLpRK_UN32oduOBQZWZotiY30rE1OXFg-IlgrrlwjlHRZtoyqC_SLERYJJq8OdN2L4DDf4z9Wx43-P1wE_HS2WLmwHh7Oolow2ImfIcemb4M/s1600/Screen+Shot+2015-01-28+at+12.15.30+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOsSLDcr1TVQjZfquc5SvR06BPEAbbVHyuLpRK_UN32oduOBQZWZotiY30rE1OXFg-IlgrrlwjlHRZtoyqC_SLERYJJq8OdN2L4DDf4z9Wx43-P1wE_HS2WLmwHh7Oolow2ImfIcemb4M/s1600/Screen+Shot+2015-01-28+at+12.15.30+AM.png" height="216" width="320" /></a></div>
<div class="p2">
<span class="s4"><br /></span></div>
<div class="p1">
<span class="s3"><br /></span></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-81803537888446646412014-08-15T22:43:00.001-07:002016-03-21T08:57:15.471-07:00Voice Recognition with ArduinoRecently I built a voice recognition circuit using Arduino. Voice recognition is not that easy with Arduino, It requires more processing and voice analyzing power. Keep in mind that all you have to deal with is a ATMega328P microcontroller running on 16MHz. That's why some modules like <a href="http://www.bitsophia.com/BitVoicer.aspx" target="_blank">BitVoicer</a> is outsourcing the processing power to the PC(Serial/UART or TCP/IP).
But modules like <a href="https://github.com/arjo129/uSpeech" target="_blank">uSpeech</a> are completely independent of the PC and can run on its own. Thus, I used uSpeech.<br />
<br />
uSpeech is a limited voice recognition software for the AVR. So, you can not directly write the text and expect it to recognize the speech. You need to deal with Phonemes. Hence,a fair amount of patient is needed. List of phonemes you would get is as below;<br />
<br />
<pre style="background-color: #f7f7f7; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; line-height: 1.45; overflow: auto; padding: 16px; word-wrap: normal;"><code style="background: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; line-height: inherit; margin: 0px; padding: 0px; word-break: normal; word-wrap: normal;">Phoneme | Literal
--------------------------------------------------------------------
e | The e sound.
--------------------------------------------------------------------
h | The `/sh/` sound. It can also be raised by
| `ch`, `j` and `z`
--------------------------------------------------------------------
v | The `v` sound, occasionally triggered by , 'z'
| (may need to be fixed)
--------------------------------------------------------------------
f | The `f` sound.
--------------------------------------------------------------------
s | The 's' sound.
--------------------------------------------------------------------
o | 'a','o','i','r','l','m','n' and 'u' sounds.
--------------------------------------------------------------------
' ' | Too Quiet for anything
--------------------------------------------------------------------</code></pre>
<br />
In order to get voice input you need a condenser mic with an operational amplifier (op-amp). The easiest way is to buy a MIC module which all are integrated. Try an <a href="http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR0.TRC0.H0.Xlm393+mic+module&_nkw=lm393+mic+module&_sacat=0" target="_blank">ebay search</a>.<br />
<br />
You can wire it as below. 220 ohm resistors are used.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6ZWzkE0DgaBYGiQGX3B7-GrxjZb-NZ87sTpwbRXNBjwbyFEBRIXbzTwjNpbQ77PBAulf4iYVA-fI7u2YYOxSj39OHRL1D3C_D7nnji2hjGc8nA-wxvTOztuo0j7QQYN3OntVFjPiC_Qw/s1600/voice+recognition_bb.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6ZWzkE0DgaBYGiQGX3B7-GrxjZb-NZ87sTpwbRXNBjwbyFEBRIXbzTwjNpbQ77PBAulf4iYVA-fI7u2YYOxSj39OHRL1D3C_D7nnji2hjGc8nA-wxvTOztuo0j7QQYN3OntVFjPiC_Qw/s1600/voice+recognition_bb.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">To Zoom in: click on the image<br />
<div>
<br /></div>
</td></tr>
</tbody></table>
This module has LM393 Op-amp chip and Electret condenser microphone.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCVpAbf2gJdUcwA8iqTlIKbwZdn1L5dwZtD8t6hsQSe7iJqJYy9eFcnCjz7hQdkM5z8PKhci66sjreB5P7YOj68sfiojMfgi_PzHJ-dLEhD3hQjnacTl_NYjTe7P3ImNYPI3X4OG8iIu0/s1600/$_12.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCVpAbf2gJdUcwA8iqTlIKbwZdn1L5dwZtD8t6hsQSe7iJqJYy9eFcnCjz7hQdkM5z8PKhci66sjreB5P7YOj68sfiojMfgi_PzHJ-dLEhD3hQjnacTl_NYjTe7P3ImNYPI3X4OG8iIu0/s1600/$_12.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This is what i bought from the ebay. Just 1.88 USD.</td></tr>
</tbody></table>
In uSpeech examples, what they actually compared is a single phoneme.It recognizes 6 phonemes (f, e, o, v, s, h). So it is handy for simple commands (if they have one of those phonemes), but it isn’t generalized at all. What i did is, I used a char[32] `buffer` to hold phoneme patterns. Then receiving `buffer` is compared with a list of predefined phoneme patterns. For instance my predefined patterns for green,orange and white are accordingly; "vvvoeeeeeeeofff", "hhhhhvoovvvvf", "hooooooffffffff". To compare which is the closest i used, minimum edit distance(<a href="http://en.wikipedia.org/wiki/Levenshtein_distance" target="_blank">Levenshtein distance</a>). But how to ignore irrelevant patterns? you can use a threshold.<br />
<br />
<pre class="brush: c; highlight: [2,3,4,12]">#include <uspeech.h>
#define ledGreen 7
#define ledOrange 6
#define ledWhite 5
#define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))
signal voice(A0);
const int BUFFER_MAX_PHONEMES=32;
char inputString[BUFFER_MAX_PHONEMES]; // Allocate some space for the string
byte index = 0; // Index into array; where to store the character
//
const int DICT_MAX_ELEMNTS=3;
char dict[DICT_MAX_ELEMNTS][BUFFER_MAX_PHONEMES]={"vvvoeeeeeeeofff","hhhhhvoovvvvf","hooooooffffffff"};
int LOWEST_COST_MAX_THREASHOLD=20;
void setup(){
/*
Phoneme | Literal
--------------------------------------------------------------------
e | The e sound.
--------------------------------------------------------------------
h | The `/sh/` sound. It can also be raised by
| `ch`, `j` and `z`
--------------------------------------------------------------------
v | The `v` sound, occasionally triggered by , 'z'
| (may need to be fixed)
--------------------------------------------------------------------
f | The `f` sound.
--------------------------------------------------------------------
s | The 's' sound.
--------------------------------------------------------------------
o | 'a','o','i','r','l','m','n' and 'u' sounds.
--------------------------------------------------------------------
' ' | Too Quiet for anything
--------------------------------------------------------------------
*/
voice.f_enabled = true;
voice.minVolume = 1500;
voice.fconstant = 500;
voice.econstant = 2;
voice.aconstant = 4;
voice.vconstant = 6;
voice.shconstant = 10;
voice.calibrate();
Serial.begin(9600);
pinMode(ledGreen, OUTPUT);
pinMode(ledOrange, OUTPUT);
pinMode(ledWhite, OUTPUT);
}
void loop(){
voice.sample();
char p = voice.getPhoneme();
if(p==' ' || index >= BUFFER_MAX_PHONEMES){
if(strLength(inputString)>0){
Serial.println("received:"+String(inputString));
parseCommand(inputString);
inputString[0]=0;//clear string char array
index=0;
}
}else{
//printArray(voice.arr);
inputString[index] = p; // Store it
index++;
inputString[index] = '\0'; // Null terminate the string
}
}
char* guessWord(char* target){
int len = strlen(target);//held target length
for(int i=0;i<DICT_MAX_ELEMNTS;i++){
//simple validation
if(dict[i]==target){
return dict[i];
}
}
unsigned int cost[DICT_MAX_ELEMNTS];//held minimum distance cost
//calculating each words cost and hits
for(int j=0;j<DICT_MAX_ELEMNTS;j++){//loop through the dictionary
cost[j]=levenshtein(dict[j],target);
Serial.println("dict[j]="+String(dict[j])+" target="+String(target)+" cost="+String(cost[j]));
}
//Determining lowest cost but still all letters in the pattern hitting word
int lowestCostIndex=-1;
int lowestCost=LOWEST_COST_MAX_THREASHOLD;
for(int j=0;j<DICT_MAX_ELEMNTS;j++){//loop through the dictionary
//Serial.println("dict[j]="+dict[j]+" dict[j].length()="+String(strlen(dict[j]))+" cost="+String(cost[j])+" hits="+String(hits[j])+" j="+String(j));
if(cost[j]<lowestCost){
lowestCost = cost[j];
lowestCostIndex=j;
}
}
//Serial.println("lowestCostIndex="+String(lowestCostIndex)+" lowestCost="+String(lowestCost));
if(lowestCostIndex>-1){
//Serial.println("lowestCost="+String(lowestCost)+" lowestCostIndex="+String(lowestCostIndex));
return dict[lowestCostIndex];
}else{
return "";
}
}
void parseCommand(char* str){
char *gWord = guessWord(str);
Serial.println("guessed :"+String(gWord));
if(gWord==""){
return;
}else if(gWord==dict[0]){
digitalWrite(ledGreen, HIGH);
digitalWrite(ledOrange, LOW);
digitalWrite(ledWhite, LOW);
}else if(gWord==dict[1]){
digitalWrite(ledGreen, LOW);
digitalWrite(ledOrange, HIGH);
digitalWrite(ledWhite, LOW);
}else if(gWord==dict[2]){
digitalWrite(ledGreen, LOW);
digitalWrite(ledOrange, LOW);
digitalWrite(ledWhite, HIGH);
}
}
unsigned int levenshtein(char *s1, char *s2) {
unsigned int s1len, s2len, x, y, lastdiag, olddiag;
s1len = strlen(s1);
s2len = strlen(s2);
unsigned int column[s1len+1];
for (y = 1; y <= s1len; y++)
column[y] = y;
for (x = 1; x <= s2len; x++) {
column[0] = x;
for (y = 1, lastdiag = x-1; y <= s1len; y++) {
olddiag = column[y];
column[y] = MIN3(column[y] + 1, column[y-1] + 1, lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1));
lastdiag = olddiag;
}
}
return(column[s1len]);
}
int strLength(char const* s) {
int i = 0;
while (s[i] != '\0' && s[i] != ' ')
++i;
return i;
}
</pre>
<br />
How to install uSpeech? download the zip file from <a href="https://github.com/arjo129/uSpeech" target="_blank">here</a>. Then, extract the files in to your arduino `Library` folder. In my case, it is on 'C:\Program Files (x86)\Arduino\libraries'. It should be in a separate folder, let's say 'uSpeech'. Finally, restart the Arduino IDE.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw3nprU3tZhmFcPryz9f4HorYTgRkb3Ncmu3FugT5q34_Ger9wARf0HO_uZkTmu2msDBrOloiqk7OZoqgy8_pdGbBbG18qsvXiKfn6bRwF06YteX_XShyxQBtL-grjAaqvAs9ySrRRhx8/s1600/path.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="215" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw3nprU3tZhmFcPryz9f4HorYTgRkb3Ncmu3FugT5q34_Ger9wARf0HO_uZkTmu2msDBrOloiqk7OZoqgy8_pdGbBbG18qsvXiKfn6bRwF06YteX_XShyxQBtL-grjAaqvAs9ySrRRhx8/s1600/path.JPG" width="400" /></a></div>
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/_zlD2lvWB7k" width="420"></iframe>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-13671366187628756732014-08-14T12:42:00.003-07:002014-08-14T12:53:09.635-07:00Movie Categorization Script<br />
I got a request from one of my batch mate to create a movie categorization software. So, I thought that would be great. Even I was suffering from it, thousands of movies... you just can't watch them and categorize each film. Then, I started writing a small script that is capable of getting IMDB movie category and `move` those files/folders to the relevant category folder.<br />
<br />
But the main problem is, name of the movie is not very straight forward. look at the list below;<br />
<br />
<ol>
<li>`Django Unchained[2012]DVD Screener-ETRG`</li>
<li>`2 STATES (2014) - 1CD - DVDRip - Hindi - x264 - MP3 - Mafiaking - [D3Si MaNiaCs]`</li>
<li>`Parker.2013.BRRip.XviD-S4A`</li>
</ol>
<br />
So, you need some tactics to tackle down them :) Please note that I didn't thought much about the performance. Even though, it is not fully optimized <b>it does the job quite well</b>! Please let me know your suggestions.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi1RR0J_ucIckEKlHIUCIlblZZCIu_ec8hovcyd7WvRxg97tFI7Z9M9lOcoJZkJqE0SuNSXxywVZFE_jarz46R4d69PYsfBL_CfG6TjOKzR_oEPwpKnvysA0PBMu0tEtCOzBSVYMrBUqE/s1600/1.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi1RR0J_ucIckEKlHIUCIlblZZCIu_ec8hovcyd7WvRxg97tFI7Z9M9lOcoJZkJqE0SuNSXxywVZFE_jarz46R4d69PYsfBL_CfG6TjOKzR_oEPwpKnvysA0PBMu0tEtCOzBSVYMrBUqE/s1600/1.JPG" height="300" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">You can drag and drop folders or files into the script</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmr-4Fe5_HvKf__WwlgqOhzYgsvD6jRAiGEEV-PVWv5X-984vEb2Mx6aPOEfkwux_AEBPx5rr9N4-GCZmPPa2C9oAyo-63NkyxbyPYhzJFZx-P0LsdD1-g2RsKH8SG08VGBuBIpw9h5_k/s1600/2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmr-4Fe5_HvKf__WwlgqOhzYgsvD6jRAiGEEV-PVWv5X-984vEb2Mx6aPOEfkwux_AEBPx5rr9N4-GCZmPPa2C9oAyo-63NkyxbyPYhzJFZx-P0LsdD1-g2RsKH8SG08VGBuBIpw9h5_k/s1600/2.JPG" height="63" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">movies will be categorized!!!</td></tr>
</tbody></table>
<br />
<br />
<a href="https://drive.google.com/file/d/0BzxqUIMB8O1neTFkanBMQVFSM0k/edit?usp=sharing" target="_blank"><b>Click here</b></a> to download the script.Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-4073721495146829692014-08-13T13:47:00.002-07:002015-02-22T05:41:40.059-08:00Android Playing YouTube Video without third-party AppsHave you tried to play a YouTube video in your App without any third-party application including YouTube App? Forget about everything and this is working perfectly. Follow these easy steps;<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ2_QT-0a3SyYhPSpd4zq21wZtLwmeZfBo4Kgl-f02C3wGbWL-YlqhAUrvo0niaK5tZDaJat0lwdFl0oS32i5-5N1eapiMS7xSs8IajvpP8wGaYBUnfFR-_UWYctldq8_Ey5nP5-CFobE/s1600/poster.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ2_QT-0a3SyYhPSpd4zq21wZtLwmeZfBo4Kgl-f02C3wGbWL-YlqhAUrvo0niaK5tZDaJat0lwdFl0oS32i5-5N1eapiMS7xSs8IajvpP8wGaYBUnfFR-_UWYctldq8_Ey5nP5-CFobE/s1600/poster.jpg" height="180" width="320" /></a></div>
<br />
<br />
First we need <a href="http://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol" target="_blank">RTSP</a> protocol URL. You can easily find RTSP link using following URL;<br />
<br />
http://gdata.youtube.com/feeds/mobile/videos/<your_video_id><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH0uXaPOQ3vloFcUtGWlzWNQ_T0W6tNn3YY6xF58R4tPaQvtH4_z_YCTTqEufRd2E-UMM_bmx67nfq0adQ5Tesx3UwbPZpC8LBpHUJ9LOvP7hVVz_EjGSNQrUfV6ntzWg4mFp0J4mSOFg/s1600/video.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH0uXaPOQ3vloFcUtGWlzWNQ_T0W6tNn3YY6xF58R4tPaQvtH4_z_YCTTqEufRd2E-UMM_bmx67nfq0adQ5Tesx3UwbPZpC8LBpHUJ9LOvP7hVVz_EjGSNQrUfV6ntzWg4mFp0J4mSOFg/s1600/video.png" height="86" width="320" /></a></div>
<br />
<br />
Once you paste this on a new tab of your webbrowser; it will print something similar to following;<br />
<br />
<pre class="brush: xml; highlight: [4]"><?xml version='1.0' encoding='UTF-8'?><media:group>
<media:category label='Film &amp; Animation' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Film
</media:category><media:content
url='rtsp://r3---sn-a5m7zu76.c.youtube.com/CiILENy73wIaGQnup-1SztVOYBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp' type='video/3gpp' medium='video' isDefault='true' expression='full' duration='597' yt:format='1'/>
<media:content url='rtsp://r3---sn-a5m7zu76.c.youtube.com/CiILENy73wIaGQnup-1SztVOYBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp' type='video/3gpp' medium='video' expression='full' duration='597' yt:format='6'/>
<media:description type='plain'>Big Buck Bunny tells the story of a giant rabbit with a heart bigger than himself.
When one sunny day three rodents rudely harass him, something snaps...
and the rabbit ain't no bunny anymore! In the typical cartoon tradition he prepares the nasty rodents a comical revenge...
</pre>
<br />
Note that highlighted link. It is your RSTP protocol link to your video. Then we need to create a seperate activity called `VideoActivity.java`.
<br />
<br />
<b>VideoActivity.java</b><br />
<pre class="brush: java;">public class VideoActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String vURL = extras.getString("EXTRA_VIDEO_URL");
VideoView videoView = (VideoView) findViewById(R.id.videoView1);
videoView.setVideoPath(vURL);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.start();
}
}
}</pre>
<br />
Create this layout `<b>activity_video.xml</b>` on res/layout folder.
<br />
<b>activity_video.xml</b><br />
<pre class="brush: xml;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<VideoView
android:id="@+id/videoView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_horizontal" />
</LinearLayout></pre>
<br />
***Don't forget to add `VideoActivity` into AndroidManifest.xml. It should be between <application> tags.
<br />
<br />
<pre class="brush: xml;"> <activity android:name="example.test.VideoActivity"
android:label="Video">
</activity></pre>
<br />
Now you can call this activity as follows;
<br />
<br />
<pre class="brush: java;">//define extra parameter
String vURL="rtsp://r3---sn-a5m7zu76.c.youtube.com/CiILENy73wIaGQnup-1SztVOYBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp";
//start activity passing extras
Intent intent = new Intent(this,VideoActivity.class);
intent.putExtra("EXTRA_VIDEO_URL", vURL);
startActivity(intent);</pre>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-66719541999052547382014-08-13T13:12:00.002-07:002015-02-21T02:51:01.510-08:00PhoneGap playing local video nativelyDoes anyone know how to play an video on PhoneGap? I wish I could use PhoneGap APIs to play a video, but I couldn't. They don't provide any video API. Closer bet would be Media API which allows to play an audio. I tried several third party plugins, but never had the luck. I spent more than 4-5 hours trying plethora of plugins which finally led to the unsuccessful efforts. All plugins are compiled without giving any single error, but once you tried to play it on mobile, it says "sorry this video cannot be played".<br />
<div>
<br /></div>
<div>
This is the work around I did, hope anyone will find this helpful.</div>
<div>
<br /></div>
<div>
<b>STEP 1:</b> Drag and drop your video file into the `raw` folder under the `res` folder (If you don't have raw folder, create a new one).</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjUdLSw3fiLRZW0SRza-XgjRSjN_JkAPPZX6cy4JmKLTeV6X3dm3X60BIGnVY52Je70e27P6A8F30J_Ll2M_rnDR2RMu2S_IF3BrcaCSW9e-fWd_q3uOOaQ5N4BgXAgwJCEankSMtbpO8/s1600/1.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjUdLSw3fiLRZW0SRza-XgjRSjN_JkAPPZX6cy4JmKLTeV6X3dm3X60BIGnVY52Je70e27P6A8F30J_Ll2M_rnDR2RMu2S_IF3BrcaCSW9e-fWd_q3uOOaQ5N4BgXAgwJCEankSMtbpO8/s1600/1.JPG" height="320" width="204" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">add your video file here</td></tr>
</tbody></table>
<div>
<b>STEP 2:</b> Create a new class called `VideoActivity.java` and paste the code below. Change the highlighted package name as appropriate.</div>
<div>
<br /></div>
<pre class="brush: java;highlight: [1]">package example.android.test;
public class VideoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String videoName = extras.getString("EXTRA_VIDEO_NAME");
if (videoName.equals("hatseller")){
VideoView videoView = (VideoView) findViewById(R.id.videoView1);
String path = "android.resource://" + getPackageName() + "/" + R.raw.video;
videoView.setVideoPath(path);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Intent intent = new Intent(VideoActivity.this,StoryTeller.class);
intent.putExtra("FORWARD", "questions");
startActivity(intent);
}
});
videoView.start();
}
}
}
}
</pre>
<b>STEP 3: </b>Create this layout `<b>activity_video.xml</b>` on res/layout folder.
<br />
<b>activity_video.xml</b><br />
<pre class="brush: xml;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<VideoView
android:id="@+id/videoView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_horizontal" />
</LinearLayout></pre>
<b>STEP 4:</b> Insert VideoActivity into the AndroidManifest.xml. This should be defined inside the <application> tag. (Highlighted package name should be changed accordingly).<br />
<br />
<pre class="brush: xml;highlight: [1]"> <activity android:name="example.android.test.VideoActivity"
android:label="Video"
android:screenOrientation="landscape">
</activity>
</pre>
<br />
<b>STEP 5: </b>Modify your DroidGap class and include following functions;<br />
<br />
<pre class="brush: java; highlight: [5,6,9,10,11,12,13,14,15]">@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init(); // Calling this is necessary to make this work
appView.addJavascriptInterface(this, "MainActivity");
super.loadUrl("file:///android_asset/www/index.html");
public void customVideoFunction() {
//Log.e("Custom Function Called", "Custom Function Called");
//define extra parameter
String videoName="hatseller";
//start activity passing extras
Intent intent = new Intent(this,VideoActivity.class);
intent.putExtra("EXTRA_VIDEO_NAME", videoName);
startActivity(intent);
}
</pre>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2T7xdEukKoUh-pJ9g5XM4FVhZwHiNw5MVtQq425FcDOAvJGjkiw5yz1tPOk-39uyjfF-Upgi5qHYL56Mc8HPSXn1bfhQ1agMUrba7Ov2A-wF2HoRsQsIkiZFHDs7MzG1_166KyHdKxj4/s1600/2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2T7xdEukKoUh-pJ9g5XM4FVhZwHiNw5MVtQq425FcDOAvJGjkiw5yz1tPOk-39uyjfF-Upgi5qHYL56Mc8HPSXn1bfhQ1agMUrba7Ov2A-wF2HoRsQsIkiZFHDs7MzG1_166KyHdKxj4/s1600/2.JPG" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">this is my droidGap class</td></tr>
</tbody></table>
<br />
<b>STEP 6: </b>Change your HTML file as follows;<br />
<br />
<pre class="brush: html; highlight: [23,39,44]"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/jquery.mobile-1.4.2.css" />
<title>Hello World</title>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Anatomy of a Page</h1>
<a href="index.html" data-icon="home" data-iconpos="notext" data-direction="reverse">Home</a>
<a href="index.html" data-icon="search" data-iconpos="notext" data-rel="dialog" data-transition="fade">Search</a>
</div><!-- /header -->
<span class="Apple-tab-span" style="white-space: pre;">
<div data-role="content">
Loading video...
</div><!-- /content -->
<div id="deviceready" style="display:none">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
</div>
<div data-role="footer">
<p>&copy; 2014 tiriboy</p>
</div>
<span class="Apple-tab-span" style="white-space: pre;"> </div><!-- /page -->
<span class="Apple-tab-span" style="white-space: pre;">
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/jquery.mobile-1.4.2.min.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript">
app.initialize();
document.addEventListener("deviceready",onDeviceReady,false);
// Cordova is ready
//
function onDeviceReady () {
window.MainActivity.customVideoFunction();
}
</script>
</body>
</html>
</span></span></span></pre>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-36575937670569988882014-08-13T11:25:00.000-07:002015-02-21T19:20:54.307-08:00Coding more than Four `7segment` display panels on ArduinoRecently I coded a seven segment display for a friend of mine. Hope <a href="http://learn.parallax.com/4-digit-7-segment-led-display-arduino-demo" target="_blank">this</a> might be helpful for wiring purposes. My task was to correctly display 5 digit number on 5 `seven segments`. So, most of the examples out there including <a href="http://learn.parallax.com/4-digit-7-segment-led-display-arduino-demo" target="_blank">this</a> module support only <b>up to</b> 4 segments. So, I wrote my own code from the scratch.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJSBQX1KkR3wZUMb1bARoVc0LmNoWWMxvfzFsE8WGcUfSpRfR2HYGVi6-WcGbRQ64p4ob3TcG0E-Io4JBHbcpvzcndiXcjc9kS1OSQXVzOeQPBksB1r0teIRJsX4zCbf3B2CSbm48Qbvo/s1600/7segment.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJSBQX1KkR3wZUMb1bARoVc0LmNoWWMxvfzFsE8WGcUfSpRfR2HYGVi6-WcGbRQ64p4ob3TcG0E-Io4JBHbcpvzcndiXcjc9kS1OSQXVzOeQPBksB1r0teIRJsX4zCbf3B2CSbm48Qbvo/s1600/7segment.png" height="231" width="400" /></a></div>
<br />
This is the code, I wrote:<br />
<br />
<pre class="brush: c;">const int SEGMENT_RENDER_DELAY_MS=5;//segment rendering delay
const int MAX_NUM_SEGMENTS=5;//store maximum segments
//
String inputString = ""; // a string to hold incoming data
String displayStr="hellO"; //current display string (keep empty to display all zero's!)
//unsigned long digit; // display digit, if you are dealing only with numbers
// a
// =======
// || ||
// f || || b
// || g ||
// =======
// || ||
// e || || c
// || d ||
// =======
byte seven_seg[16][9] = { {0,0, 1,1,1,1,1,1,0 }, // = 0
{0,0, 0,1,1,0,0,0,0 }, // = 1
{0,0, 1,1,0,1,1,0,1 }, // = 2
{0,0, 1,1,1,1,0,0,1 }, // = 3
{0,0, 0,1,1,0,0,1,1 }, // = 4
{0,0, 1,0,1,1,0,1,1 }, // = 5
{0,0, 1,0,1,1,1,1,1 }, // = 6
{0,0, 1,1,1,0,0,0,0 }, // = 7
{0,0, 1,1,1,1,1,1,1 }, // = 8
{0,0, 1,1,1,0,0,1,1 }, // = 9
{0,0, 1,0,0,1,1,1,1 }, // = e
{0,0, 0,0,0,0,1,0,1 }, // = r
{0,0, 0,0,1,1,1,0,1 }, // = o
{0,0, 1,1,1,1,1,1,0 }, // = O
{0,0, 0,1,1,0,1,1,1 }, // = h
{0,0, 0,0,0,1,1,1,0 } // = l
};
byte firstSegmentPos = 0, secSegmentPos = 0,thirdSegmentPos = 0, fourthSegmentPos = 0, fifthSegmentPos = 0;
//
int pin;
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
//define output pins
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}
void loop() {
updateSegments();
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
//if linebreak found, parse it
if (inChar == '\r'||inChar == '\n') {
//we got a break, parse string
parseCode(&inputString);
inputString="";
}else{
//append the character received
inputString += inChar;
}
}
}
/**
* Parses one line of transaction
* If validation failed-> error displayed Or value displayed
**/
void parseCode(String* receivedLine){
String line = *receivedLine;
line.trim();//remove spaces
//
int lineLength=line.length();//length of the line received
String rv="";
if(lineLength <= MAX_NUM_SEGMENTS){
rv=line;//set to display value
//nSuccessTrans++;
}else{
rv="error";
//nFailTrans++;
}
displayStr=rv;//set to display value
//digit = displayStr.toInt();// if you are dealing only with numbers
}
/**
* Updates Display Segments
**/
void updateSegments(){
/*
fifthSegmentPos = digit / 10000;
digit %= 10000;
fourthSegmentPos = digit / 1000;
digit %= 1000;
thirdSegmentPos = digit / 100;
digit %= 100;
secSegmentPos = digit / 10;
firstSegmentPos = digit % 10;
*/
firstSegmentPos = GetSegmentCharPos(&displayStr,1);
secSegmentPos = GetSegmentCharPos(&displayStr,2);
thirdSegmentPos = GetSegmentCharPos(&displayStr,3);
fourthSegmentPos = GetSegmentCharPos(&displayStr,4);
fifthSegmentPos = GetSegmentCharPos(&displayStr,5);
//Serial.println("first segment");
digitalWrite(9,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
displaySegmentChar(&firstSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("second segment");
digitalWrite(9,LOW);
digitalWrite(10,HIGH);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
displaySegmentChar(&secSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("third segment");
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
displaySegmentChar(&thirdSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("fourth segment");
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,HIGH);
digitalWrite(13,LOW);
displaySegmentChar(&fourthSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("fifth segment");
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,HIGH);
displaySegmentChar(&fifthSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
}
/**
* Returns position of the rendering `segment character`
**/
static int GetSegmentCharPos(String* strNum, int pos){
String strNumber = *strNum;
if(strNumber.length()==0) return 0;
if(strNumber.length()>=pos){
char c = strNumber.charAt(strNumber.length()-pos);
if(c=='e') return 10;//e
if(c=='r') return 11;//r
if(c=='o') return 12;//o
if(c=='O') return 13;//O
if(c=='h') return 14;//h
if(c=='l') return 15;//l
if(c-'0'>0) return c-'0';//digit [0-9]
}
return 0;
}
/**
* Sketches single digit
**/
void displaySegmentChar(byte* pos) {
int digitPos = *pos;
for(pin = 2;pin < 9; pin++) {
digitalWrite(pin,seven_seg[digitPos][pin]);
}
}
</pre>
This code holds to be displayed code as a String object i.e. `displayStr` because i needed to display non-numeric characters as well(e.g. `error`). If you only need digits, you may use unsigned long called `digit`. And you can use following code to get segment numbers;
<pre class="brush: c;">
fifthSegmentPos = digit / 10000;
digit %= 10000;
fourthSegmentPos = digit / 1000;
digit %= 1000;
thirdSegmentPos = digit / 100;
digit %= 100;
secSegmentPos = digit / 10;
firstSegmentPos = digit % 10;
</pre>
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-72653154904390034252014-07-15T23:43:00.000-07:002015-02-21T19:22:14.889-08:00ATMega328P MalfunctioningAs i mentioned in my previous <a href="http://tiriboy.blogspot.com/2014/08/arduino-part-1.html" target="_blank">post</a>, I ordered a chinese Arduino UNO R3 version board. It is pretty cool compared to genuine more additional features. But you'd not get default LED light connected to the pin 13 and Tx Rx LEDs.<br />
<br />
This is my experience with Arduino UNO R3 version board. Since I already worked with Arduino boards at Uni, I was little bit surprised since once you connected USB cable to the PC and If you correctly installed Arduino IDE(with drivers) but STILL it is not detecting my board.<br />
<br />
After spending couple of times, I realized that these version boards using a different chip for USB-to-Serial communication namely CH340/CH341 instead of ATmega16U2.
Finally i installed CH340 Serial drivers and it connected perfectly.<br />
<br />
Then i got this "Blink" example from the IDE and tried to upload it.But unfortunately It gave following error.<br />
<div>
<br /></div>
<br />
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://s27.postimg.org/td6zd7meb/capture3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://s27.postimg.org/td6zd7meb/capture3.jpg" height="640" width="435" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This is because Arduino IDE tells ATMEGA328P's bootloader to write some bytes, then IDE tries to read again from the bootloader to verify. But it fails. which means bootloader unable to write to its flash. So i tried several times several options which is on the Internet; but never worked out. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Finally i concluded that my ATMEGA328P is no longer usable.</div>
</div>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-54725511252582460852014-07-14T23:00:00.000-07:002015-02-21T19:21:46.306-08:00Arduino IntroductionI recently started developing with Arduino. In the old days we had to develop everything from the scratch. Arduino and other DIY kits makes it lot easier. If you are in two minds whether to buy Arduino or `Raspberry Pi`. I would simply say, If your project is something to do with hardware Arduino is most suitable. If your project is something to do with software more then `Raspberry Pi` would be a better choice. But notice that you need to think other factors as well.<br />
<br />
I ordered chineese Ardunio UNO R3 version board. Almost every functionality as original UNO and few things more. major difference is CH340 chip for USB-Serial instead of ATmega16U2.So it won't be automatically detect and install drivers for you. You need to install CH340 drivers first. Main programmable chip is same ATMega328P.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik-BDeOOBoObbxvHvO3OYaHEPnzOK8Z6u_dGK90Dh3i_uBGNs4WfbsEqDLU8-VjexZQERREZbVI-JQAD6aDisx3KjP4dpXn6Vz6LxxTpJCPB1yRQhA1Gt0mHKTMSKGM6XigCwHAcPXo1w/s1600/IMG_20140716_092531.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik-BDeOOBoObbxvHvO3OYaHEPnzOK8Z6u_dGK90Dh3i_uBGNs4WfbsEqDLU8-VjexZQERREZbVI-JQAD6aDisx3KjP4dpXn6Vz6LxxTpJCPB1yRQhA1Gt0mHKTMSKGM6XigCwHAcPXo1w/s1600/IMG_20140716_092531.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">this is how Arduino UNO clone look likes</td></tr>
</tbody></table>
But never trust, a chinese... received a malfunctioning ATMEGA328P microcontroller. So I went pettah market(Sri Lanka), ATMega328P microcontroller costs 390 LKR only. Finally seller agreed to refund 5 USD.<br />
<br />
However i bought another Arduino UNO from here SL, costed me around 1600 LKR. Atleast it is more look like genuine.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEIHl9hzRxJleMggJaq0RTboCAqd3dlJFRAmL0u_SkjnoveIVNz0jkaWmHzj1tJHiHjfdbDzl70q1NoVQMsCxkNHGqRGHVuDyxn5NMfCzXk448Xav0tH4F5XRNvk6Tm8rLoH9TatXHl1s/s1600/DSCN0274.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEIHl9hzRxJleMggJaq0RTboCAqd3dlJFRAmL0u_SkjnoveIVNz0jkaWmHzj1tJHiHjfdbDzl70q1NoVQMsCxkNHGqRGHVuDyxn5NMfCzXk448Xav0tH4F5XRNvk6Tm8rLoH9TatXHl1s/s1600/DSCN0274.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">this is another Arduino UNO more or less look like genuine</td></tr>
</tbody></table>
Following are the specifications of Arduino UNO R3;<br />
<br />
<br />
<table style="border: 1px solid #0082FA;">
<tbody>
<tr><td><b>Microcontroller</b></td><td>ATMega328P </td></tr>
<tr><td><b>Clock Speed</b></td><td>16MHz (but ATMega328P supports 20MHz)</td></tr>
<tr><td><b>Flash Memory</b></td><td>32K (ATMega328P) 0.5KB used by bootloader</td></tr>
<tr><td><b>EEPROM</b></td><td>1K (ATMega328P)</td></tr>
<tr><td><b>SRAM</b></td><td>2K (ATMega328P)</td></tr>
<tr><td><b>Digital I/O Pins</b></td><td>14(in which 6 PWM output supported)</td></tr>
<tr><td><b>Analog Output Pins</b></td><td>6</td></tr>
<tr><td><b>DC current per I/O pin</b></td><td>40mA</td></tr>
<tr><td><b>DC current per 3.3V pin</b></td><td>50mA</td></tr>
<tr><td><b>Operating Voltage</b></td><td>5V</td></tr>
<tr><td><b>Input Voltage</b></td><td>6-20V but 7-12V recommended</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiObqoE1xpXykWKra5s6fZYq-aE-L8Wfv31QFmWRkz259qkAgdJNd7E-j6iYKR3HT85ENnftiZN3hIGZsg4WhGY_YUPmHtsZjMFbWe9pwnNP45Q1IK6x7JGPrni_d0922acbXA9SbGJSG8/s1600/pinout.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiObqoE1xpXykWKra5s6fZYq-aE-L8Wfv31QFmWRkz259qkAgdJNd7E-j6iYKR3HT85ENnftiZN3hIGZsg4WhGY_YUPmHtsZjMFbWe9pwnNP45Q1IK6x7JGPrni_d0922acbXA9SbGJSG8/s1600/pinout.JPG" height="500" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arduino UNO R3 Pinout diagram</td></tr>
</tbody></table>
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-8433516278710251551.post-63219585499611797292014-06-08T00:24:00.001-07:002014-08-13T13:23:17.983-07:00Customize Bibliography Style on Microsoft Word 2007 / 2010 / 2013<span style="font-family: Arial, Helvetica, sans-serif;"> Microsoft Word is using their bibilograpghy styles from the Microsoft Word bibliography style directory. This directory can vary depending on where Word is installed:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><b><u>Word 2007</u></b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"> <winword .exe="" directory="">\Bibliography\Style</span><br />
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;">On most 32-bits machines with Microsoft Word 2007 this will be:</span><br />
<table style="background-color: #013E6F !important; border: 1px solid #0082FA !important; width: 100%;"><tbody>
<tr><td><span style="font-family: Arial, Helvetica, sans-serif;"> %programfiles%\Microsoft Office\Office12\Bibliography\Style</span>
</td></tr>
</tbody></table>
<span style="font-family: Arial, Helvetica, sans-serif;">Once the styles are copied to the directory, they will show up every time Microsoft Word is opened.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><b><u>Word 2010</u></b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"> <winword .exe="" directory="">\Bibliography\Style</span><br />
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;">On most 32-bits machines with Microsoft Word 2010 this will be:</span><br />
<table style="background-color: #013E6F !important; border: 1px solid #0082FA !important; width: 100%;"><tbody>
<tr><td><span style="font-family: Arial, Helvetica, sans-serif;"> %programfiles%\Microsoft Office\Office14\Bibliography\Style</span></td></tr>
</tbody></table>
<span style="font-family: Arial, Helvetica, sans-serif;">Once the styles are copied to the directory, they will show up every time Microsoft Word is opened.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b><u>Word 2013</u></b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"> <user directory="">\AppData\Roaming\Microsoft\Bibliography\Style</span><br />
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;">On most machines with Micrososft Word 2013 this will be:</span><br />
<table style="background-color: #013E6F !important; border: 1px solid #0082FA !important; width: 100%;"><tbody>
<tr><td><span style="font-family: Arial, Helvetica, sans-serif;"> %userprofile%\AppData\Roaming\Microsoft\Bibliography\Style</span></td></tr>
</tbody></table>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Once you locate above folder, you will find XML files related to each style(eg. APA,IEEE,Harvard,Chicago...etc). For the demonstration I will use Harvard style. So, hopefully my target file would be HarvardAnglia2008OfficeOnline.xsl. (Yes I know you still keep open MS Word, Please close it first!)</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Before moving into any further step It is highly recommended to create a backup first, to getting back to previous state. So you need to copy(CTRL+C) and paste(CTRL+V) the `HarvardAnglia2008OfficeOnline.xsl` file and rename it to `HarvardAnglia2008OfficeOnline.xsl.bck`.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3kRqrl2pPOniuBWsAFUuExC24dPJwRsJf8G3UzFsyzqtvPBBKVTPBnF0I-Q5Hecrn9B8A9zXhaC0DfcDLgtHmuhCi4g64rbs2Sci2USRCaVAHTy6ErA0gh6scXRub_nwp7USZ0PDCXFM/s1600/backup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3kRqrl2pPOniuBWsAFUuExC24dPJwRsJf8G3UzFsyzqtvPBBKVTPBnF0I-Q5Hecrn9B8A9zXhaC0DfcDLgtHmuhCi4g64rbs2Sci2USRCaVAHTy6ErA0gh6scXRub_nwp7USZ0PDCXFM/s1600/backup.png" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Then you can open it on notepad or any text editor. I would recommend notepad++. Wait! Since Windows background processes are reading this file you cannot simply open it up! You need to open your text editor with Administrator Priviledges. Now How to do that? It's simple, just right click on the text editor an choose 'Run as Administrator'.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl_No2Yt1N0TC13PcSQnHVr2qvpBFEsDh7UBiDbNcaSQMCnz5jeIiIT8zwTO2bsPjW1bGtNNSbXYovvKLth7YkO_B-kumP5H5RHR6BS5DEcmbGpLmhdxA4Cmsy9lIgFwurh45oO8QwQcc/s1600/run-as-admin.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl_No2Yt1N0TC13PcSQnHVr2qvpBFEsDh7UBiDbNcaSQMCnz5jeIiIT8zwTO2bsPjW1bGtNNSbXYovvKLth7YkO_B-kumP5H5RHR6BS5DEcmbGpLmhdxA4Cmsy9lIgFwurh45oO8QwQcc/s320/run-as-admin.png" /></a>
</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Now we have open the `HarvardAnglia2008OfficeOnline.xsl`. Now I need to remove Opening bracket '(' and Closing bracket ')' from the references. You need to locate 'OpenBracket' template first. Press CTRL+F to open `Find Next` window. Type 'OpenBracket' and press 'Find Next'. press it until you will find something like following;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhokmuz-_GT65jNOH7C4Dn0aeUHKqGtMWeIqg-bwrJTIrl1mMTL4vjPiFE3CnYLRmbcjojcAz9zewU32x2B8L-r6JSVGEiYahJfpmbaRc_jofQAuLWfUTi8o6c0_aLsS-3fWFYQTjecv1g/s1600/openbracket.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhokmuz-_GT65jNOH7C4Dn0aeUHKqGtMWeIqg-bwrJTIrl1mMTL4vjPiFE3CnYLRmbcjojcAz9zewU32x2B8L-r6JSVGEiYahJfpmbaRc_jofQAuLWfUTi8o6c0_aLsS-3fWFYQTjecv1g/s1600/openbracket.JPG" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Then comment the line "<xsl:value-of select="/*/b:Locals/b....." using '<!--' in the begging and '-->' at the end. Final output should be as below;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh1y81JVzDvr3Nc6SlTtQX2sI1MI_SXYjCFBQJ39Ai70QjqnpbmEuFiices7YVi6ikGHbndIEZyM97AL_5gjEG-vEz5Xzd4kQ6Qj6DOfMr2x-BURg8KttEo9B0eGUvZpnp_Fk463n0wsg/s1600/openbracket2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh1y81JVzDvr3Nc6SlTtQX2sI1MI_SXYjCFBQJ39Ai70QjqnpbmEuFiices7YVi6ikGHbndIEZyM97AL_5gjEG-vEz5Xzd4kQ6Qj6DOfMr2x-BURg8KttEo9B0eGUvZpnp_Fk463n0wsg/s1600/openbracket2.JPG" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Do the same for CloseBracket as well.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKnPBEedRayK2ZxGEl6uDpyCYtZqO1LHhfoNs9gDpHw85tlr_jzVuohB11ZOeGu1bSfrrtmzh3p8kKgj41dNyNk8hq1FGT8X1fLv838TBdQyP-Rruo7J84A0wiaCUj9zevLm0abSdpeD0/s1600/close+bracket.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKnPBEedRayK2ZxGEl6uDpyCYtZqO1LHhfoNs9gDpHw85tlr_jzVuohB11ZOeGu1bSfrrtmzh3p8kKgj41dNyNk8hq1FGT8X1fLv838TBdQyP-Rruo7J84A0wiaCUj9zevLm0abSdpeD0/s1600/close+bracket.JPG" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Now save the file. (File->Save).</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Open the MS Word and try to insert a new citation.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeo8wHMeW8cX5YtAH-BxBHOsn1MCVF0Lwu9PchITjgyDbjEw7ks94VvpKLsu0y5QvtA4OQ3_a-33A2q3BTDVda3x6O141zRN7OPbxdhoqVF0_jzATrfP3Qk56YYa29l4kUSwIeuGexqAQ/s1600/citation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeo8wHMeW8cX5YtAH-BxBHOsn1MCVF0Lwu9PchITjgyDbjEw7ks94VvpKLsu0y5QvtA4OQ3_a-33A2q3BTDVda3x6O141zRN7OPbxdhoqVF0_jzATrfP3Qk56YYa29l4kUSwIeuGexqAQ/s1600/citation.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="font-family: Arial, Helvetica, sans-serif;"> Voila! It is working!</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-vfz-0FYnr7cDyonZM0VMHTlr_vlBG6KG6qLO5wWFTx1XFQUVynwk2zJfXyFYRms1WUb5bvi4o5MbIoXQyEH-tIvb9rbbo9kWurlhOiKCYuktVlCXQp1qT4hdnvEpWTrwTN-ECf3a8lo/s1600/working.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-vfz-0FYnr7cDyonZM0VMHTlr_vlBG6KG6qLO5wWFTx1XFQUVynwk2zJfXyFYRms1WUb5bvi4o5MbIoXQyEH-tIvb9rbbo9kWurlhOiKCYuktVlCXQp1qT4hdnvEpWTrwTN-ECf3a8lo/s1600/working.png" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;">NOTE: citations you have already entered would not changed. If you need them to change, select all text (CTRL+A) and then press F9.</span>Unknownnoreply@blogger.com