source: trunk/Simulator/ModBusKit.mm @ 17

Last change on this file since 17 was 6, checked in by mansoux, 14 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.