/******************************************************************************* * Copyright (c) 2008, 2009 Bug Labs, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of Bug Labs, Inc. nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ package com.buglabs.bug.module.motion; import java.io.IOException; import java.io.InputStream; import java.util.Dictionary; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import com.buglabs.bug.accelerometer.pub.AccelerometerConfiguration; import com.buglabs.bug.accelerometer.pub.IAccelerometerControl; import com.buglabs.bug.accelerometer.pub.IAccelerometerRawFeed; import com.buglabs.bug.accelerometer.pub.IAccelerometerSampleFeed; import com.buglabs.bug.accelerometer.pub.IAccelerometerSampleProvider; import com.buglabs.bug.bmi.api.AbstractBUGModlet; import com.buglabs.bug.bmi.sysfs.BMIDevice; import com.buglabs.bug.dragonfly.module.IModuleControl; import com.buglabs.bug.dragonfly.module.IModuleLEDController; import com.buglabs.bug.jni.accelerometer.Accelerometer; import com.buglabs.bug.jni.common.CharDeviceInputStream; import com.buglabs.bug.jni.common.CharDeviceUtils; import com.buglabs.bug.jni.motion.MDACCControl; import com.buglabs.bug.jni.motion.Motion; import com.buglabs.bug.module.motion.pub.AccelerationWS; import com.buglabs.bug.module.motion.pub.IMDACCModuleControl; import com.buglabs.bug.module.motion.pub.IMotionRawFeed; import com.buglabs.bug.module.motion.pub.IMotionSubject; import com.buglabs.bug.module.motion.pub.MotionWS; import com.buglabs.services.ws.PublicWSProvider; /** * Modlet for the MOTION module. * @author kgilmer * */ public class MotionModlet extends AbstractBUGModlet implements IMDACCModuleControl, IModuleLEDController { // default is 0; make ours +1 since better than BUGview at accelerometer functionality. private final static int OUR_ACCELEROMETER_SERVICES_RANKING = 1; private ServiceRegistration moduleRef; private MotionRawFeed motiond; private AccelerometerSimpleRawFeed acceld; private Motion motionDevice; private InputStream motionIs; private InputStream accIs; private MotionSubject motionSubject; private Accelerometer accDevice; private MDACCControl mdaccControlDevice; private AccelerometerControl accControl; private AccelerometerSampleProvider asp; private boolean suspended; public MotionModlet(BundleContext context, int slotId, String moduleId, String moduleName, BMIDevice device) { super(context, moduleId, device, "MOTION"); } public void start() throws Exception { Dictionary modProperties = getCommonProperties(); modProperties.put("Power State", suspended ? "Suspended": "Active"); moduleRef = context.registerService(IModuleControl.class.getName(), this, modProperties); motionSubject.start(); registerService(IMotionSubject.class.getName(), motionSubject, getCommonProperties()); registerService(IMotionRawFeed.class.getName(), motiond, getCommonProperties()); registerService(IModuleLEDController.class.getName(), this, getCommonProperties()); MotionWS motionWS = new MotionWS(); motionSubject.register(motionWS); registerService(PublicWSProvider.class.getName(), motionWS, null); configureAccelerometer(); registerService(IAccelerometerRawFeed.class.getName(), acceld, createServicePropertiesWithRanking(OUR_ACCELEROMETER_SERVICES_RANKING)); asp = new AccelerometerSampleProvider(acceld); registerService(IAccelerometerSampleProvider.class.getName(), asp, createServicePropertiesWithRanking(OUR_ACCELEROMETER_SERVICES_RANKING)); registerService(IAccelerometerSampleFeed.class.getName(), acceld, createServicePropertiesWithRanking(OUR_ACCELEROMETER_SERVICES_RANKING)); registerService(IAccelerometerControl.class.getName(), accControl, createServicePropertiesWithRanking(OUR_ACCELEROMETER_SERVICES_RANKING)); AccelerationWS accWs = new AccelerationWS(asp, getLog()); registerService(PublicWSProvider.class.getName(), accWs, null); registerService(IMDACCModuleControl.class.getName(), this, getCommonProperties()); } private void configureAccelerometer() { AccelerometerConfiguration config = accDevice.ioctl_BMI_MDACC_ACCELEROMETER_GET_CONFIG(); config.setDelay((short) 250); config.setDelayResolution((byte) 5); config.setDelayMode((byte) 1); config.setRun((byte) 1); accDevice.ioctl_BMI_MDACC_ACCELEROMETER_SET_CONFIG(config); } public void stop() throws Exception { moduleRef.unregister(); motionSubject.interrupt(); motionDevice.ioctl_BMI_MDACC_MOTION_DETECTOR_STOP(); motionIs.close(); motionDevice.close(); mdaccControlDevice.close(); asp.close(); accDevice.ioctl_BMI_MDACC_ACCELEROMETER_STOP(); accIs.close(); super.stop(); } private Dictionary createServicePropertiesWithRanking(final int serviceRanking) { final Dictionary p = getCommonProperties(); p.put(Constants.SERVICE_RANKING, new Integer(serviceRanking)); return p; } private void updateIModuleControlProperties(){ if (moduleRef!=null){ Dictionary modProperties = getCommonProperties(); modProperties.put("Power State", suspended ? "Suspended": "Active"); moduleRef.setProperties(modProperties); } } public int resume() throws IOException { int result = -1; result = mdaccControlDevice.ioctl_BMI_MDACC_CTL_RESUME(); if (result < 0) { throw new IOException("ioctl BMI_MDACC_CTL_RESUME failed"); } suspended = false; updateIModuleControlProperties(); return result; } public int suspend() throws IOException { int result = -1; result = mdaccControlDevice.ioctl_BMI_MDACC_CTL_SUSPEND(); if (result < 0) { throw new IOException("ioctl BMI_MDACC_CTL_SUSPEND failed"); } suspended = true; updateIModuleControlProperties(); return result; } public void setup() throws Exception { int slot = getSlotId(); String devnode_motion = "/dev/bmi_mdacc_mot_m" + slot; String devnode_acc = "/dev/bmi_mdacc_acc_m" + slot; String devnode_mdacc_control = "/dev/bmi_mdacc_ctl_m" + slot; motionDevice = new Motion(); CharDeviceUtils.openDeviceWithRetry(motionDevice, devnode_motion, 2); int retval = motionDevice.ioctl_BMI_MDACC_MOTION_DETECTOR_RUN(); if (retval < 0) { throw new IOException("IOCTL Failed on: " + devnode_motion); } accDevice = new Accelerometer(); CharDeviceUtils.openDeviceWithRetry(accDevice, devnode_acc, 2); accIs = new CharDeviceInputStream(accDevice); accControl = new AccelerometerControl(accDevice); acceld = new AccelerometerSimpleRawFeed(accIs, accControl); mdaccControlDevice = new MDACCControl(); CharDeviceUtils.openDeviceWithRetry(mdaccControlDevice, devnode_mdacc_control, 2); motionIs = new CharDeviceInputStream(motionDevice); motiond = new MotionRawFeed(motionIs); motionSubject = new MotionSubject(motiond.getInputStream(), this, getLog()); } public int setLEDGreen(boolean state) throws IOException { if (mdaccControlDevice == null) { return -1; } else if (state) { return mdaccControlDevice.ioctl_BMI_MDACC_CTL_GREEN_LED_ON(); } else { return mdaccControlDevice.ioctl_BMI_MDACC_CTL_GREEN_LED_OFF(); } } public int setLEDRed(boolean state) throws IOException { if (mdaccControlDevice == null) { return -1; } else if (state) { return mdaccControlDevice.ioctl_BMI_MDACC_CTL_RED_LED_ON(); } else { return mdaccControlDevice.ioctl_BMI_MDACC_CTL_RED_LED_OFF(); } } public boolean isSuspended() { return suspended; } }