http://marcin-wiacek.fkn.pl/english/zips/mygnokii.tar.gz
[gnokii.git] / common / devices / unixirda.c
index 2931d11..cfbf39a 100644 (file)
@@ -1,14 +1,10 @@
 /*
  * $Id$
  *
- *
  * G N O K I I
  *
  * A Linux/Unix toolset and driver for Nokia mobile phones.
  *
- * Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
- * Copyright (C) 2000-2001  Marcel Holtmann <marcel@holtmann.org>
- *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License as published by the Free Software Foundation; either
  * License along with this library; if not, write to the Free
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Log$
- * Revision 1.1.1.1  2001/11/25 21:59:09  short
- * :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
- *
- * Revision 1.7  2001/11/08 16:49:19  pkot
- * Cleanups
- *
- * Revision 1.6  2001/08/17 00:18:12  pkot
- * Removed recv() from IrDA initializing procedure (many people)
- *
- * Revision 1.5  2001/06/27 23:52:48  pkot
- * 7110/6210 updates (Marian Jancar)
- *
- * Revision 1.4  2001/06/20 21:27:34  pkot
- * IrDA patch (Marian Jancar)
- *
- * Revision 1.3  2001/02/21 19:57:04  chris
- * More fiddling with the directory layout
- *
- * Revision 1.2  2001/02/20 21:55:10  pkot
- * Small #include updates
- *
- * Revision 1.1  2001/02/16 14:29:52  chris
- * Restructure of common/.  Fixed a problem in fbus-phonet.c
- * Lots of dprintfs for Marcin
- * Any size xpm can now be loaded (eg for 7110 startup logos)
- * nk7110 code detects 7110/6210 and alters startup logo size to suit
- * Moved Marcin's extended phonebook code into gnokii.c
- *
- * Revision 1.2  2001/02/06 21:15:35  chris
- * Preliminary irda support for 7110 etc.  Not well tested!
- *
- * Revision 1.1  2001/02/03 23:56:17  chris
- * Start of work on irda support (now we just need fbus-irda.c!)
- * Proper unicode support in 7110 code (from pkot)
- *
  */
 
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
 #include "devices/unixirda.h"
+#include "devices/linuxirda.h"
+
 
 #ifndef AF_IRDA
 #define AF_IRDA 23
 #define DISCOVERY_SLEEP                0.4
 
 static char *phone[] = {
-       "Nokia 7110", "Nokia 6210"
+        "Nokia 5210",
+       "Nokia 6210", "Nokia 6250", "Nokia 6310",
+       "Nokia 7110",
+       "Nokia 8210", "Nokia 8310", "Nokia 8850"
 };
 
 double d_time(void)
@@ -101,18 +77,17 @@ double d_sleep(double s)
        return time;
 }
 
-static int irda_discover_device(void)
+static int irda_discover_device(int fd)
 {
 
        struct irda_device_list *list;
        struct irda_device_info *dev;
        unsigned char           *buf;
-       int                     s, len, i, j, daddr = -1, fd;
+       int                     s, len, i, j;
+       int                     daddr = -1;
        double                  t1, t2;
        int phones = sizeof(phone) / sizeof(*phone);
        
-       fd = socket(AF_IRDA, SOCK_STREAM, 0);
-       
        len = sizeof(*list) + sizeof(*dev) * 10;        // 10 = max devices in discover
        buf = malloc(len);
        list = (struct irda_device_list *)buf;
@@ -129,11 +104,15 @@ static int irda_discover_device(void)
                                for (j = 0; (j < phones) && (daddr == -1); j++) {
                                        if (strncmp(dev[i].info, phone[j], INFO_LEN) == 0) {
                                                daddr = dev[i].daddr;
-                                               dprintf("%s\t%x\n", dev[i].info, dev[i].daddr);
+#ifdef DEBUG
+                                               fprintf(stdout,_("%s\t%x\n"), dev[i].info, dev[i].daddr);
+#endif
                                        }
                                }
                                if (daddr == -1) {
-                                       dprintf("unknown: %s\t%x\n", dev[i].info, dev[i].daddr);
+#ifdef DEBUG
+                                       fprintf(stdout,_("unknown: %s\t%x\n"), dev[i].info, dev[i].daddr);
+#endif
                                }
                        }
                }
@@ -147,7 +126,6 @@ static int irda_discover_device(void)
        } while ((t2 - t1 < DISCOVERY_TIMEOUT) && (daddr == -1));
        
        free(buf);
-       close(fd);
        
        return daddr;
 }
@@ -156,24 +134,44 @@ int irda_open(void)
 {
        struct sockaddr_irda    peer;
        int                     fd = -1, daddr;
+       int                     pgrp;         
        
-       daddr = irda_discover_device();                 /* discover the devices */
        
-       if (daddr != -1)  {
-               fd = socket(AF_IRDA, SOCK_STREAM, 0);   /* Create socket */
-               peer.sir_family = AF_IRDA;
-               peer.sir_lsap_sel = LSAP_ANY;
-               peer.sir_addr = daddr;
-               strcpy(peer.sir_name, "Nokia:PhoNet");
+       fd = socket(AF_IRDA, SOCK_STREAM, 0);   /* Create socket */
+       if (fd == -1) {
+               perror("socket");
+                       exit(1);
+                    }
+
+       /* discover the devices */ 
+       daddr = irda_discover_device(fd);
+       if (daddr == -1)  {
+                       printf("irda_discover: no nokia devices found");
+                       exit(1);
+                    }
+
+       /* Arrange for the current process to receive
+           SIGIO when the state of the socket changes. */
+       pgrp = getpid();
+       if (fcntl (fd, F_SETOWN, pgrp) < 0)
+       perror("F_SETOWN");
+
+       /*  Set the socket state for Asynchronous  */
+       if (fcntl (fd, F_SETFL, FASYNC) < 0) {
+               perror("fcntl");
+                       exit(1);
+                    }
+
+       peer.sir_family = AF_IRDA;
+       peer.sir_lsap_sel = LSAP_ANY;
+       peer.sir_addr = daddr;
+       strcpy(peer.sir_name, "Nokia:PhoNet");
                
-               if (connect(fd, (struct sockaddr *)&peer, sizeof(peer))) {      /* Connect to service "Nokia:PhoNet" */
-                       perror("connect");
-                       close(fd);
-                       fd = -1;
-/*             } else { FIXME: It does not work in most cases. Why? Or why it should work?
-                       recv(fd, NULL, 0, 0);            call recv first to make select work correctly */
+       if (connect(fd, (struct sockaddr *)&peer, sizeof(peer))) {      /* Connect to service "Nokia:PhoNet" */
+               perror("connect");
+               close(fd);
+               fd = -1;
                }
-       }
        
        return fd;
 }
@@ -186,7 +184,20 @@ int irda_close(int fd)
 
 int irda_write(int __fd, __const __ptr_t __bytes, int __size)
 {
-       return (send(__fd, __bytes, __size, 0));
+  int actual,ret;
+
+   actual = 0;
+   
+   do {
+    if ((ret = send(__fd, __bytes, __size - actual, 0)) < 0)
+       return(actual);
+
+       actual += ret;
+       __bytes += ret;
+
+    } while (actual < __size);
+
+    return (actual);
 }
 
 int irda_read(int __fd, __ptr_t __bytes, int __size)