Gammu internals  1.38.0
irda.c
Go to the documentation of this file.
1 /* (c) 2001-2004 by Marcin Wiacek */
2 /* based on some work from Ralf Thelen and MyGnokii (www.mwiacek.com) */
3 /* based on some work from MSDN */
4 /* based on some work from Gnokii (www.gnokii.org)
5  * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot
6  * GNU GPL version 2 or later
7  */
8 /* Due to a problem in the source code management, the names of some of
9  * the authors have unfortunately been lost. We do not mean to belittle
10  * their efforts and hope they will contact us to see their names
11  * properly added to the Copyright notice above.
12  * Having published their contributions under the terms of the GNU
13  * General Public License (GPL) [version 2], the Copyright of these
14  * authors will remain respected by adhering to the license they chose
15  * to publish their code under.
16  */
17 
18 /* You have to include wsock32.lib library to MS VC project to compile it */
19 
20 #include "../../gsmstate.h"
21 
22 #ifdef GSM_ENABLE_IRDADEVICE
23 #ifndef DJGPP
24 
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 
29 #ifndef WIN32
30 # include <unistd.h>
31 # include <fcntl.h>
32 # include <errno.h>
33 # include <sys/time.h>
34 # include <sys/poll.h>
35 # include <sys/socket.h>
36 # include <sys/ioctl.h>
37 typedef int SOCKET;
38 #else
39 # define WIN32_LEAN_AND_MEAN
40 # include <windows.h>
41 # include <winsock2.h>
42 # include <io.h>
43 #endif
44 
45 #include "../../gsmcomon.h"
46 #include "../../gsmphones.h"
47 #include "../devfunc.h"
48 #include "irda.h"
49 
50 static gboolean irda_discover_device(GSM_StateMachine *state, SOCKET *fd)
51 {
52  GSM_Device_IrdaData *d = &state->Device.Data.Irda;
53  struct irda_device_list *list;
54  unsigned char *buf=NULL;
55  int sec=0,s=0,z=0,len=0,i=0,deviceid=0;
56  GSM_DateTime Date;
57  gboolean founddevice = FALSE;
58 #ifdef WIN32
59  int index=0;
60 #endif
61 
62  (*fd) = socket(AF_IRDA, SOCK_STREAM, 0);
63 
64 #ifdef WIN32
65  if (*fd == INVALID_SOCKET) {
66  return ERR_DEVICEOPENERROR;
67  }
68 #else
69  if (*fd == -1) {
70  return ERR_DEVICEOPENERROR;
71  }
72 #endif
73 
74  /* can handle maximum 10 devices during discovering */
75  len = sizeof(struct irda_device_list) + sizeof(struct irda_device_info) * 10;
76  buf = (unsigned char *)malloc(len);
77  list = (struct irda_device_list *)buf;
78 
79  /* Trying to find device during 2 seconds */
80  for (z=0;z<2;z++) {
81  GSM_GetCurrentDateTime (&Date);
82  sec = Date.Second;
83  while (sec==Date.Second) {
84  s = len;
85  memset(buf, 0, s);
86 
87  if (getsockopt(*fd, SOL_IRLMP, IRLMP_ENUMDEVICES, buf, &s) == 0) {
88  for (i = 0; i < (int)list->numDevice; i++) {
89 
90 #ifdef WIN32
91  deviceid = (list->Device[i].irdaDeviceID[0] << 24) |
92  (list->Device[i].irdaDeviceID[1] << 16) |
93  (list->Device[i].irdaDeviceID[2] << 8) |
94  (list->Device[i].irdaDeviceID[3]);
95 #else
96  deviceid = list->Device[i].irdaDeviceID;
97 #endif
98  smprintf(state, "IrDA: found device \"%s\" (address %d) - ",
99  list->Device[i].irdaDeviceName,
100  deviceid
101  );
102  if (strcmp(GetModelData(state, NULL,NULL,list->Device[i].irdaDeviceName)->number,"") != 0) {
103  founddevice = TRUE;
104  /* Model AUTO */
105  if (state->CurrentConfig->Model[0]==0)
106  strcpy(state->Phone.Data.Model,GetModelData(state, NULL,NULL,list->Device[i].irdaDeviceName)->number);
107  state->Phone.Data.ModelInfo = GetModelData(state, NULL,state->Phone.Data.Model,NULL);
108  }
109  if (founddevice) {
110  smprintf(state, "correct\n");
111 #ifdef WIN32
112  for(index=0; index <= 3; index++)
113  d->peer.irdaDeviceID[index] = list->Device[i].irdaDeviceID[index];
114 #else
115  d->peer.irdaDeviceID = list->Device[i].irdaDeviceID;
116 #endif
117  break;
118  }
119  smprintf(state, "\n");
120  }
121  }
122  if (founddevice) break;
123  usleep(10000);
124  GSM_GetCurrentDateTime(&Date);
125  }
126  if (founddevice) break;
127  }
128  free(buf);
129  buf=NULL;
130 
131  if (!founddevice) {
132  socket_close(state, *fd);
133  }
134  return founddevice;
135 }
136 
137 static GSM_Error irda_open (GSM_StateMachine *s)
138 {
139  GSM_Device_IrdaData *d = &s->Device.Data.Irda;
140  SOCKET fd = -1;
141  gboolean failed;
142 #ifdef WIN32
143  int Enable9WireMode = 1;
144  WSADATA wsaData;
145  /* BCC comes with broken MAKEWORD, which emmits warnings */
146 #ifdef __BORLANDC__
147 # pragma warn -8084
148 #endif
149  WSAStartup(MAKEWORD(1,1), &wsaData);
150 #ifdef __BORLANDC__
151 # pragma warn +8084
152 #endif
153 #else
154  if (s->ConnectionType == GCT_IRDAAT)
155  return ERR_SOURCENOTAVAILABLE;
156 #endif
157 
158  /* discovering devices */
159  if (irda_discover_device(s,&fd) == FALSE) {
160  smprintf(s, "Can not find any IrDA device!\n");
161  return ERR_TIMEOUT;
162  }
163 
165 #ifndef WIN32
167 #endif
168  switch (s->ConnectionType) {
169  case GCT_IRDAGNAPBUS:
170  case GCT_IRDAAT:
171  strcpy(d->peer.irdaServiceName, "IrDA:IrCOMM");
172 #ifdef WIN32
173  if (setsockopt(fd, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode,
174  sizeof(int))==SOCKET_ERROR) return ERR_UNKNOWN;
175 #endif
176  break;
177  case GCT_IRDAPHONET:
178  strcpy(d->peer.irdaServiceName, "Nokia:PhoNet");
179  break;
180  case GCT_IRDAOBEX:
181  strcpy(d->peer.irdaServiceName, "OBEX");
182  break;
183  default:
184  close(fd);
185  return ERR_UNKNOWN;
186  }
187 
188  /* Connecting to service */
189  if (connect(fd, (struct sockaddr *)&d->peer, sizeof(d->peer))) {
190  smprintf(s, "Can't connect to service %s\n",d->peer.irdaServiceName);
191  failed = TRUE;
192  /* Try alternatives if we failed */
193  if (s->ConnectionType == GCT_IRDAOBEX) {
194  smprintf(s, "Trying alternate config: IrDA:OBEX\n");
195  strcpy(d->peer.irdaServiceName, "IrDA:OBEX");
196  if (connect(fd, (struct sockaddr *)&d->peer, sizeof(d->peer))) {
197  smprintf(s, "Can't connect to service %s\n",d->peer.irdaServiceName);
198  smprintf(s, "Trying alternate config: OBEX:IrXfer\n");
199  strcpy(d->peer.irdaServiceName, "OBEX:IrXfer");
200  if (!connect(fd, (struct sockaddr *)&d->peer, sizeof(d->peer))) {
201  failed = FALSE;
202  }
203  } else {
204  failed = FALSE;
205  }
206  }
207  if (failed) {
208  socket_close(s, fd);
209  return ERR_NOTSUPPORTED;
210  }
211  }
212 
213  d->hPhone=fd;
214 
215  return ERR_NONE;
216 }
217 
218 static int irda_read(GSM_StateMachine *s, void *buf, size_t nbytes)
219 {
220  return socket_read(s, buf, nbytes, s->Device.Data.Irda.hPhone);
221 }
222 
223 static int irda_write(GSM_StateMachine *s, const void *buf, size_t nbytes)
224 {
225  return socket_write(s, buf, nbytes, s->Device.Data.Irda.hPhone);
226 }
227 
228 static GSM_Error irda_close(GSM_StateMachine *s)
229 {
230  return socket_close(s, s->Device.Data.Irda.hPhone);
231 }
232 
233 GSM_Device_Functions IrdaDevice = {
234  irda_open,
235  irda_close,
236  NONEFUNCTION,
237  NONEFUNCTION,
238  NONEFUNCTION,
239  irda_read,
240  irda_write
241 };
242 
243 #endif
244 #endif
245 
246 /* How should editor hadle tabs in this file? Add editor commands here.
247  * vim: noexpandtab sw=8 ts=8 sts=8:
248  */
GSM_Config * CurrentConfig
Definition: gsmstate.h:1415
u_int8_t sir_lsap_sel
Definition: irda_unx.h:39
union GSM_Device::@0 Data
GSM_ConnectionType ConnectionType
Definition: gsmstate.h:1402
sa_family_t irdaAddressFamily
Definition: irda_unx.h:38
u_int32_t irdaDeviceID
Definition: irda_unx.h:46
#define LSAP_ANY
Definition: irda_unx.h:35
#define AF_IRDA
Definition: irda_w32.h:7
#define NONEFUNCTION
Definition: gsmcomon.h:12
GSM_Error
Definition: gammu-error.h:23
struct sockaddr_irda peer
Definition: irda.h:18
GSM_PhoneModel * ModelInfo
Definition: gsmstate.h:449
int gboolean
Definition: gammu-types.h:23
#define IRLMP_ENUMDEVICES
Definition: irda_unx.h:34
GSM_PhoneModel * GetModelData(GSM_StateMachine *s, const char *model, const char *number, const char *irdamodel)
Definition: gsmphones.c:1002
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
u_int32_t numDevice
Definition: irda_unx.h:53
char irdaServiceName[25]
Definition: irda_unx.h:41
u_int32_t irdaDeviceID
Definition: irda_unx.h:40
#define IRLMP_9WIRE_MODE
Definition: irda_w32.h:10
GSM_Phone_Data Data
Definition: gsmstate.h:1369
void GSM_GetCurrentDateTime(GSM_DateTime *Date)
Definition: misc.c:184
char irdaDeviceName[22]
Definition: irda_unx.h:47
const char * number
Definition: gammu-info.h:768
struct irda_device_info Device[1]
Definition: irda_unx.h:54
#define TRUE
Definition: gammu-types.h:28
#define SOL_IRLMP
Definition: irda_unx.h:33
char Model[GSM_MAX_MODEL_LENGTH+1]
Definition: gsmstate.h:445
GSM_Device Device
Definition: gsmstate.h:1429
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261