1 /* (c) 2002-2003 by Marcin Wiacek */
2 /* Based on some work from Gnokii (www.gnokii.org)
3  * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot
4  * GNU GPL version 2 or later
5  */
6 /* Due to a problem in the source code management, the names of some of
7  * the authors have unfortunately been lost. We do not mean to belittle
8  * their efforts and hope they will contact us to see their names
9  * properly added to the Copyright notice above.
10  * Having published their contributions under the terms of the GNU
11  * General Public License (GPL) [version 2], the Copyright of these
12  * authors will remain respected by adhering to the license they chose
13  * to publish their code under.
14  */
15 
16 #include "../../gsmstate.h"
17 
18 #if defined(GSM_ENABLE_IRDA) || defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_BLUEPHONET) || defined(GSM_ENABLE_DKU2PHONET)
19 
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 
24 #include "../../gsmcomon.h"
25 #include "phonet.h"
26 
PHONET_WriteMessage(GSM_StateMachine * s,unsigned const char * MsgBuffer,size_t MsgLength,int MsgType)27 static GSM_Error PHONET_WriteMessage (GSM_StateMachine 	*s,
28 				      unsigned const char 	*MsgBuffer,
29 				      size_t 		MsgLength,
30 				      int	MsgType)
31 {
32 	unsigned char		*buffer=NULL;
33 	int			sent=0,length=0;
34 	GSM_Protocol_PHONETData *d = &s->Protocol.Data.PHONET;
35 
36 	GSM_DumpMessageBinary(s, MsgBuffer, MsgLength, MsgType);
37 	length=MsgLength + 6;
38 
39 	buffer = (unsigned char *)malloc(length);
40 
41 	if (buffer == NULL) {
42 		return ERR_MOREMEMORY;
43 	}
44 	buffer[0] = d->frame_id;
45 	buffer[1] = d->device_phone;
46 	buffer[2] = d->device_pc;
47 	buffer[3] = MsgType;
48 	buffer[4] = MsgLength / 256;
49 	buffer[5] = MsgLength % 256;
50 
51 	memcpy(buffer + 6, MsgBuffer, MsgLength);
52 
53 	GSM_DumpMessageText(s, buffer + 6, MsgLength, MsgType);
54 
55 	/* Sending to phone */
56 	sent = s->Device.Functions->WriteDevice(s, buffer, length);
57 	free(buffer);
58 	buffer=NULL;
59 
60 	if (sent != length) {
61 		return ERR_DEVICEWRITEERROR;
62 	}
63 	return ERR_NONE;
64 }
65 
PHONET_StateMachine(GSM_StateMachine * s,unsigned char rx_char)66 static GSM_Error PHONET_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
67 {
68 	GSM_Protocol_PHONETData 	*d = &s->Protocol.Data.PHONET;
69 
70 	if (d->MsgRXState==RX_GetMessage) {
71 		d->Msg.Buffer[d->Msg.Count] = rx_char;
72 		d->Msg.Count++;
73 
74 		/* This is not last byte in frame */
75 		if (d->Msg.Count != d->Msg.Length) return ERR_NONE;
76 
77 		s->Phone.Data.RequestMsg = &d->Msg;
78 		s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
79 		free(d->Msg.Buffer);
80 		d->Msg.Buffer = NULL;
81 		d->Msg.Length = 0;
82 		d->MsgRXState = RX_Sync;
83 		return ERR_NONE;
84 	}
85 	if (d->MsgRXState==RX_GetLength2) {
86 		d->Msg.Length = d->Msg.Length + rx_char;
87 		d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length);
88 		d->MsgRXState = RX_GetMessage;
89 		return ERR_NONE;
90 	}
91 	if (d->MsgRXState==RX_GetLength1) {
92 		d->Msg.Length = rx_char * 256;
93 		d->MsgRXState = RX_GetLength2;
94 		return ERR_NONE;
95 	}
96 	if (d->MsgRXState==RX_GetType) {
97 		d->Msg.Type = rx_char;
98 		d->MsgRXState = RX_GetLength1;
99 		return ERR_NONE;
100 	}
101 	if (d->MsgRXState==RX_GetSource) {
102 		if (rx_char != d->device_phone) {
103 			smprintf_level(s, D_ERROR, "[ERROR: incorrect source ID - 0x%02x, not 0x%02x]\n", rx_char, d->device_phone);
104 			d->MsgRXState = RX_Sync;
105 			return ERR_NONE;
106 		}
107 		d->Msg.Source = rx_char;
108 		d->MsgRXState = RX_GetType;
109 		return ERR_NONE;
110 	}
111 	if (d->MsgRXState==RX_GetDestination) {
112 		if (rx_char != d->device_pc) {
113 			smprintf_level(s, D_ERROR, "[ERROR: incorrect destination ID - 0x%02x, not 0x%02x]\n", rx_char, d->device_pc);
114 			d->MsgRXState = RX_Sync;
115 			return ERR_NONE;
116 		}
117 		d->Msg.Destination = rx_char;
118 		d->MsgRXState = RX_GetSource;
119 		return ERR_NONE;
120 	}
121 	if (d->MsgRXState==RX_Sync) {
122 		if (rx_char != d->frame_id) {
123 			smprintf_level(s, D_ERROR, "[ERROR: incorrect frame ID - 0x%02x, not 0x%02x]\n", rx_char, d->frame_id);
124 			return ERR_NONE;
125 		}
126 		d->Msg.Count = 0;
127 		d->MsgRXState = RX_GetDestination;
128 		return ERR_NONE;
129 	}
130 	return ERR_NONE;
131 }
132 
PHONET_Initialise(GSM_StateMachine * s)133 static GSM_Error PHONET_Initialise(GSM_StateMachine *s)
134 {
135 	int 				total = 0, write_data=0;
136 	GSM_Protocol_PHONETData 	*d = &s->Protocol.Data.PHONET;
137 	unsigned char			req[10]={0};
138 
139 	d->Msg.Length	= 0;
140 	d->Msg.Buffer	= NULL;
141 	d->MsgRXState	= RX_Sync;
142 
143 	/* Connection type specific ids */
144 	switch (s->ConnectionType) {
145 		case GCT_PHONETBLUE:
146 		case GCT_BLUEPHONET:
147 			d->frame_id = PHONET_BLUE_FRAME_ID;
148 			d->device_phone =  PHONET_DEVICE_PHONE;
149 			d->device_pc = PHONET_BLUE_DEVICE_PC;
150 			break;
151 		case GCT_DKU2PHONET:
152 		case GCT_FBUS2USB:
153 			d->frame_id = PHONET_DKU2_FRAME_ID;
154 			d->device_phone =  PHONET_DEVICE_PHONE;
155 			d->device_pc = PHONET_DEVICE_PC;
156 			break;
157 		case GCT_IRDAPHONET:
158 		default:
159 			d->frame_id = PHONET_FRAME_ID;
160 			d->device_phone =  PHONET_DEVICE_PHONE;
161 			d->device_pc = PHONET_DEVICE_PC;
162 			break;
163 	}
164 
165 	if (s->ConnectionType == GCT_PHONETBLUE || s->ConnectionType == GCT_BLUEPHONET) {
166 		/* Send frame in PHONET style */
167 		req[0] = d->frame_id;
168 		req[1] = d->device_phone;
169 		req[2] = d->device_pc;
170 		req[3] = 0xD0;
171 		req[4] = 0x00;
172 		req[5] = 0x01;
173 		req[6] = 0x04;
174 		write_data=s->Device.Functions->WriteDevice(s,req,7);
175 
176 		if (write_data != 7) {
177 			return ERR_DEVICEWRITEERROR;
178 		}
179 
180 		while (total < 7) {
181 			total += s->Device.Functions->ReadDevice(s, req + total, sizeof(req) - total);
182 		}
183 		if (req[0] != d->frame_id) {
184 			smprintf_level(s, D_ERROR, "Phonet_init: invalid frame id 0x%02x!\n", req[0]);
185 			return ERR_UNKNOWN;
186 		}
187 		if (req[1] != d->device_pc) {
188 			smprintf_level(s, D_ERROR, "Phonet_init: invalid destination id 0x%02x!\n", req[1]);
189 			return ERR_UNKNOWN;
190 		}
191 		if (req[2] != d->device_phone) {
192 			smprintf_level(s, D_ERROR, "Phonet_init: invalid source id 0x%02x!\n", req[2]);
193 			return ERR_UNKNOWN;
194 		}
195 		if (req[3] != 0xD0) {
196 			smprintf_level(s, D_ERROR, "Phonet_init: invalid char id 0x%02x!\n", req[3]);
197 			return ERR_UNKNOWN;
198 		}
199 		if (req[4] != 0x00) {
200 			smprintf_level(s, D_ERROR, "Phonet_init: invalid char id 0x%02x!\n", req[4]);
201 			return ERR_UNKNOWN;
202 		}
203 		if (req[5] != 0x01) {
204 			smprintf_level(s, D_ERROR, "Phonet_init: invalid char id 0x%02x!\n", req[5]);
205 			return ERR_UNKNOWN;
206 		}
207 		if (req[6] != 0x05) {
208 			smprintf_level(s, D_ERROR, "Phonet_init: invalid char id 0x%02x!\n", req[6]);
209 			return ERR_UNKNOWN;
210 		}
211 	}
212 
213 	return ERR_NONE;
214 }
215 
PHONET_Terminate(GSM_StateMachine * s)216 static GSM_Error PHONET_Terminate(GSM_StateMachine *s)
217 {
218 	free(s->Protocol.Data.PHONET.Msg.Buffer);
219 	s->Protocol.Data.PHONET.Msg.Buffer=NULL;
220 	return ERR_NONE;
221 }
222 
223 GSM_Protocol_Functions PHONETProtocol = {
224 	PHONET_WriteMessage,
225 	PHONET_StateMachine,
226 	PHONET_Initialise,
227 	PHONET_Terminate
228 };
229 
230 #endif
231 
232 /* How should editor hadle tabs in this file? Add editor commands here.
233  * vim: noexpandtab sw=8 ts=8 sts=8:
234  */
235