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