969091a2fc8b2ce95e6e6bb9a89ba055ecb6a7fd
[gnokii.git] / common / data / datapump.c
1 /*
2
3   $Id$
4
5   G N O K I I
6
7   A Linux/Unix toolset and driver for Nokia mobile phones.
8
9   Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
10
11   Released under the terms of the GNU GPL, see file COPYING for more details.
12
13   This file provides routines to handle processing of data when connected in
14   fax or data mode. Converts data from/to GSM phone to virtual modem
15   interface.
16
17   $Log$
18   Revision 1.1.1.1  2001/11/25 21:59:07  short
19   :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
20
21   Revision 1.4  2001/11/17 16:41:35  pkot
22   Cleanup
23
24   Revision 1.3  2001/02/21 19:57:00  chris
25   More fiddling with the directory layout
26
27   Revision 1.2  2001/02/17 22:40:51  chris
28   ATA support
29
30
31 */
32
33 #define         __data_datapump_c
34
35
36 #include <stdio.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <signal.h>
40 #include <termios.h>
41 #include <grp.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <sys/poll.h>
47 #include <unistd.h>
48
49
50 #include "misc.h"
51 #include "gsm-common.h"
52 #include "gsm-api.h"
53 #include "data/at-emulator.h"
54 #include "data/virtmodem.h"
55 #include "data/datapump.h"
56 #include "data/rlp-common.h"
57
58 /* Global variables */
59 extern bool CommandMode;
60
61 /* Local variables */
62 int             PtyRDFD;        /* File descriptor for reading and writing to/from */
63 int             PtyWRFD;        /* pty interface - only different in debug mode. */ 
64 struct pollfd ufds;
65 u8 pluscount;
66 bool connected;
67
68 bool DP_Initialise(int read_fd, int write_fd)
69 {
70         PtyRDFD = read_fd;
71         PtyWRFD = write_fd;
72         ufds.fd = PtyRDFD;
73         ufds.events = POLLIN;
74         RLP_Initialise(GSM->SendRLPFrame, DP_CallBack);
75         RLP_SetUserRequest(Attach_Req, true);
76         pluscount = 0;
77         connected = false;
78         return true;
79 }
80
81
82 int DP_CallBack(RLP_UserInds ind, u8 *buffer, int length)
83 {
84         int temp;
85
86         switch(ind) {
87         case Data:
88                 if (CommandMode == false) write(PtyWRFD, buffer, length);
89                 break;
90         case Conn_Ind:
91                 if (CommandMode == false) ATEM_ModemResult(MR_CARRIER);
92                 RLP_SetUserRequest(Conn_Req, true);
93                 break;
94         case StatusChange:
95                 if (buffer[0] == 0) {
96                         connected = true;
97                         if (CommandMode == false) ATEM_ModemResult(MR_CONNECT);
98                 }
99                 break;
100         case Disc_Ind:
101                 if (CommandMode == false) ATEM_ModemResult(MR_NOCARRIER);
102                 connected = false;
103                 /* Set the call passup back to the at emulator */
104                 GSM->DialData(NULL, -1, &ATEM_CallPassup);
105                 CommandMode = true;
106                 break;
107         case Reset_Ind:
108                 RLP_SetUserRequest(Reset_Resp, true);
109                 break;
110         case GetData:
111                 if (poll(&ufds, 1, 0)) {
112
113                         /* Check if the program has closed */
114                         /* Return to command mode */
115                         /* Note that the call will still be in progress, */
116                         /* as with a normal modem (I think) */
117
118                         if (ufds.revents != POLLIN) { 
119                                 CommandMode = true;
120                                 /* Set the call passup back to the at emulator */
121                                 GSM->DialData(NULL, -1, &ATEM_CallPassup);
122                                 return 0;
123                         }
124
125                         temp = read(PtyRDFD, buffer, length);
126
127                         if (temp < 0) return 0; /* FIXME - what do we do now? */
128
129                         /* This will only check +++ and the beginning of a read */
130                         /* But there should be a pause before it anyway */
131       
132                         if (buffer[0] == '+') {
133                                 pluscount++;
134                                 if (temp > 1) {
135                                         if (buffer[1] == '+') pluscount++;
136                                         else pluscount = 0;
137                                         if (temp > 2) {
138                                                 if (buffer[2] == '+') pluscount++;
139                                                 else pluscount = 0;
140                                                 if (temp > 3) pluscount = 0;
141                                         }
142                                 }
143                         } else pluscount = 0;
144       
145                         if (pluscount == 3) {
146                                 CommandMode = true;
147                                 /* Set the call passup back to the at emulator */
148                                 GSM->DialData(NULL, -1, &ATEM_CallPassup);
149                                 ATEM_ModemResult(MR_OK);
150                                 break;
151                         }
152       
153                         return temp;
154                 }
155                 break;
156         default:
157                 break;
158         }
159         return 0;
160 }
161
162 void DP_CallPassup(char c)
163 {
164         switch (c) {
165         case 'D':
166                 if (CommandMode == false) ATEM_ModemResult(MR_CARRIER);
167                 RLP_SetUserRequest(Conn_Req, true);
168                 connected = true;
169                 break;
170         case ' ':
171                 CommandMode = true;
172                 /* Set the call passup back to the at emulator */
173                 GSM->DialData(NULL, -1, &ATEM_CallPassup);
174                 ATEM_ModemResult(MR_NOCARRIER);
175                 RLP_SetUserRequest(Disc_Req, true);
176                 connected = false;
177                 break;
178         default:
179                 break;
180         }
181 }