source: trunk/Simulator/ModBusKit.mm@ 10

Last change on this file since 10 was 6, checked in by mansoux, 15 years ago

Ajout client base MacOSX

File size: 11.6 KB
Line 
1//
2// ModBusKit.mm
3// ModBusKit
4//
5// Created by Matthew Butch on 03/02/08.
6// Copyright 2008 Volitans Software and R Engineering, Inc.
7/*
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21
22 These library of functions are designed to enable a program send and
23 receive data from a device that communicates using the Modbus protocol.
24 */
25//
26// This is an Objective-C interface to libmodbus
27
28#import "ModBusKit.h"
29
30
31@implementation ModBusKit
32
33- (void)initialize
34{
35 NSDictionary *infoDict = [[NSBundle bundleForClass: [self class]] infoDictionary];
36 compatibilityVersionNumber=[[infoDict objectForKey: @"VSCompatibilityVersion"] intValue];
37 modbuskitVersionString=[NSString stringWithFormat:@"%@ (%@).",
38 [infoDict objectForKey:@"CFBundleShortVersionString"], [infoDict objectForKey:@"CFBundleVersion"]];
39 //libmodbusVersionString=[[NSBundle mainBundle] objectForInfoDictionaryKey:@"VSlibmodbusVersion"];
40 libmodbusVersionString=[infoDict objectForKey:@"VSlibmodbusVersion"];
41 outputDebugMessages=FALSE;
42}
43
44- (id)init
45{
46 if ((self = [super init]) != nil)
47 {
48 [self initialize];
49 lmbWrap= new libmodbusWrapper();
50 /*if (someError)
51 {
52 [self release];
53 self = nil;
54 }*/
55 }
56 return self;
57}
58
59- (id) initWithSerialPort: (NSString *)serialLocation baudRate: (int) baudRate parity: (int) parity dataBits: (int) dataBits stopBits: (int) stopBits
60{
61 [self init];
62
63 if ([self setupSerialPort:serialLocation baudRate: baudRate parity: parity dataBits: dataBits stopBits: stopBits])
64 return (self);
65
66 return(NULL);
67}
68
69- (id)initWithTCP: (NSString *)ipAddress port :(int)port
70{
71 [self init];
72
73 if ([self setupTCP: ipAddress port: port])
74 return(self);
75
76 return (NULL);
77}
78
79- (int)compatibilityVersion
80{
81 return(compatibilityVersionNumber);
82}
83
84- (NSString *)modbuskitVersion
85{
86 return(modbuskitVersionString);
87}
88
89- (NSString *)libmodbusVersion
90{
91 return(libmodbusVersionString);
92}
93
94- (BOOL) setupSerialPort: (NSString *)serialLocation baudRate: (int) baudRate parity: (int) parity dataBits: (int) dataBits stopBits: (int) stopBits;
95{
96 if (address!=NULL)
97 [address release];
98 address=[[NSString alloc] initWithString: serialLocation];
99 return(lmbWrap->lmbInitSerial([serialLocation cStringUsingEncoding: NSASCIIStringEncoding], baudRate, parity, dataBits, stopBits));
100}
101
102- (BOOL)setupTCP: (NSString *)ipAddress port: (int)port
103{
104 if (address!=NULL)
105 [address release];
106 address=[[NSString alloc] initWithString: ipAddress];
107 return(lmbWrap->lmbInitTCP([ipAddress cStringUsingEncoding: NSASCIIStringEncoding], port));
108}
109
110- (int)openConnection
111{
112 if (outputDebugMessages)
113 NSLog(@"Opening connection...");
114 return(lmbWrap->lmbConnect());
115}
116
117- (void)closeConnection
118{
119 if (outputDebugMessages)
120 NSLog(@"Closing connection...");
121 lmbWrap->lmbDisconnect();
122}
123
124- (NSArray *) readDiscreteInput: (int) slaveID startAddress: (int) startAddress inputCount: (int) inputCount;
125{
126 uint8_t *data;
127 int i;
128 NSMutableArray *dataArray;
129// NSArray *returnArray;
130
131 if (outputDebugMessages)
132 NSLog(@"Reading Discrete Input registers...");
133
134 data=(uint8_t *) malloc(inputCount * sizeof(uint8_t));
135 dataArray=[[NSMutableArray alloc] initWithCapacity: inputCount];
136
137 if (lmbWrap->lmbReadDiscreteInput(slaveID, startAddress, inputCount, data))
138 {
139 for(i=0;i<inputCount;i++)
140 {
141 [dataArray addObject:[NSNumber numberWithBool: data[i]]];
142 }
143// returnArray=[NSArray arrayWithArray:dataArray];
144// [dataArray autorelease];
145 return (dataArray);
146 }
147 return (NULL);
148}
149
150- (NSArray *) readCoil: (int) slaveID startAddress: (int) startAddress coilCount: (int) coilCount;
151{
152 uint8_t *data;
153 int i;
154 NSMutableArray *dataArray;
155// NSArray *returnArray;
156
157 if (outputDebugMessages)
158 NSLog(@"Reading Coil registers...");
159
160 data=(uint8_t *) malloc(coilCount * sizeof(uint8_t));
161 dataArray=[[NSMutableArray alloc] initWithCapacity: coilCount];
162 if (lmbWrap->lmbReadCoil(slaveID, startAddress, coilCount, data))
163 {
164 for(i=0;i<coilCount;i++)
165 {
166 [dataArray addObject:[NSNumber numberWithBool: data[i]]];
167 }
168// returnArray=[NSArray arrayWithArray:dataArray];
169// [dataArray autorelease];
170 return (dataArray);
171 }
172 return(NULL);
173}
174
175- (BOOL) writeSingleCoil: (int) slaveID coilAddress: (int) coilAddress state: (BOOL) state;
176{
177 return(lmbWrap->lmbWriteSingleCoil(slaveID, coilAddress, state));
178}
179
180- (BOOL) writeMultipleCoils: (int) slaveID startAddress: (int) startAddress coilCount: (int) coilCount stateData: (NSArray *) stateData;
181{
182
183 uint8_t *data;
184 int i;
185
186 data=(uint8_t *)malloc(coilCount * sizeof(uint8_t));
187
188 for (i=0;i<[stateData count];i++)
189 {
190 data[i]= [[stateData objectAtIndex:i] intValue];
191 }
192
193 return(lmbWrap->lmbWriteMultipleCoils(slaveID, startAddress, coilCount, data));
194}
195
196- (NSArray *) readInputRegisters: (int) slaveID startAddress: (int) startAddress registerCount: (int) registerCount;
197{
198 uint16_t *data;
199 int i;
200 NSMutableArray *dataArray;
201// NSArray *returnArray;
202
203 if (outputDebugMessages)
204 NSLog(@"Reading Input registers...");
205
206 data=(uint16_t *) malloc(registerCount * sizeof(uint16_t));
207 dataArray=[[NSMutableArray alloc] initWithCapacity: registerCount];
208 if (lmbWrap->lmbReadInputRegisters(slaveID, startAddress, registerCount, data))
209 {
210 for(i=0;i<registerCount;i++)
211 {
212 [dataArray addObject:[NSNumber numberWithInt: data[i]]];
213 }
214// returnArray=[NSArray arrayWithArray:dataArray];
215// [dataArray autorelease];
216 return (dataArray);
217 }
218 return(NULL);
219}
220
221- (NSArray *) readHoldingRegisters: (int) slaveID startAddress: (int) startAddress registerCount: (int) registerCount;
222{
223 uint16_t *data;
224 int i;
225 NSMutableArray *dataArray;
226// NSArray *returnArray;
227
228 if (outputDebugMessages)
229 NSLog(@"Reading Holding registers...");
230
231 data=(uint16_t *) malloc(registerCount * sizeof(uint16_t));
232 dataArray=[[NSMutableArray alloc] initWithCapacity: registerCount];
233 if (lmbWrap->lmbReadHoldingRegisters(slaveID, startAddress, registerCount, data))
234 {
235 for(i=0;i<registerCount;i++)
236 {
237 [dataArray addObject:[NSNumber numberWithInt: data[i]]];
238 }
239// returnArray=[NSArray arrayWithArray:dataArray];
240// [dataArray autorelease];
241 return (dataArray);
242 }
243 return(NULL);
244}
245
246- (BOOL) writeSingleHoldingRegister: (int) slaveID registerAddress: (int) registerAddress value: (uint16_t) value;
247{
248 return(lmbWrap->lmbWriteSingleHoldingRegister(slaveID, registerAddress, value));
249}
250
251- (BOOL) writeMultipleHoldingRegisters: (int) slaveID startAddress: (int) startAddress registerCount: (int) registerCount valueData: (NSArray *) valueData;
252{
253 uint16_t *data;
254 int i;
255
256 data=(uint16_t*)malloc([valueData count] * sizeof(uint16_t));
257
258 for (i=0;i<[valueData count];i++)
259 {
260 data[i]= [[valueData objectAtIndex:i] intValue];
261 }
262
263 return(lmbWrap->lmbWriteMultipleHoldingRegisters(slaveID, startAddress, registerCount, data));
264}
265
266- (int) getLastError
267{
268 return(lmbWrap->lmbErrorCode());
269}
270
271- (NSString *) getLastErrorString
272{
273 switch(lmbWrap->lmbErrorCode())
274 {
275 case ILLEGAL_FUNCTION:
276 return(@"Illegal Function");
277 case ILLEGAL_DATA_ADDRESS:
278 return(@"Illegal Data Address");
279 case ILLEGAL_DATA_VALUE:
280 return(@"Illegal Data Value");
281 case SLAVE_DEVICE_FAILURE:
282 return(@"Slave Device Failure");
283 case ACKNOWLEDGE:
284 return(@"Did not receive Acknowledge");
285 case SLAVE_DEVICE_BUSY:
286 return(@"Slave Device Busy");
287 case NEGATIVE_ACKNOWLEDGE:
288 return(@"Did not receive Acknowledge");
289 case MEMORY_PARITY_ERROR:
290 return(@"Memory Parity Error");
291 case GATEWAY_PROBLEM_PATH:
292 return(@"Problem with Gateway Path");
293 case GATEWAY_PROBLEM_TARGET:
294 return(@"Problem with Gateway Target");
295 case COMM_TIME_OUT:
296 return(@"Communication Time Out");
297 case PORT_SOCKET_FAILURE:
298 return(@"Socket Failure");
299 case SELECT_FAILURE:
300 return(@"Select Failure");
301 case TOO_MANY_DATA:
302 return(@"Too Much Data");
303 case INVALID_CRC:
304 return(@"Invalid CRC");
305 case INVALID_EXCEPTION_CODE:
306 return(@"Unknown Exception");
307 }
308 return(@"Unknown Error");
309}
310
311- (NSString *) getAddress
312{
313 return([NSString stringWithString:address]);
314}
315
316- (void) setDebug: (BOOL)debugToggle
317{
318 lmbWrap->lmbSetDebug(debugToggle);
319 outputDebugMessages=debugToggle;
320}
321
322- (BOOL) getDebug
323{
324 return(outputDebugMessages);
325}
326
327- (void) setSaveRawData: (BOOL)toggle
328{
329 lmbWrap->lmbSetRawDataSave(toggle);
330}
331
332- (NSArray *) getLastRawQuery
333{
334 uint8_t *data;
335 int i;
336 NSMutableArray *dataArray;
337// NSArray *returnArray;
338
339 if (outputDebugMessages)
340 NSLog(@"Getting last raw query...");
341
342 data=(uint8_t *) malloc(MIN_QUERY_LENGTH * sizeof(uint8_t));
343 dataArray=[[NSMutableArray alloc] initWithCapacity: lmbWrap->lmbLastRawQueryLength()];
344 if (lmbWrap->lmbLastRawQuery(data))
345 {
346 for(i=0;i<lmbWrap->lmbLastRawQueryLength();i++)
347 {
348 [dataArray addObject:[NSNumber numberWithInt: data[i]]];
349 }
350 free(data);
351// returnArray=[NSArray arrayWithArray:dataArray];
352// [dataArray autorelease];
353 return (dataArray);
354 }
355 return(NULL);
356
357}
358
359- (NSArray *) getLastRawResponse{
360 uint8_t *data;
361 int i;
362 NSMutableArray *dataArray;
363// NSArray *returnArray;
364
365 if (outputDebugMessages)
366 NSLog(@"Getting last raw response...");
367
368 data=(uint8_t *) malloc(MAX_MESSAGE_LENGTH * sizeof(uint8_t));
369 if (lmbWrap->lmbLastRawResponse(data))
370 {
371 dataArray=[[NSMutableArray alloc] initWithCapacity: lmbWrap->lmbLastRawResponseLength()];
372 for(i=0;i<lmbWrap->lmbLastRawResponseLength();i++)
373 {
374 [dataArray addObject:[NSNumber numberWithInt: data[i]]];
375 }
376 free(data);
377// returnArray=[NSArray arrayWithArray:dataArray];
378// [dataArray autorelease];
379 return (dataArray);
380 }
381 return(NULL);
382
383}
384
385
386+ (NSArray *)scanSerialPorts
387{
388 kern_return_t kernResult;
389 CFMutableDictionaryRef classesToMatch;
390 io_iterator_t serialPortIterator;
391 NSString* serialPort;
392 NSMutableArray *serialPorts;
393
394 serialPorts=[[NSMutableArray alloc] initWithCapacity:5];
395
396 // Serial devices are instances of class IOSerialBSDClient
397 classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
398 if (classesToMatch != NULL)
399 {
400 CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
401
402 // This function decrements the refcount of the dictionary passed it
403 kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, &serialPortIterator);
404 if (kernResult == KERN_SUCCESS) {
405 while ((serialPort = [self getNextSerialPort:serialPortIterator]) != nil)
406 {
407 [serialPorts addObject:serialPort];
408 }
409 (void)IOObjectRelease(serialPortIterator);
410 }
411 }
412
413 [serialPorts autorelease];
414 return(serialPorts);
415}
416
417+ (NSString *)getNextSerialPort:(io_iterator_t)serialPortIterator
418{
419 NSString *serialPort = nil;
420
421 io_object_t serialService = IOIteratorNext(serialPortIterator);
422 if (serialService != 0)
423 {
424 CFStringRef bsdPath = (CFStringRef)IORegistryEntryCreateCFProperty(serialService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
425 if (bsdPath)
426 {
427 // If the port already exists in the list of ports, we want that one. We only create a new one as a last resort.
428 // if ([serialPorts containsObject:(NSString*)bsdPath])
429 serialPort = (NSString *)bsdPath;
430 }
431
432 // We have sucked this service dry of information so release it now.
433 (void)IOObjectRelease(serialService);
434 }
435
436 return serialPort;
437}
438
439@end
Note: See TracBrowser for help on using the repository browser.