Fez Panda II USB host communication problem with Samsung Wave-8500 (BADA OS)

I am trying to develop an Accessory for my Samsung Wave phone which runs on Bada OS and for USB host I am trying to use Fez Panda II board.
Instead of using Android Phone and Arduino board I am trying with Samsung Wave & Fez Panda II board since BADA OS also have support for Accessory development.

Here is the link for Bada Tutorial for accessory app development:
http://developer.bada.com/documentation/docView.do?docID=D000001292&&searchCategoryID=C000000006&searchTag=&searchDisplayDate=¤tPage=1&menu=MC01310000&pageCount=10&orderField=DISP_DD_TXT_DESC&searchPubYNFlag=Y

On phone I am running a sample accessory application provided by Bada in above mentioned tutorial.
On Fez Panda board I am using below mentioned code which is modified as per Samsung wave phone communication requirement. While writing code for Fez Panda I referred the Arduino USB host code for the necessary configuration.

But I am not able to establish proper communication between Fez Panad Boad & Samsung Wave phone, every time after transferring few byte of Data, Fez Panad Boad hangs, on serial monitor I can’t see further communication. Also Phone initially show the USB connected state but later it shows Connected, Disconnected continuously.

I tried everything to establish the communication but didn’t get success, So requesting you to check the code and tell me what is missing for successful communication.

Also here is the Device & Configuration Info
Connection Information
Port: 3
Speed: High Speed (USB 2.0)
Device address: 7
Open pipes: 8
Connection status: Device connected

Device Descriptor
USB version: 2.0
Device class: 0xef - Miscellaneous Device
Device subclass: 0x2 - ?
Device protocol: 0x1 - Interface Association
Control pipe max size: 64 bytes
Vendor ID: 0x4e8 (Samsung Electronics Co., Ltd)
Product ID: 0x6860 (Unknown)
Product version: 4.0
Manufacturer: Not specified
Product: Not specified
Serial Number: Not specified
Configurations: 1

Configuration Descriptor
Number of interfaces: 4
Configuration value: 0x1
Attributes: Self powered, Bus powered
Max power: 100 mA

Interface Descriptor: 0, Alternate setting: 0
Number of endpoints: 3
Interface class: 0x6 - Imaging
Interface subclass: 0x1 - Still Image Capture
Interface protocol: 0x1 - Picture Transfer Protocol (PIMA 15470)
Endpoint address 0x5, Output, Bulk, max packet size: 512 bytes
Endpoint address 0x4, Input, Bulk, max packet size: 512 bytes
Endpoint address 0x6, Input, Interrupt, max packet size: 64 bytes, update interval: 4 1-millisecond frames

Unknown Descriptor (Type: 0xb, Length: 8 bytes)

Interface Descriptor: 1, Alternate setting: 0
Number of endpoints: 1
Interface class: 0x2 - Communications
Interface subclass: 0x2 - Abstract (modem)
Interface protocol: 0x1 - AT-commands (v.25ter)

[b]Communication Class-Specific Descriptor: 0x00 (Header Functional Descriptor)

Communication Class-Specific Descriptor: 0x02 (Abstract Control Management Functional Descriptor)
Capabilities: 00000020(bitmap)

Communication Class-Specific Descriptor: 0x06 (Union Functional Descriptor)
Master Interface 1
Slave Interface0: 2

Communication Class-Specific Descriptor: 0x01 (Call Management Functional Descriptor)
Capabilities: 00000021(bitmap)
Data Interface: 2
[/b]
Endpoint address 0x3, Input, Interrupt, max packet size: 64 bytes, update interval: 4 1-millisecond frames

Interface Descriptor: 2, Alternate setting: 0
Number of endpoints: 2
Interface class: 0xa - CDC Data
Interface subclass: 0x0 - Unused
Interface protocol: 0x0 - Unknown
Endpoint address 0x1, Input, Bulk, max packet size: 512 bytes
Endpoint address 0x2, Output, Bulk, max packet size: 512 bytes

Interface Descriptor: 3, Alternate setting: 0
Number of endpoints: 2
Interface class: 0xff - Vendor Specific Class
Interface subclass: 0x10 - Unknown
Interface protocol: 0x1 - Unknown
Endpoint address 0x8, Input, Bulk, max packet size: 512 bytes
Endpoint address 0x7, Output, Bulk, max packet size: 512 bytes

Source Code:

using System;
using System.Threading;
using System.IO.Ports;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.USBHost;
using System.Text;

namespace UsbHost
{
    public class Program
    {
        static SerialTracer tracer = new SerialTracer();

        public static void Main()
        {

            USBH_RawDevice openedDevice = null;
            var deviceOpened = new ManualResetEvent(false);

            tracer.WriteLine("-Started-");

            USBHostController.DeviceConnectedEvent += (device) =>
                        {
                            tracer.WriteLine("Device connected VID = " + device.VENDOR_ID
                                + " PID = " + device.PRODUCT_ID);
                            openedDevice = new USBH_RawDevice(device); deviceOpened.Set();
                        };

            tracer.WriteLine("Waiting for events");
            deviceOpened.WaitOne();
            deviceOpened.Reset();

            var configurationDescriptor = openedDevice.GetConfigurationDescriptors(0);

            USBH_RawDevice.Pipe outPipe = null;
            USBH_RawDevice.Pipe inPipe = null;

            USBH_Descriptors.Interface cdcinterface = null;
            byte CDCDataClass = 0x0A;
            bool bDataCDC = false;
            tracer.WriteLine(" Looking for CDCDataClass interface");
            foreach (var _interface in configurationDescriptor.interfaces)
            {
                if (_interface.bInterfaceClass == CDCDataClass)
                {
                    bDataCDC = true;
                    cdcinterface = _interface;
                    tracer.WriteLine(" CDCDataClass found, bInterfaceNumber =" + _interface.bInterfaceNumber
                         + " InterfaceProtocol =" + _interface.bInterfaceProtocol
                         + " InterfaceClass = " + _interface.bInterfaceClass
                         + " InterfaceSubclass = " + _interface.bInterfaceSubclass
                         + " bDescriptorType = " + _interface.bDescriptorType
                         + " bNumberEndpoints = " + _interface.bNumberEndpoints);
                    break;
                }
            }

            if (!bDataCDC)
            {
                tracer.WriteLine(" CDCDataClass not found exiting the app ");
                return;
            }

            tracer.WriteLine(" Setting configuration bConfigurationValue = " + configurationDescriptor.bConfigurationValue);
            // USB_SETUP_HOST_TO_DEVICE 0x00
            // USB_REQUEST_SET_CONFIGURATION = 0x09
            // SET CONFIGURATION
            openedDevice.SendSetupTransfer(0x00, 0x09, configurationDescriptor.bConfigurationValue, 0x00);

            //USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
            // 0x00 | 0x20 | 0x01 = 0x21
            byte bmREQ_CDCOUT = 0x21; // bmRequestType
            byte CDC_SET_CONTROL_LINE_STATE = 0x22; // bRequest
            byte SET_LINE_CODING = 0x20; // bRequest

            ushort wValue = 0x03; //value 
            ushort wIndex = 0x01; // windex
            // DATA 00 C2 01 00 00 00 08 
            byte[] dataBuff2 = new byte[] { 0x00, 0x01, 0xC2, 0x00, 0x00, 0x00, 0x08 };


            try
            {
                tracer.WriteLine(" SET_LINE_CODING  Req"); // set serial config parameters
                openedDevice.SendSetupTransfer(bmREQ_CDCOUT, SET_LINE_CODING, 0, wIndex, dataBuff2, 0, dataBuff2.Length);

                tracer.WriteLine("Sending SendSetupTransfer Req");
                openedDevice.SendSetupTransfer(bmREQ_CDCOUT, CDC_SET_CONTROL_LINE_STATE, wValue, wIndex);
            }
            catch (Exception ex)
            {
                tracer.WriteLine("Exception in Connect =." + ex.Message + " Inner Exception" + ex.InnerException);
                USBH_ERROR err = USBHostController.GetLastError();
                tracer.WriteLine("USBH_ERROR in Connect =." + err);
            }

            foreach (var endpoint in cdcinterface.endpoints)
            {
                if ((endpoint.bEndpointAddress & 0x80) != 0)
                {
                    tracer.WriteLine("Opening inPipe");
                    inPipe = openedDevice.OpenPipe(endpoint);
                }
                else
                {
                    tracer.WriteLine("Opening outPipe");
                    outPipe = openedDevice.OpenPipe(endpoint);
                }
            }

            tracer.WriteLine("Pipes are opened");

            if (outPipe != null)
            {
                // Command to activate serial communication on Samsung Bada phone
                // http://developer.bada.com/documentation/docView.do?docID=D000001292&&searchCategoryID=C000000006&searchTag=&searchDisplayDate=¤tPage=1&menu=MC01310000&pageCount=10&orderField=DISP_DD_TXT_DESC&searchPubYNFlag=Y
                byte[] command = Encoding.UTF8.GetBytes("AT+OSPSERIALOPEN\r\n");
                tracer.WriteLine("AT+OSPSERIALOPEN\r\n");
                outPipe.TransferData(command, 0, command.Length);
                byte[] command2 = Encoding.UTF8.GetBytes("Osp:Req=\'AccessoryApp\'\r\n");
                tracer.WriteLine("Osp:Req='AccessoryApp'\r\n");
                outPipe.TransferData(command2, 0, command2.Length);
                StartMonitoring(inPipe, outPipe);
            }
        }

        private static void StartMonitoring(USBH_RawDevice.Pipe inPipe, USBH_RawDevice.Pipe outPipe)
        {
            try
            {
                tracer.WriteLine(" InPipe.PipeEndpoint.wMaxPacketSize : " + inPipe.PipeEndpoint.wMaxPacketSize);
                tracer.WriteLine(" OutPipe.PipeEndpoint.wMaxPacketSize : " + outPipe.PipeEndpoint.wMaxPacketSize);
                byte[] inBuffer = new byte[inPipe.PipeEndpoint.wMaxPacketSize];
                int bytesTransferred = 0;
                while (true)
                {
                    tracer.WriteLine(" Waiting for data ");
                    Thread.Sleep(10);
                    try
                    {
                        bytesTransferred = inPipe.TransferData(inBuffer, 0, inPipe.PipeEndpoint.wMaxPacketSize);

                        if (bytesTransferred > 0)
                        {
                            tracer.WriteLine("Byte received : " + bytesTransferred);
                            tracer.WriteLine("Data Recieved : " + new string(Encoding.UTF8.GetChars(inBuffer)));
                        }
                    }
                    catch (Exception)
                    {
                        tracer.WriteLine(" USBH_ERROR while reading =." + USBHostController.GetLastError());
                    }
                }
            }
            catch (Exception)
            {
                tracer.WriteLine("USBH_ERROR in DoProtocol =." + USBHostController.GetLastError());
            }
            tracer.WriteLine(" Out of while loop");
        }
    }

    public class SerialTracer
    {
        SerialPort UART; // = new SerialPort("COM2", 115200);

        public SerialTracer()
        {
            UART = new SerialPort("COM2", 115200);
            UART.DataBits = 8;
            UART.Handshake = Handshake.None;
            UART.Parity = Parity.None;
            UART.StopBits = StopBits.One;
            UART.Open();

        }

        public int WriteLine(string StringToWrite)
        {
            // convert the string to bytes
            byte[] buffer = Encoding.UTF8.GetBytes(StringToWrite + "\r\n");
            // send the bytes on the serial port
            return UART.Write(buffer, 0, buffer.Length);
        }

        public int SerialRead(byte[] buffer, int offset, int count)
        {
            return UART.Read(buffer, offset, count);
        }
    }
}

@ andre.m - Hi Andre thanks for the suggestion. Now I have updated the code section.

@ rathorechandan - Welcome to the forum!

What kind of output do you see?

@ Architect - Hi

Here is the debug trace for your reference. After few seconds I can’t see any trace message and on phone USB status keep changing from connected to disconnected.

345 2013-03-05 16:33:38.482 A to PC: -Started-
346 2013-03-05 16:33:38.487 A to PC: Waiting for events
347 2013-03-05 16:33:53.561 A to PC: Device connected VID = 1256 PID = 26720
349 2013-03-05 16:33:53.582 A to PC: Looking for CDCDataClass interface CDCDataClass found,
bInterfaceNumber =2 Interface

351 2013-03-05 16:33:53.596 A to PC: Protocol =0 InterfaceClass = 10 InterfaceSubclass = 0
bDescriptorType = 4 bNumberEndpoints = 2
Setting configuration bConfigurationValue = 1
SET_LINE_CODING Req
Sending SendSetupTransfer Req

353 2013-03-05 16:33:53.632 A to PC: Opening inPipe
Opening outPipe
Pipes are opened
AT+OSPSERIALOPENOsp:Req='AccessoryApp’
InPipe.PipeEndpoint.wMaxPacketSize : 64
OutPipe.PipeEndpoint.wMaxPacketSize : 64

354 2013-03-05 16:33:53.648 A to PC: Waiting for data
Byte received : 17
Data Recieved : AT+OSPSERIALOPEN

355 2013-03-05 16:33:53.656 A to PC: Waiting for data
Byte received : 2
Data Recieved : OK+OSPSERIALOPEN

355 2013-03-05 16:33:53.656 A to PC: Waiting for data
Byte received : 2
Data Recieved : OK+OSPSERIALOPEN

357 2013-03-05 16:33:54.183 A to PC: Waiting for data
358 2013-03-05 16:33:54.703 A to PC: Waiting for data
359 2013-03-05 16:33:54.710 A to PC: Waiting for data
360 2013-03-05 16:33:55.227 A to PC: Waiting for data
362 2013-03-05 16:33:55.764 A to PC: Waiting for data

I don’t know much about the Accessory protocol for that phone/os, but is it possible that you have to write something back after you have received the data?

@ Architect - please refer following link: it has source code for phone app and Arduino accessory app:

http://developer.bada.com/documentation/docView.do?docID=D000001292&&searchCategoryID=C000000006&searchTag=&searchDisplayDate=&currentPage=1&menu=MC01310000&pageCount=10&orderField=DISP_DD_TXT_DESC&searchPubYNFlag=Y

@ rathorechandan - Check this entry on Codeshare:

http://www.tinyclr.com/codeshare/entry/290

It is a working Android Accessory driver.