Logo Search packages:      
Sourcecode: p2kmoto version File versions  Download package

p2kmoto.c

/***************************************************************************
 *   Copyright (C) 2005 by Dmitry Nezhevenko                               *
 *   dionua@gmail.com                                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "p2kmoto.h"


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <usb.h>

// #define P2K_DEBUG

// Intefaces for Motorola P2k phones
#define INTERFACE_ACCESSORIES 0x05
#define INTERFACE_DATA_LOGGING_MCU 0x06
#define INTERFACE_TEST_COMMAND 0x08

// Default Phone Vendor/Product ID
#define DEF_PHONE_AT_VENDOR 0x22b8
#define DEF_PHONE_AT_PRODUCT 0x4902
#define DEF_PHONE_P2K_VENDOR 0x22b8
#define DEF_PHONE_P2K_PRODUCT 0x4901

// Transfer direction
#define DIR_IN 0
#define DIR_OUT 1



#ifdef P2K_DEBUG
#define FUNC(val)\
      char FUNC_NAME[]=val;\
      printf("=== [P2k API: %s]\n", val);
#define DEBUG( ... )\
      printf(__VA_ARGS__);
#else
#define FUNC(val)\
      char FUNC_NAME[]=val;
#define DEBUG(...) ;
#endif

#define RAISE(a, ...)\
{\
      printf("(E_%s.%d: %s)\n", FUNC_NAME, a, __VA_ARGS__);\
      return(a);\
}


00066 typedef struct myDev
{
      unsigned int vendor;    // Vendor ID
      unsigned int product;   // Product ID
      char name[150];               // Name
}
myDev;

00074 typedef union
{
      unsigned short wordId;
      char id[2];
} mWord;

00080 typedef union
{
      unsigned long longId;
      char id[4];
}
mLong;

myDev devlst[]={
                   {0x0, 0x0, "NONE"},
                   {DEF_PHONE_AT_VENDOR, DEF_PHONE_AT_PRODUCT, "AT"},
                   {DEF_PHONE_P2K_VENDOR, DEF_PHONE_P2K_PRODUCT, "P2K"}
               };

// Phone device/handle
struct usb_device *phone;
usb_dev_handle *phoneHandle;
mWord freeID;
unsigned char packetCount[16*2+2];

// Print array in hex mode
void p2k_showArr(unsigned char *bytes, int size)
{
#ifdef P2K_DEBUG
#define BYTES_IN_LINE 16

      int i;
      if (size==0) return;

      printf("   -------");
      for (i=0; i<16; i++)
      {
            printf("%3X",i);
      }
      printf("\n");

      for (i=0; i<size; i++)
      {
            if (i % 16 ==0)
            {
                  if (i!=0) printf("\n");
                  printf("   %06x: ",i);
            }
            printf("%02x ",bytes[i]);
      }
      printf("\n");
#endif
}

// Init lib
void p2k_init()
{
      usb_init();
      usb_find_busses();
      usb_find_devices();
      freeID.wordId=0;
}

// Set AT config
void p2k_setATconfig (unsigned int vendor, unsigned int product)
{
      devlst[1].vendor=vendor;
      devlst[1].product=product;
}

// Set P2K config
void p2k_setP2kconfig (unsigned int vendor, unsigned int product)
{
      devlst[2].vendor=vendor;
      devlst[2].product=product;
}

// Get device list. Phone must not be opened
p2k_devInfo* p2k_getDevList()
{
      usb_find_busses();
      usb_find_devices();

      struct usb_bus *bus;
      struct usb_device *dev;
      usb_dev_handle *udev;

      int idx=0;
      unsigned int devVendor;
      unsigned int devProduct;
      char devManufacturerStr[200];
      char devProductStr[200];
      int ret;
      p2k_devInfo* lst;

      int cnt=0;

      for (bus = usb_busses; bus; bus = bus->next)
            for (dev = bus->devices; dev; dev = dev->next)
                  cnt++;

      lst=(p2k_devInfo *) malloc (sizeof(p2k_devInfo) * (cnt+1));
      lst[cnt].vendor=-1;
      lst[cnt].product=-1;

      for (bus = usb_busses; bus; bus = bus->next)
      {
            for (dev = bus->devices; dev; dev = dev->next)
            {
                  devVendor=dev->descriptor.idVendor;
                  devProduct=dev->descriptor.idProduct;
                  devManufacturerStr[0]=0;
                  devProductStr[0]=0;

                  udev = usb_open(dev);
                  if (udev)
                  {
                        if (dev->descriptor.iManufacturer)
                              ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer,
                                                          devManufacturerStr, sizeof(devManufacturerStr));

                        if (dev->descriptor.iProduct)
                              ret = usb_get_string_simple(udev, dev->descriptor.iProduct,
                                                          devProductStr, sizeof(devProductStr));
                        usb_close (udev);
                  };

                  lst[idx].vendor=devVendor;
                  lst[idx].product=devProduct;
                  strcpy(lst[idx].manufacturerStr, devManufacturerStr);
                  strcpy(lst[idx].productStr, devProductStr);
                  idx++;
            }
      }

      return lst;
}


// Find device by Vendor ID & Product ID
struct usb_device * p2k_findDevice(int vendor, int product)
{
      struct usb_bus *busses;
      struct usb_bus *bus;

      usb_find_busses();
      usb_find_devices();

      busses = usb_get_busses();

      for (bus = busses; bus; bus = bus->next)
      {
            struct usb_device *dev;

            for (dev = bus->devices; dev; dev = dev->next)
                  if ((dev->descriptor.idVendor==vendor) && (dev->descriptor.idProduct==product))
                        return(dev);

      }
      return(0x00);
}

// Return Current phone state
int p2k_findPhone()
{
      int i;
      for (i=1; i<=2; i++)
      {
            phone=(p2k_findDevice(devlst[i].vendor, devlst[i].product));
            if (phone)  return(i);
      }
      return(P2K_PHONE_NONE);
}

// Connect to Phone. Call after p2k_findPhone
int p2k_connect()
{
      FUNC("p2k_connect");

      phoneHandle=0;
      phoneHandle = usb_open(phone);
      if (phoneHandle==0) RAISE(P2K_E_CANT_OPEN, "Unable to open phone\n");
      if (usb_set_configuration(phoneHandle,1)) RAISE(P2K_E_CANT_SETCONFIG, "Unable to set configuration");
      if (usb_claim_interface(phoneHandle, INTERFACE_TEST_COMMAND)) RAISE(P2K_E_CANT_CLAIMIFACE, "Unable to claim the interface");
      return(1);
}

// Open phone
int p2k_openPhone()
{
      FUNC("p2k_openPhone");
      int ph=p2k_findPhone();
      if (ph!=P2K_PHONE_P2K) RAISE(P2K_E_NOPHONE, "no p2k phone");
      return(p2k_connect());
}

// Close phone
int p2k_closePhone()
{
      FUNC("p2k_closePhone");
      if (phoneHandle<=0) return(1);
      if (usb_close(phoneHandle)) RAISE(P2K_E_CANT_CLOSE, "Unable to close phone");
      return(1);
}

// Decode from Big Endian
void p2k_swapLong(mLong * nm)
{
      mLong t;
      t.longId=nm->longId;
      nm->id[0]=t.id[3];
      nm->id[1]=t.id[2];
      nm->id[2]=t.id[1];
      nm->id[3]=t.id[0];
      //    printf(" -- Swaplong: Was=%08X  Now=%08X -- \n",t.longId, nm->longId);s
}

// Decode from Big Endian
void p2k_swapWord(mWord * nm)
{
      mWord t;
      t.wordId=nm->wordId;
      nm->id[0]=t.id[1];
      nm->id[1]=t.id[2];
}

// Calculate phone answer size
int p2k_get_cmd_size(unsigned char * packetCount)
{
      mWord cnt;
      mWord size;
      int bufsize;
      cnt.id[0]=packetCount[1]; cnt.id[1]=packetCount[0];
      size.id[0]=packetCount[3]; size.id[1]=packetCount[2];
      bufsize=2*cnt.wordId+size.wordId+4;
      return(bufsize);
}

// Send control message to device, but with debug loging and error handling
// Return value is like usb_control_msg() from libusb
int p2k_sendControl(int dir, usb_dev_handle *dev, int requesttype, int request, int value,
                    int index, char *bytes, int size, int timeout)
{
      FUNC("p2k_sendControl");
      if (dev==0) RAISE(P2K_E_NOT_CONNECTED, "no connection");
      int ret;
#ifdef P2K_DEBUG
      if (dir==DIR_IN) printf("<==== "); else printf("====> ");
      printf("Control Message\n");
      printf("   requesttype=0x%02x, request=0x%02x, value=0x%02x, index=0x%02x, size=0x%02x (%04d), timeout=%04d\n",
             requesttype, request, value, index, size, size, timeout);
      if (dir==DIR_OUT) p2k_showArr((unsigned char *)bytes, size);
#endif
      ret=usb_control_msg(dev, requesttype, request, value, index, bytes, size, timeout);
#ifdef P2K_DEBUG
      printf("   result=%04d",ret);
#endif
      if (ret<0) printf(" Error:[%s]\n",usb_strerror());
#ifdef P2K_DEBUG
      else printf("\n");
      if ((dir==DIR_IN) && (ret>0)) p2k_showArr((unsigned char *)bytes,ret);
      printf("\n");
#endif
      return(ret);
}

// Add header and set data to phone via p2k_sendControl
int p2k_outData(unsigned char * data, unsigned int size)
{
      /*
      41 02 00 00 08 00 x1 x1       - Setup packet
      x2 x2 x3 x3 x4 x4 00 00       - data
      x1 - ALl packet size 
      x2 - ID - packet counter
      x3 - command. for reboot = 22
      x4 - command arguments size 
      */

      // Set Packet ID
      freeID.wordId++;
      freeID.wordId&=0xFFF;
      data[0]=freeID.id[1];
      data[1]=freeID.id[0];

      return(p2k_sendControl(DIR_OUT, phoneHandle, 0x41, 0x02, 0x00, 0x08, (char*) data, size,1000));
}

// Request Packet Count
int p2k_inpSize(unsigned char * cmd, int size)
{
      /* Getting info about answer packets
      1 00 00 00 08 00 08 00 */
      int t;
      int ret;

      t=time(NULL);

      // Waiting 5 sec for each answer.
      while (time(NULL)-t<5)
      {
            ret = p2k_sendControl(DIR_IN, phoneHandle, 0xc1, 0x00, 0x00, 0x08, (char *)cmd, size, 1000);
            if ((ret<0) || (ret>2)) break;
#ifdef P2K_DEBUG
            else printf("Error answer. try again\n");
#endif
            usleep(1000);
      }
      return(ret);

}

// Get data from phone and perform error handling
int p2k_inpData(unsigned char * data, unsigned int count, unsigned int size)
{
      FUNC("p2k_inpData");
      /* Getting phone answer:
      1 01 x1 x1 08 00 x2 x2
      x1 - count of packet
      x2 - answer size

      Answer:
      0  1  2  3  4  5   6  7  8  9  0  1  2  3  4  5  6  6  7
      01 00 00 00 00 87  80 03 80 4a 00 7f 00 00 10
      01 00 00 00 00 09 80  04  80  4a 00 01 00 00 08
      x1 ?? ?? ?? x2 x2 [x3 x3 x4 x4 x5 x5 ?? ?? yy yy yy yy yy] ...
      x1 - Count of answers;
      x2 - Total size of answers
      x3 - PacketID or 8000h
      x4 - Only first byte!. 60 - Ok, no data, 80 - Ok, with data, other - errors
      x5 - packet size
      yy - packet data
      [] - Anser for packet
      */

      int ret=p2k_sendControl(DIR_IN , phoneHandle, 0xc1, 0x01, 0x01, 0x08, (char*)data, size, 1000);
      if (ret<0) return (ret);

      int err;
      mWord x2;
      x2.id[1]=data[4]; x2.id[0]=data[5];
      err=0;
      if (err+=(data[0]!=count)) RAISE(P2K_E_ANSWER_E001, "E001");
      if (err+=(x2.wordId!=size-6)) RAISE(P2K_E_ANSWER_E001, "E002");
      return(ret);
}

// Check answer. Some error control
int p2k_check_packet_header(unsigned char * buf, int bufsize, int adr, char needdata, char checky)
{
      FUNC("CPH");

      mWord packId;
      mWord packSize;
      int myid;
      unsigned char packType;
      unsigned char iserr;

      packId.id[0]=buf[adr+1];
      packId.id[1]=buf[adr];
      myid= packId.wordId & 0xFFF;

      packType=buf[adr+2];
      packSize.id[0]=buf[adr+5];
      packSize.id[1]=buf[adr+4];
      iserr=buf[adr+8];

      if (bufsize<0) RAISE(P2K_E_CPH_00, "E00");

      if (myid != freeID.wordId) RAISE(P2K_E_CPH_01, "E01");
      if (needdata)
      {
            if (packType!=0x80) RAISE(P2K_E_CPH_02a, "E02a");
      }
      else
      {
            if (packType!=0x60) RAISE(P2K_E_CPH_02b, "E02b");
      }
      if (checky && iserr) RAISE(P2K_E_CPH_03, "E03");

      /*    if ((myid != freeID.wordId) || (packType!=0x80) || (iserr))
      {
      printf("(E_CPH_01)");
      return(-1);
      }
      */
      return(packSize.wordId);
}

// Reboot phone.
int p2k_reboot()
{
      FUNC("p2k_reboot");
      //This is reboot p2k command
      unsigned char cmd1[]={0xFF, 0xFF, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00};
      unsigned char cmd2[0x0e];
      if (p2k_outData(cmd1, sizeof(cmd1))<0) RAISE(P2K_E_OUTDATA, "E001");
      if (p2k_inpSize(packetCount, sizeof(packetCount))<0) RAISE(P2K_E_INPSIZE, "E002");
      if (p2k_inpData(cmd2, 1, sizeof(cmd2))<0) RAISE(P2K_E_INPDATA, "E003");
      return(1);
}

// Suspend phone
int p2k_suspend()
{
      FUNC("p2k_suspend");
      unsigned char cmd1[]={0xFF, 0xFF, 0x00, 0x36, 0x00, 0x01, 0x00, 0x00,0x00};
      unsigned char * tmp;
      int sz;
      if (p2k_outData(cmd1, sizeof(cmd1))<0) RAISE(P2K_E_OUTDATA, "E01");
      if (p2k_inpSize(packetCount, sizeof(packetCount))<0) RAISE(P2K_E_INPSIZE, "E02");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E03");
      free(tmp);
      return(1);
}

// Get drive information
int p2k_getDriveName(unsigned char * buf)
{
      FUNC("p2k_getDriveName");

      //TODO: Support for E398 and other phones with Memory Flash card.

      unsigned char cmd[]={0xFF, 0xFF, 0x00, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A};
      unsigned char * tmp;
      int sz;
      int buf_ps;
      int ps;
      // 0x00 0x4A - command code

      if (p2k_outData(cmd, sizeof(cmd))<0) RAISE(P2K_E_OUTDATA, "E001")
            //    usleep(100000);
            if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE,"E002");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E003");
      if (p2k_check_packet_header(tmp, sz, 6, 1, 1)<0) RAISE(P2K_E_CPH, "E004");
      buf_ps=0;
      ps=15;
      while (tmp[ps]!=0)
      {
            buf[buf_ps++]=tmp[ps];
            ps+=2;
      }
      buf[buf_ps++]=0;
      free(tmp);
      return(1);
}

// Get phone model.
int p2k_getPhoneModel(unsigned char * buf)
{
      FUNC("p2k_getPhoneName");

      unsigned char cmd[0x10]={0xFF, 0xFF, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x01, 0x17, 0x00, 0x01, 0x00, 0x00, 0x00};
      // 00 02 00 20 00 08 00 00 01 17 00 01 00 00 00 00
      //    unsigned char tmp[1024];
      unsigned char * tmp;
      int sz;
      int buf_ps;
      int ps;
      // 0x00 0x4A - Command code

      if (p2k_outData(cmd, sizeof(cmd))<0) RAISE(P2K_E_OUTDATA, "E001");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E002");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E003");
      if (p2k_check_packet_header(tmp, sz, 6, 1, 1)<0) RAISE(P2K_E_CPH, "E004");
      buf_ps=0;
      ps=0x10;
      while (tmp[ps]!=0)
      {
            buf[buf_ps++]=tmp[ps];
            ps+=2;
      }
      buf[buf_ps++]=0;

      free(tmp);
      return(1);
}

// Return Free space in device
int p2k_freeSpace(unsigned char * dev)
{
      FUNC("p2k_freeSpace");

      //TODO: Check for E398 Support

      unsigned char cmd[0x208] ={0xFF, 0xFF, 0x00, 0x4A, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00};
      unsigned char * tmp;
      int i;
      int ps;
      int sz;
      int size=strlen((char*)dev);

      mLong lng;

      ps=13;
      for (i=0; i< size; i++)
      {
            cmd[ps++]=dev[i];
            cmd[ps++]=0;
      }
      cmd[ps++]=0;
      cmd[ps++]=0;

      if (p2k_outData(cmd, sizeof(cmd))<=0) RAISE(P2K_E_OUTDATA, "E001");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E002");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E003");
      if (p2k_check_packet_header(tmp, sz, 6, 1, 1)<0) RAISE(P2K_E_CPH, "E004");

      lng.id[3]=tmp[14]; lng.id[2]=tmp[15]; lng.id[1]=tmp[16]; lng.id[0]=tmp[17];
      free(tmp);

      return(lng.longId);
}

// Get File Count
int p2k_fileCount()
{
      FUNC("p2k_fileCount");

      unsigned char cmd[]={0xFF, 0xFF, 0x00, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07};
      unsigned char * tmp;
      int sz;
      mWord t;

      if (p2k_outData(cmd, sizeof(cmd))<=0) RAISE(P2K_E_OUTDATA, "E001");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E002");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);

      if (p2k_inpData(tmp, 0x01, sz)<0) RAISE(P2K_E_INPDATA, "E003");

      //    This package has incorrect yy. So we can not check it.
      //    if (check_packet_header(tmp,sz,6)<0) RAISE("E004");
      t.id[1]=tmp[14]; t.id[0]=tmp[15];
      free(tmp);
      return(t.wordId);
}

// Get File List
int p2k_fileList(p2k_onFile onGetFile)
{
      FUNC("p2k_fileList");

      int fCnt;
      unsigned char cmd[] = {0xFF, 0xFF, 0x00, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00,  0x00, 0x00, 0x08};
      unsigned char * tmp;
      unsigned char * recAddr;
      int sz;
      int sz1;
      mWord rCnt;
      int inRec;
      int i;
      int curidx=0;
      int fnameSize;
      int recSize;

      p2k_fileInfo nfo;

      fCnt=p2k_fileCount();
      if (fCnt<0) RAISE(fCnt, "E000");

      sz=-1;

      while (curidx < fCnt)
      {
            if (p2k_outData(cmd, sizeof(cmd))<=0) RAISE (P2K_E_OUTDATA, "E001");
            if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E002");
            sz1=p2k_get_cmd_size(packetCount);
            if (sz1>sz)
            {
                  if (sz!=-1) free(tmp);
                  sz=sz1;
                  tmp=(unsigned char *) malloc (sz);
            }

            if (p2k_inpData(tmp, 0x01, sz1)<0) RAISE (P2K_E_INPDATA, "E003");
            if (p2k_check_packet_header(tmp,sz,6,1,1)<0) RAISE(P2K_E_CPH, "E004");

            rCnt.id[0]=tmp[0x0f]; rCnt.id[1]=tmp[0x10];

            inRec=rCnt.wordId;      //Files in reply. We must calculate rec size - FIX for C350
            if ((sz1-0x12) % inRec)
            {
                  RAISE(P2K_E_BUG,"(BUG) Unsupported filelist answer: sz1=%d, inRec=%d. Please Report!!!", sz1, inRec);
            }
            recSize=(sz1-0x12)/inRec;
            fnameSize=recSize-8;

            recAddr=tmp+0x12;
            for (i=0; i<inRec; i++)
            {
                  p2k_swapLong((mLong *)(recAddr+fnameSize+4));
                  curidx++;

                  nfo.id=curidx;
                  strcpy(nfo.name, (char *) recAddr);
                  nfo.size=((mLong *)(recAddr+fnameSize+4))->longId;
                  nfo.owner=recAddr[fnameSize+3];
                  nfo.attr=recAddr[fnameSize+1];

                  onGetFile(nfo);

                  recAddr+=recSize;
            }
      }
      free(tmp);
      return(1);
}

// Read SEEM record from phone
int p2k_read_seem(int x, int y, unsigned char * seemBuf, int seemBufSize)
{
      unsigned char cmd1[0x10]={0xFF, 0xFF, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0xAA, 0xAA, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00};\
      //    unsigned char * mem;
      mWord xxxx;
      mWord yyyy;
      mWord cnt;
      mWord size;
      mWord packId;
      int bufsize;
      unsigned char * buf;
      int adr;
      //    int dadr;
      unsigned short myid;
      mWord packSize;
      unsigned char packType;
      int seemPos;
      int j;
      unsigned char iserr;

      FUNC("p2k_read_seem");
      
      xxxx.wordId=x;    cmd1[8]=xxxx.id[1]; cmd1[9]=xxxx.id[0];
      yyyy.wordId=y;    cmd1[10]=yyyy.id[1]; cmd1[11]=yyyy.id[0];
      if (p2k_outData(cmd1,sizeof(cmd1))<0) RAISE(P2K_E_OUTDATA, "E001");
      //    usleep(100000);
      //    sleep(1);
      if (p2k_inpSize(packetCount, sizeof(packetCount))<=2) RAISE(P2K_E_INPSIZE,"E002");
      //    sleep(1);
      cnt.id[0]=packetCount[1]; cnt.id[1]=packetCount[0];
      size.id[0]=packetCount[3]; size.id[1]=packetCount[2];
      bufsize=2*cnt.wordId+size.wordId+4;
      buf = (unsigned char *) malloc (bufsize);
      if (p2k_inpData(buf, cnt.wordId, bufsize)!=bufsize) RAISE(P2K_E_INPDATA,"E003");

      adr=6;
      seemPos=0;

      int i;
      for (i=0; i<cnt.wordId; i++)
      {
            packId.id[0]=buf[adr+1];
            packId.id[1]=buf[adr];
            myid= packId.wordId & 0xFFF;
            packType=buf[adr+2];
            packSize.id[0]=buf[adr+5];
            packSize.id[1]=buf[adr+4];
            iserr=buf[adr+8];

            if ((myid != freeID.wordId) || (packType!=0x80) || (iserr))
            {
                  if (packType==0x60) adr+=7;   else adr+=8+packSize.wordId;
                  //                printf("Packet Error. myid=0x%04X, needID=0x%04X, packID=0x%04X packType=0x%02X, yy=0x%02X\n",myid, freeID.wordId, packId, packType, iserr);
                  printf("(E01)");
                  return(P2K_E_OLD);
            }
            for (j=0; j<packSize.wordId-1; j++)
            {
                  if (seemPos>=seemBufSize)
                  {
                        printf("(E_RS_01_%04d_%04d\n",seemBufSize,packSize.wordId-1);
                        return(P2K_E_OLD);
                  }
                  seemBuf[seemPos++]=buf[adr+9+j];
            }
            break;
      }
      return(seemPos);
}

// Write SEEM record to phone
int p2k_write_seem(int x, int y, unsigned char * seemBuf, int seemSize)
{
#define MAX_SEEM_SIZE 102400

      unsigned char * temp_seem;
      unsigned char * temp_packet;

      FUNC("p2k_write_seem");
      
      temp_packet=(unsigned char *) malloc (MAX_SEEM_SIZE);
      temp_seem=temp_packet+16;

      int actualSize;
      int ret;

      // Check seem size by re-reading it from phone

      //    if (!isFirstRead)
      //    {
      actualSize=p2k_read_seem(x,y, temp_seem, MAX_SEEM_SIZE-16);
      actualSize=seemSize;

      if (actualSize != seemSize) RAISE(P2K_E_INCORRECT_SEEMSIZE, "E001");

      mWord wrd;
      memcpy(temp_seem,seemBuf,seemSize);
      wrd.wordId=seemSize+8;

      //     0    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
      //  00 05 00 2F 00 88 00 00 02 06 00 01 00 00 00 80
      //    FF FF 00 2F AA AA 00 00 XX XX YY YY 00 00 ZZ ZZ


      /*    FF FF - ID . AUTO
      00 2F - seem
      AA AA - Size
      XX XX - Seem XXXX
      YY YY - Seem YYYY
      ZZ ZZ - Seem size
      */

      temp_packet[2]=0x00; temp_packet[3]=0x2F;
      wrd.wordId=seemSize+8; temp_packet[4]=wrd.id[1]; temp_packet[5]=wrd.id[0];
      wrd.wordId=x; temp_packet[8]=wrd.id[1]; temp_packet[9]=wrd.id[0];
      wrd.wordId=y; temp_packet[10]=wrd.id[1]; temp_packet[11]=wrd.id[0];
      wrd.wordId=seemSize; temp_packet[14]=wrd.id[1]; temp_packet[15]=wrd.id[0];

      ret=p2k_outData(temp_packet,seemSize+16);
      if (ret!=seemSize+16) RAISE(ret,"E002");
      //    usleep(100000);

      if (p2k_inpSize(packetCount, sizeof(packetCount))<=2) RAISE(P2K_E_INPSIZE, "E003");

      mWord pcnt;
      mWord psize;
      int bufsize;

      pcnt.id[0]=packetCount[1]; pcnt.id[1]=packetCount[0];
      psize.id[0]=packetCount[3]; psize.id[1]=packetCount[2];
      bufsize=2*pcnt.wordId+psize.wordId+4;

      if (p2k_inpData(temp_packet, pcnt.wordId, bufsize)!=bufsize) RAISE(P2K_E_INPDATA, "E004");
      ret=p2k_check_packet_header(temp_packet, pcnt.wordId, 6,1 ,1);
      if (ret<0) RAISE(ret, "E005");

      free(temp_packet);
      return(1);
}

// Delete file from phon.
int p2k_FSAC_Delete(char * fname)
{
      FUNC("FSAC_Delete")
      //                        0     1     2     3     4     5     6     7    8       9     A     B    C     D     E     F
                  unsigned char cmd[]={0xFF, 0xFF, 0x00, 0x4A, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05};
      unsigned char * buf;
      unsigned char * tmp;
      int bufsize;
      int sz;
      mWord t;

      bufsize=sizeof(cmd)+strlen(fname);
      buf=(unsigned char *) malloc (bufsize);
      memcpy(buf,cmd,sizeof(cmd));
      memcpy(buf+sizeof(cmd), fname, strlen(fname));
      t.wordId=bufsize-8;
      buf[0x04]=t.id[1];
      buf[0x05]=t.id[0];

      if (p2k_outData(buf, bufsize)<=0) RAISE (P2K_E_OUTDATA, "E001");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E002");
      sz=p2k_get_cmd_size(packetCount);

      tmp=(unsigned char*) malloc (sz);

      if (p2k_inpData(tmp, 0x01, sz)<0) RAISE (P2K_E_INPDATA, "E003");
      if (p2k_check_packet_header(tmp,sz,6,0,0)<0) RAISE(P2K_E_CPH, "E004");

      free(tmp);
      free(buf);
      return(1);

}

// Open file
int p2k_FSAC_Open(char * fname, unsigned char attr)
{
      FUNC("FSAC_Open");


      //                                   0xFF, 0xFF, 0x00, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
      //                                0    1     2     3     4     5     6     7       8     9     A     B       C     D     E     F
      unsigned char cmd[]={0xFF, 0xFF, 0x00, 0x4A, 0xAA, 0xAA, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0xAA};
      int bufsize;
      unsigned char * buf;
      unsigned char * tmp;
      int sz;
      mWord tWord;

      bufsize=sizeof(cmd)+strlen(fname);
      buf=(unsigned char *)malloc(bufsize);
      memcpy(buf,cmd, sizeof(cmd));
      memcpy(buf+sizeof(cmd),fname,strlen(fname));

      tWord.wordId=bufsize-8;
      buf[0x04]=tWord.id[1];
      buf[0x05]=tWord.id[0];
      buf[0x0F]=attr;

      if (p2k_outData(buf, bufsize)<=0) RAISE (P2K_E_OUTDATA, "E001");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E002");
      sz=p2k_get_cmd_size(packetCount);

      tmp=(unsigned char*) malloc (sz);

      if (p2k_inpData(tmp, 0x01, sz)<0) RAISE (P2K_E_INPDATA, "E003");
      if (p2k_check_packet_header(tmp,sz,6,0,0)<0) RAISE(P2K_E_CPH,"E004");

      free(tmp);
      free(buf);
      return(1);
}

// Close File
int p2k_FSAC_Close()
{
      FUNC("FSAC_Close");

      unsigned char cmd[]={0xFF, 0xFF, 0x00, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
      unsigned char * tmp;
      int sz;

      if (p2k_outData(cmd, sizeof(cmd))<0) RAISE(P2K_E_OUTDATA, "E01");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E02");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E03");
      if (p2k_check_packet_header(tmp,sz,6,0,0)<0) RAISE(P2K_E_CPH, "E04");
      free(tmp);
      return(1);
}

// Seek
int p2k_FSAC_Seek(unsigned long offset, char dir)
{
      FUNC("FSAC_Seek");

      //    4 bytes- offset, 
      //  5 -  0 for begin, 1 for current, 2 - for end.
      
      //                                0    1     2     3     4     5     6     7    8     9     A     B       C     D     E     F
      unsigned char cmd[]={0x00, 0x7C, 0x00, 0x4A, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0x00 };
      unsigned char * tmp;
      int sz;

      mLong t;
      t.longId=offset;
      p2k_swapLong(&t);

      memcpy(cmd+0x0C,&t,4);
      cmd[0x10]=dir;

      if (p2k_outData(cmd, sizeof(cmd))<0) RAISE(P2K_E_OUTDATA, "E01");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E02");
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E03");
      if (p2k_check_packet_header(tmp,sz,6,0,0)<0) RAISE(P2K_E_CPH,"E04");
      free(tmp);
      return(1);
}

// Read from file
int p2k_FSAC_Read(unsigned char * buf, unsigned short size)
{
      FUNC("FSAC_Read");
      //                        0     1     2     3     4     5     6     7    8       9     A     B    C     D     E     F
      unsigned char cmd[]={0xFF, 0xFF, 0x00, 0x4A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xAA, 0xAA};
      //00 7D 00 4A 00 08 00 00 00 00 00 01 00 00 00 0C
      mWord t;
      int sz;
      unsigned char * tmp;
      int ret;

      if (size>0x400) RAISE(P2K_E_BUFFER_TOOLONG, "E00");
      t.wordId=size;

      cmd[0x0e]=t.id[1];
      cmd[0x0f]=t.id[0];
      if (p2k_outData(cmd, sizeof(cmd))<0) RAISE(P2K_E_OUTDATA, "E01");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E02");
      
      sz=p2k_get_cmd_size(packetCount);
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)!=size+0xE) RAISE(P2K_E_INPDATA, "E03");
      if ((ret=p2k_check_packet_header(tmp,sz,6,1,0))!=size) RAISE(P2K_E_CPH,"E04");

      memcpy(buf, tmp+0x0E, size);

      free(tmp);
      return(1);
}

// Write to file
int p2k_FSAC_Write(unsigned char * tbuf, int size)
{
      FUNC("FSAC_Write");
      //                            0     1     2     3     4     5     6     7    8       9     A     B    C     D     E     F
      unsigned char cmd[] ={0xFF, 0xFF, 0x00, 0x4A, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xAA, 0xAA};
      unsigned char * buf;
      unsigned char * tmp;
      int bufsize;
      mWord t;
      int sz;

      if (size>0x400) RAISE(P2K_E_BUFFER_TOOLONG, "E00");

      bufsize=size+sizeof(cmd);
      buf=0;
      buf = (unsigned char *) malloc (bufsize);
      memcpy(buf, cmd, sizeof(cmd));
      memcpy(buf+0x10, tbuf, size);

      t.wordId=size+8;
      buf[0x04]=t.id[1];
      buf[0x05]=t.id[0];

      t.wordId=size;
      buf[0x0E]=t.id[1];
      buf[0x0F]=t.id[0];

      if (p2k_outData(buf, bufsize)<0) RAISE(P2K_E_OUTDATA, "E01");
      //    usleep(100000);
      if (p2k_inpSize(packetCount, sizeof(packetCount))!=4) RAISE(P2K_E_INPSIZE, "E02");
      sz=p2k_get_cmd_size(packetCount);
      tmp=0;
      tmp=(unsigned char *)malloc(sz);
      if (p2k_inpData(tmp , 0x01 , sz)<0) RAISE(P2K_E_INPDATA, "E03");
      if (p2k_check_packet_header(tmp,sz,6,0,0)<0) RAISE(P2K_E_CPH, "E04");

      free(buf);
      free(tmp);

      return(1);
}

Generated by  Doxygen 1.6.0   Back to index